/* imaptest - To programatically test responses from bincimap on WEST02 and in particular how to get the unseen message count. */ #include #include #include #include #include #include #include #include #include #define HOST "WEST02" // the host we will connect to #define PORT 143 // the port we will be connecting to (imap) #define MAXDATASIZE 1024 // max number of bytes we can get at once int main(void) { int sockfd, numbytes, unseen_cnt, j; char msg[80]; char *ptr1, *ptr2; char buf[MAXDATASIZE]; char unseen_buf[MAXDATASIZE]; struct hostent *he; struct sockaddr_in their_addr; // connector's address information if ((he=gethostbyname(HOST)) == NULL) { // get the host info perror("gethostbyname"); exit(1); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(PORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct // connect printf("Connecting...\n"); if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; printf("Received:\n%s",buf); // login strcpy(msg, "01 LOGIN \"xxxxxxxx\" \"yyyyyy\"\r\n"); if ((numbytes=sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } printf("\n--->Sent: %s", msg); if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; printf("Received:\n%s",buf); // examine inbox strcpy(msg, "02 EXAMINE INBOX\r\n"); if ((numbytes=sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } printf("\n--->Sent: %s", msg); if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; printf("Received:\n%s",buf); // search unseen strcpy(msg, "03 SEARCH UNSEEN\r\n"); if ((numbytes=sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } printf("\n--->Sent: %s", msg); //************************************************************************************** // bincimap does not always send the reply to SEARCH UNSEEN all in one go, // so loop until we get it all, limit to 50 tries to avoid infinite loop unseen_cnt = 0; unseen_buf[0] = 0; j = 0; do { if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; strcat(unseen_buf, buf); j++; if (j > 50) { perror("loop > 50"); exit(1); } } while(!strstr(buf, "OK SEARCH completed")); //************************************************************************************** printf("Received:\n%s", unseen_buf); // find end of line ptr1 = strstr(unseen_buf, "* SEARCH") + 8; ptr2 = strstr(ptr1, "\r"); if(!ptr2) ptr2 = strstr(ptr1, "\n"); if(!ptr2) { perror("unseen_buf"); exit(1); } *ptr2 = 0; // count spaces to get unseen message count while((ptr1 = strstr(ptr1, " "))) { unseen_cnt++; ptr1++; } printf("Unseen = %d\n", unseen_cnt); // logout strcpy(msg, "04 LOGOUT\r\n"); if ((numbytes=sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } printf("\n--->Sent: %s", msg); if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; printf("Received:\n%s",buf); // exit printf("Closing connection...\n"); close(sockfd); return 0; }