// // 地名検索サーバ // #include #include #include main() { readdata(); server(); } // // 曖昧検索ルーチン (1998年2月号「asearch」と同じもの) // makepat(パタン,曖昧度); // match(テキスト); // int mismatch; unsigned int epsilon, acceptpat; unsigned int shiftpat[0x100]; void makepat(unsigned char *pat, int m) { int i; unsigned int mask = 0x4000; mismatch = (m <= 0 ? 0 : m <= 3 ? m : 3); epsilon = 0; for(i=0;i<0x100;i++) shiftpat[i] = 0; for(;*pat;pat++){ if(*pat == ' '){ // ワイルドカード文字 epsilon |= mask; } else { shiftpat[*pat] |= mask; mask >>= 1; } } acceptpat = mask; } int match(register unsigned char *text) { unsigned int i0 = 0x4000, i1=0, i2=0, i3=0; unsigned int mask; unsigned int e = epsilon; for(;*text;text++){ mask = shiftpat[*text]; i3 = (i3 & e) | ((i3 & mask) >> 1) | (i2 >> 1) | i2; i2 = (i2 & e) | ((i2 & mask) >> 1) | (i1 >> 1) | i1; i1 = (i1 & e) | ((i1 & mask) >> 1) | (i0 >> 1) | i0; i0 = (i0 & e) | ((i0 & mask) >> 1); i1 |= (i0 >> 1); i2 |= (i1 >> 1); i3 |= (i2 >> 1); } switch(mismatch){ case 0: return (i0 & acceptpat); case 1: return (i1 & acceptpat); case 2: return (i2 & acceptpat); case 3: return (i3 & acceptpat); default: return 0; } } // // 郵便番号辞書読み込み // #define ZIPFILE "./loclist" #define MAXWORDS 120000 unsigned char *address[MAXWORDS]; unsigned char *addressyomi[MAXWORDS]; unsigned char *zip[MAXWORDS]; int nlines = 0; #define MAXLEN 1000 readdata() { unsigned char buf[MAXLEN]; unsigned char s1[MAXLEN],s2[MAXLEN],s3[8]; FILE *f; if((f = fopen(ZIPFILE,"r")) == NULL){ fprintf(stderr,"Can't open ZIP file %s\n",ZIPFILE); exit(0); } while(fgets(buf,1000,f)){ int len = strlen(buf); if(buf[len-1] == '\n') buf[len-1] = '\0'; sscanf(buf,"%s %s %s",s1,s2,s3); address[nlines] = (unsigned char*)strdup(s1); addressyomi[nlines] = (unsigned char*)strdup(s2); zip[nlines] = (unsigned char*)strdup(s3); nlines++; } } // // 検索サーバメインルーチン // #include #include #include #include #include #include #define MAXDTAB 20 #define MAXCLIENT 32 // 最大接続数 #define BUFSIZE 512 // リクエストの最大サイズ #define MAXQUE 5 #define ZIPSERVERPORT 5560 int initsock; // 要求待ちsocket int clientfd[MAXCLIENT]; // 各クライアント用socket int nclients = 0; server() { int i; int len; struct sockaddr_in sin; struct sockaddr_in from; struct servent *sp; fd_set readfds, writefds, exceptfds; fd_set getrfds(); bzero((char*)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(ZIPSERVERPORT); if((initsock = socket(PF_INET,SOCK_STREAM,0))<0){ fprintf(stderr,"socket: can't create a socket"); exit(0); } if(bind(initsock, struct sockaddr*)&sin,sizeof(sin))<0){ fprintf(stderr,"bind: socket already used"); exit(0); } if(listen(initsock,MAXQUE)<0){ fprintf(stderr,"listen:"); exit(0); } FD_ZERO(&writefds); FD_ZERO(&exceptfds); for(;;){ FD_ZERO(&readfds); FD_SET(initsock,&readfds); for (i = 0; i < nclients; i ++) FD_SET(clientfd[i], &readfds); if (select(MAXDTAB,&readfds,&writefds,&exceptfds,NULL)<0){ fprintf(stderr,"select:"); } if (FD_ISSET(initsock, &readfds)) { len = sizeof(from); if((clientfd[nclients++] = accept(initsock,&from,&len)) < 0){ fprintf(stderr,"accept:"); } if(nclients >= MAXDTAB-3) { write(clientfd[--nclients],"F",1); close(clientfd[nclients]); } } for(i=0;i0 && (buf[n-1]=='\n' || buf[n-1]=='\r');n--); buf[n] = '\0'; if(buf[0]=='S'){ // 検索要求 "S1 emerald ", etc. makepat(&buf[2],buf[1]-'0'); for(i=n=0;i