/* ckskkserv.c: check skkserv */ #include #include #include #include #include #include #include #include #include #include /*#define DEBUG*/ #ifdef DEBUG # define Debug(a) a #else # define Debug(a) #endif #define SKK_PORT_NUMBER 1178 #define SKK_SERVICENAME "skkserv" #define SKK_SERVER_HOST "localhost" #define bincopy(a,b,n) memcpy(b,a,n) #define fillzero(a,n) memset(a,0,n) #define timediff(tvfrom, tvto) ((((tvto).tv_sec - (tvfrom).tv_sec)) * 1000000 \ + ((tvto).tv_usec - (tvfrom).tv_usec)) typedef struct entry_t { struct entry_t *next; long time; /* elapsed time to search */ char result; /* result code of skkserv '1': found, '4': not found */ char word[1]; /* word to search */ } Entry; /* prototypes */ Entry *read_words(FILE *fp); void search(char *server, char *port, Entry *first_entry); int openSKKserv(char *server, char *port); void getCandFromServer(Entry *p); void closeSKKserv(void); int skkservsock = -1; int main(int argc, char *argv[]) { Entry *first_entry = NULL; int i; char *server = SKK_SERVER_HOST, *port = NULL; /* check arguments */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-p") == 0) { /* port || service name */ port = argv[++i]; } else { server = argv[i]; } } /* first, read all words to search */ if ((first_entry = read_words(stdin)) == NULL) { fprintf(stderr, "Failed to read words.\n"); exit(1); } /* do search and print result */ search(server, port, first_entry); return 0; } Entry * read_words(FILE *fp) { Entry *p, *first_entry = NULL; char buf[BUFSIZ]; while (fgets(buf, sizeof(buf), fp) != NULL) { int i = strlen(buf) - 1; if (buf[i] == '\n') buf[i] = '\0'; if ((p = (Entry *)malloc(sizeof(Entry) + strlen(buf))) == NULL) { fprintf(stderr, "malloc failed\n"); exit(1); } strcpy(p->word, buf); p->time = 0; p->next = first_entry; first_entry = p; } if (first_entry == NULL) { fprintf(stderr, "No word to search\n"); exit(1); } return first_entry; } void search(char *server, char *port, Entry *first_entry) { Entry *p; struct timeval start, connected, end; int num = 0; long total = 0; gettimeofday(&start, NULL); Debug(printf("start: %ld, %ld\n", start.tv_sec, start.tv_usec)); if (openSKKserv(server, port) < 0) { fprintf(stderr, "Failed to openSKKserv()\n"); exit(1); } gettimeofday(&connected, NULL); Debug(printf("connected: %ld, %ld\n", connected.tv_sec, connected.tv_usec)); for (p = first_entry; p != NULL; p = p->next) { if (*(p->word) != '\0') { getCandFromServer(p); Debug(printf("word %s: %ld\n", p->word, p->time)); } #ifdef MEMORY_USAGE else { /* empty line */ char buf[BUFSIZ]; if (port == NULL) port = SKK_SERVICENAME; sprintf(buf, "ps -auxwww > '%s.mem'", port); system(buf); } #endif } closeSKKserv(); gettimeofday(&end, NULL); Debug(printf("end: %ld, %ld\n", end.tv_sec, end.tv_usec)); /* print result */ for (p = first_entry; p != NULL; p = p->next) { printf("%ld %s %c\n", p->time, p->word, p->result); total += p->time; num++; } printf("\n%ld [To connect]\n", timediff(start, connected)); printf("%ld (%ld) [from open to close (sum)]\n", timediff(start, end), total); if (num == 0) { fprintf(stderr, "No words\n"); exit(1); } printf("%.6f [average]\n", (double)total / (double)num); } int openSKKserv(char *server, char *port) { int sock; struct sockaddr_in hostaddr; struct hostent *entry; struct servent *serv; struct protoent *proto; int a1,a2,a3,a4; unsigned long adr; char *hostname; int portnum = -1; if (port == NULL) { /* use default */ port = SKK_SERVICENAME; portnum = SKK_PORT_NUMBER; } else if (isdigit(port[0])) { portnum = atoi(port); } if (portnum >= 0 || (serv = getservbyname(port,"tcp")) == NULL) { serv = (struct servent*)malloc(sizeof(struct servent)); if (serv == NULL) { fprintf(stderr, "failed malloc()\n"); return -1; } if (portnum < 0) { fprintf(stderr, "Illegal service name: %s\n", port); return -1; } serv->s_port = htons(portnum); } fillzero((char*)&hostaddr,sizeof(struct sockaddr_in)); if ((proto = getprotobyname("tcp")) == NULL) { fprintf(stderr, "failed getprotobyname(\"tcp\")\n"); return -1; } if ((sock = socket(AF_INET,SOCK_STREAM,proto->p_proto)) < 0) { fprintf(stderr, "failed socket(AF_INET,SOCK_STREAM,)\n"); return -1; } if (server != NULL) { hostname = server; } else if ((hostname = getenv("SKKSERVER")) == NULL) { fprintf(stderr, "failed to get hostname\n"); return -1; } if ('0' <= *hostname && *hostname <= '9') { if (sscanf(hostname,"%d.%d.%d.%d",&a1,&a2,&a3,&a4) != 4) { fprintf(stderr, "failed to get hostname from IP address: %s\n", hostname); return -1; } adr = htonl((a1<<12)|(a2<<8)|(a3<<4)|a4); bincopy(&adr, &hostaddr.sin_addr, 4); } else { if ((entry = gethostbyname(hostname)) == NULL) { fprintf(stderr, "failed gethostbyname(%s)\n", hostname); return -1; } bincopy(entry->h_addr, &hostaddr.sin_addr, entry->h_length); } hostaddr.sin_family = AF_INET; hostaddr.sin_port = serv->s_port; if (connect(sock,(struct sockaddr *)&hostaddr,sizeof(struct sockaddr_in)) < 0) { fprintf(stderr, "failed connect(%d,..)\n", sock); return -1; } /* printf("SKKSERVER=%s\n\r",hostname); */ skkservsock = sock; return 0; } void getCandFromServer(Entry *p) { char r; int n; char buf[BUFSIZ]; struct timeval start, end; sprintf(buf, "1%s \n", p->word); gettimeofday(&start, NULL); write(skkservsock,buf,strlen(buf)); read(skkservsock, &r, 1); gettimeofday(&end, NULL); /* search done */ p->time = timediff(start, end); p->result = r; #ifdef PRINT_SEARCH_RESULT printf("%s %c", p->word, r); #endif while ((n = read(skkservsock,buf,sizeof(buf))) > 0) { int i; buf[n] = '\0'; Debug(printf("read[%c]: %s", r, buf)); #ifdef PRINT_SEARCH_RESULT printf("%s", buf); #endif for (i = 0; i < n; i++) { if (buf[i] == '\n') /* cannot use strchr() */ break; /* because buf may have '\0' */ } if (i < n) break; } } void closeSKKserv(void) { if (skkservsock >= 0) { write(skkservsock, "0\n", 2); close(skkservsock); skkservsock = -1; } }