socklen_t non déclaré lors de la compilation du code .c

J’essaie de comstackr ce code .c dans Windows en utilisant MinGW (fichier gcc.c -o comstackd.exe):

/***************************************************/ /* AUTHOR : LAW CHIU YUEN */ /* FILENAME : smtpr.c */ /***************************************************/ #ifdef WIN32 #include  #include  #else #define closesocket close #include  #include  #include  #include  #include  #endif #include  #include  #include  #include  #include  #include  //#define MYPORT 40711 // the port users will be connecting to #define PORT 25 #define MAXBUFLEN 1024 // max buffer size #define RELAY_NAME 255 // max length of file name #define BACKLOG 10 // how many pending connections queue will hold #define MAXDATASIZE 512 // max number of bytes we can get at once #define SQMAXDATASIZE 1048576 //1024 * 1024 #define RECVTIME 100 // max number of time to wait for client's message #define MAXEMAILADDRESS 320 // 64 + 1 + 255 #define MAXRCPT 50 //max number of mail receipients /* State1 */ #define ACCEPT 0 #define HELO 1 #define MAILFROM 2 #define RCPTTO 3 #define DATA 4 #define MESSAGE 5 #define QUIT 6 #define RELAY 7 /* State2 */ #define FIRSTHELO 0 #define SECONDHELO 1 #define MAXHELO 1024 /* tokenize mailto ssortingng, each time return the first email address */ /* eg. [email protected],[email protected],[email protected] --> [email protected] */ char* tokenize(char *mailto){ const char delimiters[] = ","; char *token, *cp; printf("b4 strtok: mailto:%s\n",mailto); /* Make writable copy. */ token = strtok (mailto, delimiters); /* token => "words" */ printf("tokenize() speaking : mailto: %s\n",mailto); printf("tokenize() speaking : token: %s\n",token); return token; } /* tokenize mailto ssortingng, each time return the email address other then the first one*/ /* first call: [email protected],[email protected],[email protected] --> [email protected] */ /* second call: [email protected],[email protected],[email protected] --> [email protected] */ char* tokenize_null(){ const char delimiters[] = ","; char *token, *cp; token = strtok (NULL, delimiters); /* token => "words" */ printf("tokenize_null() speaking : token: %s\n",token); return token; } /* take in an email_address, and header; */ /* convert to : header: email_address */ char* compose_mailheader(char *header,char *mail){ char *a = malloc(strlen(mail)+30); char *b = NULL; char *c = NULL; strcpy(a, header); b = strcat(a, mail); c = strcat(b, "\r\n"); printf("compose_mailheader: b=%s\n", b); return b; } /* 1. receive message from smtp server */ void receive(int fd, char* command, char *buf){ int numbytes; if ((numbytes=recv(fd, buf, MAXDATASIZE, 0)) == -1) { fprintf(stderr,"error in receiving\n"); exit(1); } buf[numbytes] = '\0'; printf(" receive() Received buf : %s",buf); if ( strstr(buf, command) != NULL ){ printf(" receive() Received command : %s\n",command); }else{ } } /* helo */ /* 1. called by relaymail() */ /* 2. interact with a smtp server */ void helo(int sockfd){ int numbytes; char buf2[MAXDATASIZE]; char buf[MAXDATASIZE]; printf("\n"); printf("helo is called\n"); /*receive 220*/ receive(sockfd, "220 ", buf); /* send helo */ if (send(sockfd, "HELO server\r\n", 13, 0) == -1) perror("HELO SERVER"); // printf("sent HELO SERVER\n"); /* receive 250*/ receive(sockfd, "250 ", buf); /* testing */ // if (send(sockfd, "HELO server\r\n", 13, 0) == -1) // perror("HELO SERVER"); // receive(sockfd, "250 ", buf); } /* mailfrom */ /* 1. called by relaymail() */ /* 2. interact with a smtp server */ void mailfrom(int sockfd,char *mail_from){ char buf[MAXDATASIZE] = "MAIL FROM:"; char *out; int numbytes; int i; printf("\n"); printf("mailfrom is called\n"); /* compose the "MAIL FROM:[email protected]" message */ strcat(buf, mail_from); strcat(buf, "\r\n"); printf("mailfrom() speaking: buf=%s\n", buf); printf("mailfrom() speaking: strlen(buf)=%i\n", strlen(buf)); /* send out */ if( send(sockfd, buf, strlen(buf), 0) == -1 ) perror("mailfrom()"); /* receive 250*/ receive(sockfd, "250 ", buf); } //mailfrom /* 1. called by rcptto() */ /* 2. interact with a smtp server */ void rcptto2(int sockfd,char *mailtos){ char buf[MAXDATASIZE]=""; char *a; char *out; int numbytes; int i,len; printf("\n"); printf("rcptto2 is called\n"); /* compose the "RCPT TO:[email protected]" message */ strcat(buf, "RCPT TO:"); strcat(buf, tokenize_null()); strcat(buf, "\r\n"); printf("rcptto2() speaking: buf=%s\n", buf); printf("rcptto2() speaking: strlen(buf)=%i\n", strlen(buf)); /* send out */ if( send(sockfd, buf, strlen(buf), 0) == -1 ) perror("rcptto()"); /* receive 250*/ receive(sockfd, "250 ", buf); /* clear the buffer */ for(i=0; i<strlen(buf);i++){ buf[i]='\0'; }//for() } /* rcptto */ /* 1. called by relaymail() */ /* 2. interact with a smtp server */ void rcptto(int sockfd,char *mailtos, int mailto_num){ char buf[MAXDATASIZE] = "RCPT TO:"; char *a; char *out; int numbytes; int i,len; printf("\n"); printf("rcptto is called\n"); /* sending the first address... */ /* compose the "RCPT TO:[email protected]" message */ strcat(buf, tokenize(mailtos)); strcat(buf, "\r\n"); printf("rcptto() speaking: buf=%s\n", buf); printf("rcptto() speaking: strlen(buf)=%i\n", strlen(buf)); /* send out */ if( send(sockfd, buf, strlen(buf), 0) == -1 ) perror("rcptto()"); /* receive 250*/ receive(sockfd, "250 ", buf); /* clear the buffer */ /* handle multiple recipients case*/ for(i=0;i<mailto_num-1;i++) rcptto2(sockfd, mailtos); /* sending remaining addresses... */ } //rcptto /* 1. called by relaymail() */ /* 2. interact with a smtp server */ void data(int sockfd){ char buf[MAXDATASIZE] = ""; printf("\n"); printf("data() is called\n"); /* send "DATA" */ if( send(sockfd, "DATA\r\n", 6, 0) == -1 ) perror("data()"); /* receive 354 */ receive(sockfd, "354 ", buf); } /* 1. called by relaymail() */ /* 2. interact with a smtp server */ void message(int sockfd, char *msg){ int times,i,j; int remainder; printf("\n"); char out[1025]; printf("message() is called\n"); times = strlen(msg) / MAXDATASIZE; remainder = strlen(msg) - (times * MAXDATASIZE); printf("remainder: %i\n", remainder); printf("times: %i\n", times); for (i=0;i< times;i++){ for (j=0;j< 1024;j++) out[j]= msg[1024*i + j]; out[1024 +1] = '\0'; printf("sending msg: %i\n", i); if( send(sockfd, out, 1025, 0) == -1 ); } printf("end while: %i\n", i); printf("out: %s\n", out); for (j=0;jh_addr); memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { fprintf(stderr,"connect fail\n"); exit(1); } while (state <7 && logwhile <10){ /* make sure the program won't run indefinitely */ logwhile++; /* log */ // printf("\n"); // printf("logwhile = %i\n", logwhile); // printf("state = %i\n", state); // printf("\n"); switch (state){ case HELO : helo(sockfd); state++; printf ("end of case HELO\n"); break; case MAILFROM : mailfrom(sockfd, mail_from); state++; printf ("relaymail(): end of case MAILFROM\n"); break; case RCPTTO : rcptto(sockfd, mailto, mailto_num); state++; printf ("relaymail(): end of case RCPTTO\n"); break; case DATA : data(sockfd); state++; printf ("relaymail(): end of case DATA\n"); break; case MESSAGE : message(sockfd, msg); printf ("relaymail(): end of case MESSAGE\n"); state++; printf ("relaymail(): end of case MESSAGE\n"); case QUIT : quit(sockfd); state++; printf ("end of case QUIT\n"); closesocket(sockfd); break; default : break; } } // while() closesocket(sockfd); } /* remove  */ char* remove_brackets(char* input) { int length; int i, j; char* output; length = strlen(input); output = (char*) malloc(length + 1); j = 0; /* copy character of input which in not equal to  to output */ for (i=0; i<length; i++) if ((input[i]!='')) { output[j] = input[i]; j++; } output[j] = '\0'; return output; } /* sortingm the space(s) before and after the ssortingng */ char* sortingm_space(char* input) { int i, j, length, is_ch, is_end, end_pos; char *output; /* sortingm the space(s) before the ssortingng */ length = strlen(input); output = (char*) malloc (length+1); is_ch = 0; is_end = 0; j = 0; for(i=0; i<length; i++) { /* copy input characters to output */ if (is_ch==1 || !isspace(input[i])) { output[j] = input[i]; j++; is_ch = 1; } } output[j] = '\0'; /* trim the space(s) after the string */ length = strlen(output); end_pos = length-1; is_end = 0; for (i=0; i [email protected] */ char *extractemail(const char *buf, const int i){ char * email = NULL; char * tmp_email = NULL; char * tmp_email2 = NULL; char * tmp_email3 = NULL; /* extract email address */ /* 1. remove MAIL FROM: */ email = malloc(strlen(buf)); strcpy(email,buf); email += i; printf("\n"); printf("email =%s\n", email); printf("email length =%i\n", strlen(email)); printf("\n"); /* 2. sortingm head and trailing whitespace */ tmp_email = sortingm_space(email); printf("sortingmmed email= %s\n", tmp_email); /* 3. remove  */ tmp_email2 = remove_brackets(tmp_email); printf("remove email= %s\n", tmp_email2); /* 4. sortingm again */ // tmp_email3 = sortingm_space("[email protected]"); // printf("\n"); // printf("extracted email= ~~~~~~%s~~~~~~\n", tmp_email3); // printf("\n"); // printf("extracted email= ~~~~~~%s~~~~~~\n", tmp_email3); return tmp_email2; } /* check if email address is a valid one */ int check_email_validity(const char *address) { // check if email address is valid // return 1 if valid // return 0 if invalid int number = 0; const char *a, *host; static char *special_characters = "()@,;:\\\"[]"; /* validate name */ for (a = address; *a; a++) { if (*a == '\"' && (a == address || *(a - 1) == '.' || *(a - 1) == '\"')) { while (*++a) { if (*a == '\"') break; if (*a == '\\' && (*++a == ' ')) continue; if (*a = 127) return 0; } if (!*a++) return 0; if (*a == '@') break; if (*a != '.') return 0; continue; } if (*a == '@') break; if (*a = 127) return 0; if (strchr(special_characters, *a)) return 0; } if (a == address || *(a - 1) == '.') return 0; /* next we validate the host portion (name@host) */ if (!*(host = ++a)) return 0; do { if (*a == '.') { if (a == host || *(a - 1) == '.') return 0; number++; } if (*a = 127) return 0; if (strchr(special_characters, *a)) return 0; } while (*++a); return (number >= 1); } int main(int argc, char *argv[]) { int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information int sin_size; int yes=1; socklen_t addr_len; int numbytes=0; char buf[MAXBUFLEN] = ""; char tmp_msg[MAXBUFLEN] =""; char message[SQMAXDATASIZE]; char message_buf[10000]; char *msg = message; char quit[MAXBUFLEN]; int MYPORT; char relay[RELAY_NAME]; int i,j; char *email = NULL; char *email2 = NULL; char *mail_from = NULL; char *mail_to = NULL; char *tmp_mail = NULL; char mailtos[2000]; int mailto_num =0; char *data = NULL; char *data2 = NULL; char *quit1 = NULL; char *quit2 = NULL; int state1 = 0; // int state2 = 0; // keep track of number of 'helo's int logwhile = 0; char hardcode_email[15] = "[email protected]"; #ifdef WIN32 WSADATA wsaData; WSAStartup(0x0101, &wsaData); #endif /* check number of parameters */ if ( argc != 3 && argc !=2 ) { fprintf(stderr,"usage: smtpr  ()\n"); exit(1); } /* fill in port number */ MYPORT = atoi(argv[1]); if ( MYPORT <= 0){ fprintf(stderr, "Invalid port number.\nusage: smtpr  ()\n"); exit(1); } /* fill in the server relay to */ if (argc == 2) strcpy(relay, "some.mail.server"); else if (argc == 3) strcpy(relay, argv[2]); printf("relay to %s\n", relay); /*create a TCP socket */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } printf("port number : %i\n", MYPORT); my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // automatically fill with my IP memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct /* bind to the port number*/ if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } /* listen*/ if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } /* slow the receiving speed */ // sleep(1); while(1){ logwhile++; switch ( state1 ){ case ACCEPT: /* accept */ sin_size = sizeof(struct sockaddr_in); if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); } printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr)); /* send msg : 220 */ if (send(new_fd, "220 cylaw's smtpr ready\r\n", 25, 0) == -1) perror("send"); /*proceed to next state*/ printf("state1 = %i\n", state1); state1++; break; case HELO: if(state2 == 0){ //state2 keep track of if this is the first HELO if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) { perror("recv"); exit(1); } } buf[numbytes] = '\0'; /* log */ printf("case HELO\n"); printf("============\n"); printf("buf :%s\n", buf); /* check on length */ if ( strlen(buf)  MAXDATASIZE ){ printf("550 Syntax: \n"); if (send(new_fd, "550 Syntax:  \r\n", 36, 0) == -1) perror("HELO send"); } /* compare (case-insensitively) the first 4 bytes of buf with "HELO" and "EHLO" */ if ( (strncasecmp(buf, "HELO ", 5) != 0) && (strncasecmp(buf, "EHLO ", 5) != 0 ) ){ printf("550 Syntax: \n"); if (send(new_fd, "550 Syntax:  \r\n", 36, 0) == -1) perror("HELO-1 send"); } /* not implement case : heloaaaaa */ if ( buf[5] == '\0' && buf[5] == ' ' ){ printf("550 Syntax:  \n"); if (send(new_fd, "550 Syntax:  \r\n", 36, 0) == -1) perror("HELO-2 send"); } /* send 250 OK */ printf("250 HELO OK\n"); if ( send( new_fd, "250 HELO OK\r\n", 13, 0 ) == -1 ) perror("HELO-250-OK send"); printf("\n"); /*proceed to next state*/ state1++; state2++; break; //case HELO case MAILFROM : if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; /* log */ printf("\n"); printf("case MAILFROM\n"); printf("=============\n"); printf("buf :%s\n", buf); /* HELO */ if ( (strncasecmp(buf, "HELO ", 5) == 0) || (strncasecmp(buf, "EHLO ", 5) == 0 ) ){ printf("HELO received at case MAILFROM, go back to case HELO\n"); state1--; break; } /* check "MAIL FROM:" */ if ( strncasecmp(buf, "MAIL FROM:", 10) != 0 ){ printf("550 Syntax: MAIL FROM: \n"); if (send(new_fd, "550 Syntax: MAIL FROM: \r\n", 40, 0) == -1) perror("MAIL FROM: send()"); exit(1); } /* extract email address */ mail_from = extractemail(buf, 10); /* check email validity */ if ( check_email_validity(mail_from) == 0 ){ //0 - invalid 1 - valid printf("550 Invalid email address\r\n"); if (send(new_fd, "550 Invalid email address\r\n", 27, 0) == -1) perror("Email address send()"); break; //case MAILFROM } /* send 250 OK */ printf("250 MAIL FROM OK\n"); if ( send( new_fd, "250 MAIL FROM OK\r\n", 18, 0 ) == -1 ) perror("MAILFROM-250-OK send()"); printf("\n"); state1++; break; //case MAILFROM case RCPTTO : /* check if this is the first MAIL FROM:  line */ if ( mailto_num == 0){ if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; } /* log */ printf("\n"); printf("case RCPTTO\n"); printf("=============\n"); printf("state1 = %i\n", state1); printf("buf :%s\n", buf); /* check RCPT TO:  */ if ( strncasecmp(buf, "RCPT TO:", 8) != 0 ){ printf("550 Syntax: RCPT TO: \n"); if (send(new_fd, "550 Syntax: RCPT TO: \r\n", 38, 0) == -1) perror("MAIL FROM: send()"); } /* extract email address */ mail_to = extractemail(buf, 8); // 8 = strlen("RPCT TO:") /* recipients address on to mailtos []*/ strcat(mailtos, mail_to); strcat(mailtos, ","); mailto_num++; printf("mailtos %s\n", mailtos); printf("mailto_num %i\n", mailto_num); /* check email validity */ if ( check_email_validity(mail_to) == 0 ){ printf("550 Invalid email address\n"); if (send(new_fd, "550 Invalid email address\r\n", 27, 0) == -1) perror("RCPTTO address send()"); break; //case MAILFROM } /* send 250 OK */ printf("250 RCPT TO OK\n"); if ( send( new_fd, "250 RCPT TO OK\r\n", 16, 0 ) == -1 ) perror("MAILFROM-250-OK send()"); state1++; break; // case RCPTTO case DATA : if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; /* log */ printf("\n"); printf("case DATA\n"); printf("=============\n"); printf("state1 = %i\n", state1); printf("buf :%s\n", buf); /* multiple recipients */ if ( strncasecmp(buf, "RCPT TO:", 8 ) == 0){ printf("Multiple recipients -- Go back to state RCPT TO\n"); printf("\n"); state1--; break; } if ( strncasecmp(buf,"DATA", 4) != 0 ){ printf("451 Syntax: DATA\n"); if (send(new_fd, "451 Syntax: DATA\r\n", 18, 0) == -1) perror("DATA send"); } else{ /* send 354 OK */ // send( new_fd, "354 End\r\n", 10, 0 ); printf("354 End data with .\n"); if ( send( new_fd, "354 End data with .\r\n", 37, 0 ) == -1 ){ perror("MAILFROM-354-OK send()"); printf("354 error\n"); exit(1); } printf("\n"); } state1++; break; // case DATA case MESSAGE : printf("\n"); printf("case MESSAGE\n"); printf("============\n"); i=0; while(i<10000){ i++; if ((numbytes=recv(new_fd, message_buf, 9999, 0)) == -1) { perror("recv"); exit(1); } message_buf[numbytes] = '\0'; /* log */ // printf("message_buf:\n\n%s", message_buf); /* append message_buf to message */ strcat(message, message_buf); if (strstr (message_buf, "\r\n.\r\n") != NULL ){ /* send 250 OK */ printf(". found\n"); if ( send( new_fd, "250 message received\r\n", 22, 0 ) == -1 ) perror("MESSAGE"); printf("message:\n\n %s\n", message); state1++; break; }//if() }//while() state1++; break; case QUIT : if ((numbytes=recv(new_fd, quit, MAXDATASIZE, 0)) == -1) { perror("recv"); exit(1); } quit[numbytes] = '\0'; /* log */ printf("\n"); printf("case QUIT\n"); printf("=============\n"); printf("buf :%s\n", quit); printf("\n"); /* trim space " QUIT " */ // quit1 = malloc(strlen(quit)); // strcpy(quit1, quit); // printf("quit :%s\n", quit1); // quit2 = trim_space(quit1); // printf("quit :%s\n", quit1); /* check QUIT */ if ( strncasecmp(quit, "QUIT", 4) != 0 ){ state1 = QUIT; if (send(new_fd, "550 Syntax: QUIT\r\n", 18, 0) == -1) perror("QUIT"); }else{ /* send 221 OK */ if ( send( new_fd, "221 QUIT.\r\n", 11, 0 ) == -1 ) perror("QUIT"); printf("QUIT!\n"); closesocket(new_fd); state1++; break; } break; // case QUIT case RELAY : relaymail(relay,mail_from,mailtos,mailto_num, msg); /* go back to ACCEPT states */ state1 = ACCEPT; /* reset variables */ strcpy(buf, ""); strcpy(tmp_msg, ""); strcpy(message, ""); strcpy(message_buf, ""); strcpy(quit,""); i=0;j=0; email = NULL; email2 = NULL; mail_from = NULL; mail_to = NULL; tmp_mail = NULL; strcpy(mailtos, ""); mailto_num =0; data = NULL; data2 = NULL; quit1 = NULL; quit2 = NULL; state2 = 0; break; default : break; }//switch } // while(1) close(new_fd); #ifdef WIN32 WSACleanup(); #endif return 0; } 

Mais son échec avec l’erreur:

 C:\MinGW\bin>gcc file.c -o comstackd.exe file.c: In function `main': file.c:973: error: `socklen_t' undeclared (first use in this function) file.c:973: error: (Each undeclared identifier is reported only once file.c:973: error: for each function it appears in.) file.c:973: error: syntax error before "addr_len" 

J’ai essayé de googler l’erreur mais tout ce que j’ai trouvé, c’est des informations sur la compilation de logiciels spécifiques, mais pas sur ce qui pourrait en être la cause.

Que puis-je faire pour corriger cette erreur?

Déterminez le fichier .h dans lequel il est défini et incluez-le. Sur une boîte Unix / Linux, je commencerais par un find / grep dans / usr / include

 $ find /usr/include -name \*.h -print0 |xargs -0 grep -w socklen_t ... /usr/include/unistd.h:typedef __socklen_t socklen_t; ... /usr/include/sys/socket.h: socklen_t *__ressortingct __addr_len); 

On dirait qu’il est défini dans unistd.h – mais vous l’avez déjà inclus, alors je suppose que vous êtes couvert de ce côté. Je ne sais pas comment trouver le fichier à inclure du côté Windows.

Sous mingw, vous pouvez essayer d’inclure ws2tcpip.h

 #include  

Vérifiez votre socket.h – c’est probablement là où il est défini. Votre code comstack bien avec CygWin puisque le socket.h contient (en vertu de cygwin/socket.h ):

 typedef int socklen_t; 

En tant que kludge, vous pouvez essayer d’append cette ligne à votre propre code. Mais vous devriez toujours chercher pourquoi il manque et peut-être faire un rapport de bogue.

Il y a beaucoup de pages qui se plaignent que MinGW ne supporte pas socklen_t, par exemple ici , ici , ici et ici , le dernier indique qu’il réside dans ws2tcpip.h tel que je l’ai défini ci-dessus.

Selon la spécification Unix , socket.h met à disposition un type, socklen_t, qui est un type intégral opaque non signé d’une longueur d’au moins 32 bits. Apparemment, MingW ne l’inclut pas.

Vous pouvez le définir comme:

 #include  typedef uint32_t socklen_t;