/* ** Logger module for fhttpd ** fhttpd-log.cc Copyright (C) 1995-99 Alex Belits ** This code is a part of fhttpd distribution */ #include #include #include #include #include #include #include #ifdef SOLARIS extern "C"{ void bzero(void *s, size_t n); int gethostname(char *name, int namelen); } #endif #ifdef IRIX #include "irix-fix.h" #endif #ifdef GETOPT_VARS_NOT_DEFINED extern char *optarg; extern int optind, opterr; #endif #include "fhttpd-decls.h" #include "configargs.h" #include "lists.h" #include "wildmat.h" #ifndef FHTTPD_CONFIG_FILE #define FHTTPD_CONFIG_FILE "/etc/fhttpd.conf" #endif extern "C" { #include "servproc.h" } int global_resolve_hostnames=1; char *configcommands[NCONFIGCOMMANDS]={ "NORESOLVE","HONORKEEPALIVE","HTTPPORT","FTPPORT","PROCESSPORT", "STORMODE","ABSSTORMODE","MKDMODE","ABSMKDMODE", "INBOUND","ABSINBOUND","PIPEINEXEC","ABSPIPEINEXEC", "PIPEOUTEXEC","ABSPIPEOUTEXEC", "DEFAULTHEADER","DEFAULTFOOTER","TYPE","ABSTYPE","DIRTYPE","ABSDIRTYPE", "GETRULE","ABSGETRULE","EXECMASK","SPECIALEXECMASK", "ACCESSREALM","ACCESSRIGHTS", "PRELOAD","HTTPROOT","ADDRESSROOT","APPLICATION","AUTHAPPLICATION", "LOGAPPLICATION", "UMASK","MAXCONTENTLENGTH","MAXMESSAGESIZE", "MAXDATAINQUEUE","MAXDATAINLOGQUEUE","USERDIR","MAPUSERDIR"}; char *strupr(char *s){ char *s1=s; while(*s1){ if(*s1>='a'&&*s1<='z') *s1&=0xdf; s1++; } return s; } int filenamecmp(char *s1,char *s2,int *noslashflag){ int noslashvar,*noslash=&noslashvar; char *s11=s1,*s22=s2; int n; if(noslashflag) noslash=noslashflag; while(*s11==*s22&&*s11){ s11++; s22++; } if(!*s11&&!*s22) return 0; if(*s11!='/'&&*s22!='/'){ if(s11==s1) return 1; s11--; s22--; } n=((*s11=='/')<<1)|(*s22=='/'); switch(n){ case 0: return 1; case 1: // *s22=='/' && *s11!='/' if(*s11) return 1; if(!s22[1]){ *noslash=1; return 0; } if(!strcmp(s22,"/file_index.html")){ *noslash=1; return 0; } if(!strcmp(s22,"/index.html")){ *noslash=1; return 0; } return 1; case 2: // *s11=='/' && *s22!='/' if(*s22) return 1; if(!s11[1]){ *noslash=1; return 0; } if(!strcmp(s11,"/file_index.html")){ *noslash=1; return 0; } if(!strcmp(s11,"/index.html")){ *noslash=1; return 0; } return 1; default: // *s11=='/' && *s22=='/' if(s22[1]) if(strcmp(s22,"/file_index.html")) if(strcmp(s22,"/index.html")) return 1; if(!s11[1]) return 0; if(!strcmp(s11,"/file_index.html")) return 0; if(!strcmp(s11,"/index.html")) return 0; return 1; } } void unconfig(void){ global_resolve_hostnames=1; } int readconfig(char *name){ char buffer[MESSAGE_BUFFER_SIZE],*p,*p1,*param[20]; int i,l,nparam,nline=0; FILE *f; f=fopen(name,"rt"); if(f){ while(fgets(buffer,MESSAGE_BUFFER_SIZE,f)){ nline++; do{ buffer[(MESSAGE_BUFFER_SIZE-1)]=0; p=strchr(buffer,'\n'); if(p) *p=0; p=strchr(buffer,'\r'); if(p) *p=0; p=strchr(buffer,'#'); if(p) *p=0; p=strrchr(buffer,'\\'); if(p){ p1=p+1; while(p&&*p1){ if(((unsigned char)*p1)>' '){ p=NULL; }else p1++; } if(p){ fgets(p,MESSAGE_BUFFER_SIZE-(p-buffer),f); nline++; } } }while(p&&p-buffer<(MESSAGE_BUFFER_SIZE-1)); i=0; nparam=0; l=strlen(buffer); while(buffer[i]&&((unsigned char)buffer[i]<=' ')) i++; if(buffer[i]){ do{ while(buffer[i]&&(unsigned char)buffer[i]<=' ') i++; param[nparam]=buffer+i; for(;(unsigned char)buffer[i]>' ';i++); if(buffer[i]&&(unsigned char)buffer[i]<=' '){ buffer[i]=0; i++; } if(!nparam){ strupr(param[0]); } nparam++; }while(i Log filename\n" " -u Set umask\n" " -c fhttpd config file\n", server->app_progname); exit(1); break; case APP_ERR_CONFIG: fprintf(stderr,"%s: configuration error\n",server->app_progname); exit(1); break; case APP_ERR_READ: fprintf(stderr,"%s: read error\n",server->app_progname); exit(1); break; case APP_ERR_HOSTNAME: fprintf(stderr,"%s: can't resolve server hostname\n",server->app_progname); exit(1); break; case APP_ERR_SOCKET: fprintf(stderr,"%s: can't create socket\n",server->app_progname); exit(1); break; case APP_ERR_CONNECT: fprintf(stderr,"%s: can't connect\n",server->app_progname); exit(1); break; case APP_ERR_APPCONNECT: fprintf(stderr,"%s: connect error\n",server->app_progname); exit(1); break; case APP_ERR_USER: fprintf(stderr,"%s: login error\n",server->app_progname); exit(1); break; case APP_ERR_PASSWORD: fprintf(stderr,"%s: login error\n",server->app_progname); exit(1); break; case APP_ERR_APPLICATION: fprintf(stderr,"%s: application rejected by server\n",server->app_progname); exit(1); break; case APP_ERR_INSANE: case APP_ERR_DAEMON: case APP_ERR_AUTH: default: if(server->infd<0) exit(1); } if(server->infd==0&&server->outfd==1){ int fd2; close(2); fd2=open("/dev/null",O_WRONLY); if(fd2!=2){ dup2(fd2,2); close(fd2); } } readconfig(configfile); logfile=fopen(logfilename,"a"); if(!logfile) return -1; while((req=readrequest(server))){ if(req->reqtype==FHTTPD_LOG_REQUEST){ clientid=0; requestid=0; instid=0; t_sec=0; t_usec=0; if(req->databuffsize==6*sizeof(__s32)){ memcpy(&nclientid,req->databuffer,sizeof(__s32)); memcpy(&nrequestid,req->databuffer+sizeof(__s32),sizeof(__s32)); memcpy(&ninstid,req->databuffer+sizeof(__s32)*2,sizeof(__s32)); memcpy(&n_t_sec,req->databuffer+sizeof(__s32)*3,sizeof(__s32)); memcpy(&n_t_usec,req->databuffer+sizeof(__s32)*4,sizeof(__s32)); clientid=htonl(nclientid); requestid=htonl(nrequestid); instid=htonl(ninstid); t_sec=htonl(n_t_sec); t_usec=htonl(n_t_usec); if(t_usec>=1000000){ t_sec++; t_usec=0; } } struct tm *t_tm=localtime(&t_sec); char tmpline1[32],tmpline2[16]; strftime(tmpline1,31,"%b %d %H:%M:%S",t_tm); strftime(tmpline2,15,"%Z %Y",t_tm); for(i=0;inlines;i++){ switch(req->lines[i].paramc){ case 1: fprintf(logfile,"%s.%06ld %s %d %d %d %s\n",tmpline1,t_usec,tmpline2,clientid,requestid,instid,req->lines[i].params[0]); break; case 2: fprintf(logfile,"%s.%06ld %s %d %d %d %s %s\n",tmpline1,t_usec,tmpline2,clientid,requestid,instid,req->lines[i].params[0],req->lines[i].params[1]); break; } } fflush(logfile); }else{ fflush(logfile); if(req->reqtype==FHTTPD_EXITOK){ exit(0); } } deleterequest(req); } }