2016-03-15 2 views
0

J'ai un client http écrit en c, et dans certaines sections j'ai le temps et remplir le tampon, j'ai vérifié toutes les valeurs d'entrée sont valides, mais lorsque la fonction s'exécute, il donne la faute de segmentation, numéro de ligne 77, la ligne:SIGSEGV sur strftime (libc.so.6) en utilisant gcc (GCC) 5.3.0

strftime (timebuf, sizeof (timebuf), RFC1123FMT, gmtime (& maintenant));

i testé les entrées par le débogueur et non d'entre eux est problématique

Après avoir compilé exécution avec cette commande

./COMPILED_FILE_NAME https://stackoverflow.com/ -d 1: 1: 1

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <netinet/in.h> 
#include <netinet/ip.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <sys/types.h> 
#define HEADER "-h" 
#define TIME_STAMP "-d" 
#define PROTOCOL "http://" 
#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT" 
#define DEFAULT_PORT 80 
#define BUFFER_SIZE 256 
typedef struct sockaddr_in sockaddr_t; 
void printError(int flag,char * name); 
int parseUrl(char * url,char** host,int * portt ,char ** path); 
int checkString(const char * date); 
int parseDate(char* date,int * day,int * hour,int* minute); 
void freeData(); 
int socketConnect(char * host,int port,char * page,char* requestType , char * dateRequest); 
char * host; // the url with out any addititons 
char * path; // the path after the url 

int main(int argc,char * argv[]) 
{ 

    time_t now; 
    now = time(NULL); 
    char timebuf[BUFFER_SIZE/2]; 
    int headrFlag=0; 
    int timeFlag=0; 
    int day=0,hour=0,minute=0; 

    // char * host;//=(char*)malloc(sizeof(char)*128); 
    // char * path;//=(char*)malloc(sizeof(char)*128); 

    char requestType[BUFFER_SIZE]; 
    char dateRequest[BUFFER_SIZE]; 
    bzero(dateRequest,sizeof(dateRequest)); 

    strcpy(requestType,"GET"); 
    int port=DEFAULT_PORT; 
    if(argc >1 && argc <=5) // the host at least their 
    { 
// checking the incoming args 
     int i = 1; 
     for(;i<argc;i++) 
     { 
      if(strcmp(argv[i],HEADER)==0) 
      { 
       if(headrFlag==0) 
       { 
       headrFlag=1; 
       strcpy(requestType,"HEAD"); 
       } 
       else 
       { 
        printError(0,""); 
        break; 

       } 

      } 
      else if(strcmp(argv[i],TIME_STAMP)==0) 
      { 
       // take the date from the next i , if not there as error 
       if(timeFlag==0) 
       { 
        timeFlag=1; 
        if(i+1!=argc && parseDate(argv[i+1],&day,&hour,&minute)!=-1) // there is date "thing" after the flag 
        { 

         now=now-(day*24*3600+hour*3600+minute*60); //where day, hour and min are the values 
         //from the input 
         strftime(timebuf, sizeof(timebuf), RFC1123FMT, gmtime(&now)); 
         //timebuf holds the correct format of the time 

         sprintf(dateRequest,"If-Modified-Since: %s\n",timebuf); 

          i++; 


          continue; 

        } 
        else 
        { 
         printError(1,""); 

        } 

       } 
       else 
       { 
         printError(0,""); 

       } 

        printError(0,""); 
        break; 



      } 
      else // the host 
      { 
       if(parseUrl(argv[i],&host,&port,&path)<0) 
       { 
        printError(1,""); 
       } 

      } 


     } 

     // connect after every thing is valid 
      if(host!=NULL){socketConnect(host,port,path,requestType,dateRequest);}else{printError(0,"");} 



    } 
    else 
    { 
     printError(1,""); 
    } 




    return 0; 
} 

void printError(int flag,char * name) 
{ 
    // 0 wrong command usage 
    //1 wrong input 
    //2 system call failure 
    if(flag==0) 
    { 
     printf("Usage: client [-h] [-d <time-interval>] <URL>\n"); 
    } 
    else if(flag==1) // wrong input 
    { 
     printf("wring input\n"); 
    } 
    else // flag ==2 , sys calls 
    { 
     perror(name); 
    } 
    freeData(); 
      exit(-1); 


} 
// handles the validation of the url 
int parseUrl(char * url,char** host,int * portt ,char ** path) 
{ 

    char * det=":"; 
    char * det1="/"; 
    char * port; 
    char * temp; 
    char * pathValue; 
    int pathSize=0,hostSize=0; 
    int addSize=0; 
    int portNumber=80; 


    char * urlToParse; 
    if((temp=strstr(url,PROTOCOL))!=NULL && temp==url) // checking http:// 
    { 

     temp=&temp[strlen(PROTOCOL)]; 
     urlToParse=temp; 
     if(strlen(urlToParse) <=1) 
      return -1; 
    } 
    else 
    { 
     return -1; 
    } 
    if((temp=strstr(temp,det))!=NULL) // checking port 
    { 
     int len1 = strlen(temp)-1; // length from the : to the end 
     addSize=len1; 
     char * temp1; 
     if((temp1=strstr(temp,det1))!=NULL) 
     { 
      pathSize= strlen(temp1); 
      pathValue=temp1; 
      int portLength= len1-pathSize; 
      port = (char*)malloc(sizeof(char)*portLength+1); 
      if(port==NULL) 
      { 
       printError(2,"malloc"); 
      } 
      port[portLength]='\0'; 
      strncpy(port,++temp,portLength); 
      if(checkString(port)<0) 
       return -1; 
      portNumber=atoi(port); 
      free(port); 
       addSize=len1+1; 


     } 

    } 
    else // no port 
    { 
     temp=urlToParse; 



     if((temp=strstr(temp,det1))==NULL) // checking filepath 
     { 
      return -1; 
     } 
     else 
     { 
        pathValue=temp; 
        pathSize=strlen(temp); 
        addSize=pathSize; 

     } 

    } 
     hostSize=strlen(urlToParse)-addSize; 

      *host =(char*)malloc(sizeof(char)*(hostSize+1)); 
      if(*host==NULL) 
      { 
       printError(2,"malloc"); 
      } 
      **host=NULL; 
      * path =(char*)malloc(sizeof(char)*(pathSize+1)); 
      if(*path==NULL) 
      { 
      printError(2,"malloc"); 

      } 
      **path=NULL; 

      // *path=pathValue; 
      strcpy(*path,pathValue); 
      *portt=portNumber; 

    strncpy(*host,urlToParse,hostSize); 




    return 0; 
} 

// checks if the number is valid 
int checkString(const char * date) 
{ 
    if(date==NULL || strcmp(date,"")==0) 
    { 
     return -1; 
    } 
    int len = strlen(date); 
    if(strlen(date)>1 && strncmp(&date[0],"-",1)==0 ) 
    { 
     date++; 
    } 
    while(date && strcmp(date,"")!=0) 
    { 

     if(isdigit(*(date++))==0) 
     { 
      return -1; 
     } 
    } 
    return 1; 
} 

// converts from chars to int 
int parseDate(char* date,int * day,int * hour,int* minute) 
{ 

char * det=":"; 
    // int days,hours,minutes; 

    char * dayss = strtok(date,det); 
    char * hourss = strtok(NULL,det); 
    char * moinutss = strtok(NULL,det); 
    if(dayss ==NULL || hourss==NULL||moinutss==NULL) 
    { 
     return -1; 
    } 

    if(checkString(dayss)<0 || checkString(hourss)<0 || checkString(moinutss)<0 ) 
     return -1; 
    *day = atoi(dayss); 
    *hour= atoi(hourss); 
    *minute=atoi(moinutss); 
    return 1; 



} 
// free what ever memory we used 
void freeData() 
{ 
    if(host !=NULL) 
    { 
     free(host); 

    } 
    if(path!=NULL) 
    { 
     free(path); 
    } 

} 
// handles the connection to the server 
int socketConnect(char * host,int port,char * page,char* requestType , char * dateRequest) 
{ 
      struct in_addr serverIp; 
      struct hostent * hostt =NULL; 
      hostt= (struct hostent *)gethostbyname(host); 
      if(hostt==NULL) 
      { 
       freeData(); 
       herror(""); 
       printf("\n"); 
       exit(0); 
      } 
      struct addr_in** addresses = (struct in_addr **)hostt->h_addr_list; 
      int i=0; 

      // char * ss= inet_ntoa(((struct in_addr*)hostt->h_addr)->s_addr); 

    // serverIp.s_addr=inet_addr(ss); 

    struct sockaddr_in packet; 

     packet.sin_family=AF_INET; 
     packet.sin_port=htons(port); 
     packet.sin_addr.s_addr=((struct in_addr*) hostt->h_addr)->s_addr; 

    int socketFd ; 
    if((socketFd=socket(PF_INET,SOCK_STREAM,0))<0) 
    { 
     printError(2,"socket"); 
    } 

    if(connect(socketFd,(struct sockaddr*)&packet,sizeof(packet))<0) 
    { 
     printError(2,"connect"); 

    } 


    char buffer[BUFFER_SIZE*4]; 
    char * req = malloc(sizeof(requestType)+sizeof(page)+sizeof(dateRequest)+BUFFER_SIZE); 
    if(req==NULL) 
    { 
     freeData(2,"malloc"); 
    } 

     sprintf(req,"%s http://%s%s HTTP/1.0\r\n%s\n",requestType,host,page,dateRequest); 



    printf("HTTP request =\n%s\nLEN = %d\n",req,strlen(req)); 
    send(socketFd,req,strlen(req),0); 

    int sizeOfResponse=0; 

    int reading=0 ; 
    do 
    { 

     bzero(buffer,sizeof(buffer)); 
     reading= read(socketFd,buffer,sizeof(buffer),0); 
     if(reading >0) 
     { 
     printf("%s",buffer); 
     sizeOfResponse=sizeOfResponse+strlen(buffer); 

     } 

    } 
    while(reading>0); 
    printf("\nTotal received response bytes: %d\n",sizeOfResponse); 
    close(socketFd); 
    free(req); 
     freeData(); 




} 

Répondre

0

cause racine : vous devez #include <time.h>.

La raison en est que sans une déclaration dans la portée, le compilateur suppose que gmtime() renvoie int. En réalité, il retourne struct tm *, et apparemment sur votre plate-forme un pointeur est plus large que l'entier.

Vous devez activer tous les avertissements et faire attention à eux.