/* tic files support */ #include #include #include #include #include #include #include #include #include #include "config.h" ilist_t *ticlist_list; int ticlist_list_max; void readtic(ticlist_t *tlist) /* read tic file from ony ticlist_t */ { char buff[BUFSIZE>PATH_MAX?BUFSIZE:PATH_MAX]; FILE *fp; tic_t *cur; int linecnt; char *v,*k; node_t tmp_node; int i,j; ass(tlist!=NULL); ass(tlist->tic==NULL); ass(tlist->name!=NULL); ass(tlist->path!=NULL); strcpy(buff,tlist->path); strcat(buff,"/"); strcat(buff,tlist->name); fp=fopen(buff,"rb"); if(fp==NULL) { e_printf("readtic: unable to read ticfile \"%s\" - ignored", buff); /* TODO: mark tic as bad here */ return; } cur=xmalloc(sizeof(tic_t)); /* tic_t initialization */ cur->area=NULL; cur->areadesc=NULL; cur->file=NULL; cur->realname=NULL; cur->fullname=NULL; cur->magic=NULL; cur->replaces=NULL; cur->ldesc=NULL; cur->desc=NULL; cur->max_desc=0; cur->max_ldesc=0; cur->size=-1; cur->date=-1; cur->release=-1; cur->author=NULL; cur->source=NULL; cur->app=NULL; cur->max_app=0; (cur->origin).zone=0; (cur->from).zone=0; cur->from_pwd=NULL; (cur->to).zone=0; cur->created=NULL; cur->via=NULL; cur->max_via=0; cur->path=NULL; cur->max_path=0; cur->seenby=NULL; cur->pw=xstrcpy("*"); /* see Notes2 */ linecnt=0; while(fgets(buff,sizeof(buff)-1,fp)) { delcrlf(buff); linecnt++; if(buff[0]==0) continue; v=strschr(buff,DELIM); /* printf("DEBUG: %s=%s\n",buff,v?v:"?null?");*/ if(v==NULL) continue; /* blank keywords should be dropped (by FSC-0087) */ /* this string must follows v==NULL check */ strschr2(buff,DELIM)[0]=0; if(!strcasecmp(buff,"area")) { cur->area=xstrcpy(v); } else if(!strcasecmp(buff,"areadesc")) { cur->areadesc=xstrcpy(v); } else if(!strcasecmp(buff,"file")) { /* if all chars of v isupper(), change filename to lower case */ j=strlen(v); for(i=0;ifile=xstrcpy(v); } else if(!strcasecmp(buff,"fullname")) { cur->fullname=xstrcpy(v); } else if(!strcasecmp(buff,"magic")) { cur->magic=xstrcpy(v); } else if(!strcasecmp(buff,"replaces")) { cur->replaces=xstrcpy(v); /*printf("FUCK: %p,%s\n",cur->replaces,cur->replaces);*/ /*printf("DEBUG2: cur=%p\n",cur);*/ } else if(!strcasecmp(buff,"author")) { cur->author=xstrcpy(v); } else if(!strcasecmp(buff,"created")) { cur->created=xstrcpy(v); } else if(!strcasecmp(buff,"pw")) { if(cur->pw) xfree(cur->pw); /* see Notes2 */ cur->pw=xstrcpy(v); } else if(!strcasecmp(buff,"crc")) { cur->crc=strtoul(v,NULL,16); } else if(!strcasecmp(buff,"size")) { cur->size=strtoul(v,NULL,10); } else if(!strcasecmp(buff,"date")) { cur->date=strtoul(v,NULL,10); } else if(!strcasecmp(buff,"release")) { cur->release=strtoul(v,NULL,10); } else if(!strcasecmp(buff,"source")) { cur->source=xstrcpy(v); } else if(!strcasecmp(buff,"origin")) { if(ftntonode(&(cur->origin),v,NULL)) e_printf("bad address \"%s\"",v); } else if(!strcasecmp(buff,"to")) { if(ftntonode(&(cur->to),v,NULL)) e_printf("bad address \"%s\"",v); } else if(!strcasecmp(buff,"from")) { k=strchr(buff,' '); if(k) k[0]=0; if(ftntonode(&(cur->from),v,NULL)) e_printf("bad address \"%s\"",v); if(k) cur->from_pwd=xstrcpy(k+1); } else if(!strcasecmp(buff,"desc")) { k=xstrcpy(v); if(cur->max_desc==0) { cur->desc=ilist_init(); } ilist_add(cur->desc,cur->max_desc,k); cur->max_desc++; } else if(!strcasecmp(buff,"ldesc")) { k=xstrcpy(v); if(cur->max_ldesc==0) { cur->ldesc=ilist_init(); } ilist_add(cur->ldesc,cur->max_ldesc,k); cur->max_ldesc++; } else if(!strcasecmp(buff,"path")) { k=xstrcpy(v); if(cur->max_path==0) { cur->path=ilist_init(); } ilist_add(cur->path,cur->max_path,k); cur->max_path++; } else if(!strcasecmp(buff,"via")) { k=xstrcpy(v); if(cur->max_via==0) { cur->via=ilist_init(); } ilist_add(cur->via,cur->max_via,k); cur->max_via++; } else if(!strcasecmp(buff,"seenby")) { /* k=xstrcpy(v);*/ if(cur->seenby==NULL) cur->seenby=list_init(); if (ftntonode(&tmp_node,v,NULL)) e_printf("bad address \"%s\"", v); nodetoftn(buff,&tmp_node); list_add(cur->seenby,buff,""); } else if(!strcasecmp(buff,"Destination")) continue; /* skip for ALLFIX+ */ else if(!strcasecmp(buff,"pgp")) continue; /* skip by FSC-0087 */ else if(!strcasecmp(buff,"ReceiptRequest")) continue; /* skip by FSC-0087 */ else { l_printf("readtic: %s(%d) - %s[%s] - keyword unknown - ignored", tlist->name,linecnt,buff,v); continue; } } if(cur->area==NULL || cur->file==NULL || cur->crc==0 || /* TODO: rewrite unknown-crc32 check */ (cur->origin).zone==0 || (cur->from).zone==0 || cur->created==NULL || cur->path==NULL || cur->seenby==NULL || cur->pw==NULL ) { tlist->bad=TRUE; l_printf("BADTIC: ticname=%s, not full tic-header (see FSC-0087)", tlist->name); } tlist->tic=cur; fclose(fp); } void read_tics_from_list(void) /* read all tic files from ticlist_list */ { int i; ilist_t *tmp; ass(ticlist_list!=NULL); for(i=0;id_name,TICPATTERN)) { strcpy(buff,dirname); strcat(buff,"/"); strcat(buff,dirp->d_name); ass(stat(buff,&stat_buf)==0); if(!(stat_buf.st_mode & S_IFREG)) continue; /* ticlist_t initialization */ cur=(ticlist_t *)xmalloc(sizeof(ticlist_t)); cur->bad=FALSE; cur->type=ticlist_type; cur->path=dirname; cur->name=xstrcpy(dirp->d_name); cur->badname=NULL; cur->old_tic=OLDTIC_OK; cur->ctime=stat_buf.st_ctime; cur->tic=NULL; /*printf("DEBUG: _readticlist_readdir - type=%d, path=%s, name=%s, ctime=%d\n", cur->type,cur->path,cur->name,(int)cur->ctime); */ ilist_add(ticlist_list,ticlist_list_max++,cur); } } closedir(dir); } void freeticlist(void) /* free all ticlist_t from ticlist_list */ { int i; ticlist_t *tl_tmp; if(!ticlist_list) { e_printf("warning: trying to freeticlist zero ticlist_t - ignored"); return; } for(i=0;ibadname) xfree(tl_tmp->badname); if(tl_tmp->name) xfree(tl_tmp->name); if(tl_tmp->bad==FALSE) /* Free tic in memory ONLY if this is GOOD tic */ if(tl_tmp->tic) freetic(tl_tmp->tic); xfree(tl_tmp); } ilist_free(ticlist_list); } void readticlist(void) /* read tics from inbound and possibly from bad_dir */ { ticlist_list_max=0; ticlist_list=ilist_init(); _readticlist_readdir(inbound,TICLIST_INBOUND); if(toss_badtic) _readticlist_readdir(bad_dir,TICLIST_BADDIR); if(ticlist_list_max==0) { l_printf("EXIT: no tics found"); exit(0); } } static void _free_ilist(ilist_t *lst,int max,char *info,tic_t *tic) { int i; char *ctmp; /*printf("DEBUG: &lst=%p\n",lst);*/ if(lst) { for(i=0;ifile=%s,key=%d)", info,tic->file?tic->file:"?null pointer?",i); } /*printf("DEBUG: %s\n",ctmp); */ xfree(ctmp); } ilist_free(lst); } } void freetic(tic_t *tic) /* frees one tic_t */ { if(!tic) { e_printf("warning: trying to freetic zero tic_t - ignored"); return; } _free_ilist(tic->desc, tic->max_desc, "desc", tic); _free_ilist(tic->ldesc, tic->max_ldesc, "ldesc", tic); _free_ilist(tic->app, tic->max_app, "app", tic); _free_ilist(tic->via, tic->max_via, "via", tic); _free_ilist(tic->path, tic->max_path, "path", tic); list_free(tic->seenby); if(tic->area) xfree(tic->area); if(tic->areadesc) xfree(tic->areadesc); if(tic->file) xfree(tic->file); if(tic->realname) xfree(tic->realname); if(tic->fullname) xfree(tic->fullname); if(tic->magic) xfree(tic->magic); if(tic->replaces) xfree(tic->replaces); if(tic->author) xfree(tic->author); if(tic->source) xfree(tic->source); if(tic->from_pwd) xfree(tic->from_pwd); if(tic->created) xfree(tic->created); if(tic->pw) xfree(tic->pw); xfree(tic); } tic_t *copytic(tic_t *tic) /* copy all members of tic_t to new tic_t allocate memory for any of pointer of original tic to new tic and copy pointer content */ { tic_t *tmp; int i; list_t *ltmp; char *ctmp; tmp=xmalloc(sizeof(tic_t)); tmp->desc=NULL; tmp->ldesc=NULL; tmp->app=NULL; tmp->via=NULL; tmp->path=NULL; tmp->seenby=NULL; tmp->crc=tic->crc; tmp->size=tic->size; tmp->date=tic->date; tmp->release=tic->release; tmp->max_desc=tic->max_desc; tmp->max_ldesc=tic->max_ldesc; tmp->max_app=tic->max_app; tmp->max_via=tic->max_via; tmp->max_path=tic->max_path; nodecpy(&(tmp->origin),&(tic->origin)); nodecpy(&(tmp->from),&(tic->from)); nodecpy(&(tmp->to),&(tic->to)); /* xstrcpy returns NULL if argument==NULL */ tmp->area=xstrcpy(tic->area); tmp->source=xstrcpy(tic->source); tmp->areadesc=xstrcpy(tic->areadesc); tmp->file=xstrcpy(tic->file); tmp->realname=xstrcpy(tic->realname); tmp->fullname=xstrcpy(tic->fullname); tmp->magic=xstrcpy(tic->magic); tmp->replaces=xstrcpy(tic->replaces); tmp->author=xstrcpy(tic->author); tmp->from_pwd=xstrcpy(tic->from_pwd); tmp->created=xstrcpy(tic->created); tmp->pw=xstrcpy(tic->pw); if(tic->max_desc) { tmp->desc=ilist_init(); for(i=0;imax_desc;i++) { ctmp=ilist_find_entry(tic->desc,i); ass(ctmp!=NULL); ilist_add(tmp->desc,i,xstrcpy(ctmp)); } } if(tic->max_ldesc) { tmp->ldesc=ilist_init(); for(i=0;imax_ldesc;i++) { ctmp=ilist_find_entry(tic->ldesc,i); ass(ctmp!=NULL); ilist_add(tmp->ldesc,i,xstrcpy(ctmp)); } } if(tic->max_app) { tmp->app=ilist_init(); for(i=0;imax_app;i++) { ctmp=ilist_find_entry(tic->app,i); ass(ctmp!=NULL); ilist_add(tmp->app,i,xstrcpy(ctmp)); } } if(tic->max_via) { tmp->via=ilist_init(); for(i=0;imax_via;i++) { ctmp=ilist_find_entry(tic->via,i); ass(ctmp!=NULL); ilist_add(tmp->via,i,xstrcpy(ctmp)); } } if(tic->max_path) { tmp->path=ilist_init(); for(i=0;imax_path;i++) { ctmp=ilist_find_entry(tic->path,i); ass(ctmp!=NULL); ilist_add(tmp->path,i,xstrcpy(ctmp)); } } if(tic->seenby) /* maybe check list_head_max of seenby? */ { tmp->seenby=list_init(); for(i=0;iseenby);i++) { ltmp=list_get(tic->seenby,i); ass(ltmp!=NULL); ass(list_key(ltmp)!=NULL); list_add(tmp->seenby,list_key(ltmp),""); } } return tmp; } int writeticFILE(tic_t *tic,FILE *fp) { char buff[BUFSIZE],ftmp[FTN_MAX_SIZE]; int i; list_t *ltmp; char *p; if(fp==NULL) return 1; if(tic->area) { snprintf(buff,sizeof(buff)-1,"Area %s\r\n",tic->area); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->areadesc) { snprintf(buff,sizeof(buff)-1,"Areadesc %s\r\n",tic->areadesc); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->file) { snprintf(buff,sizeof(buff)-1,"File %s\r\n",tic->file); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->fullname) { snprintf(buff,sizeof(buff)-1,"Fullname %s\r\n",tic->fullname); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } snprintf(buff,sizeof(buff)-1,"Crc %lX\r\n",tic->crc); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; if(tic->magic) { snprintf(buff,sizeof(buff)-1,"Magic %s\r\n",tic->magic); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->replaces) { snprintf(buff,sizeof(buff)-1,"Replaces %s\r\n",tic->replaces); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->max_desc) for(i=0;imax_desc;i++) { p=ilist_find_entry(tic->desc,i); ass(p!=NULL); snprintf(buff,sizeof(buff)-1,"Desc %s\r\n",p); str_truncate(80,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->max_ldesc) for(i=0;imax_ldesc;i++) { p=ilist_find_entry(tic->ldesc,i); ass(p!=NULL); snprintf(buff,sizeof(buff)-1,"Ldesc %s\r\n",p); str_truncate(80,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->size!=(unsigned long)(-1)) { snprintf(buff,sizeof(buff)-1,"Size %lu\r\n",tic->size); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->date!=(time_t)(-1)) { snprintf(buff,sizeof(buff)-1,"Date %lu\r\n",tic->date); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->release!=(time_t)(-1)) { snprintf(buff,sizeof(buff)-1,"Release %lu\r\n",tic->release); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->author) { snprintf(buff,sizeof(buff)-1,"Author %s\r\n",tic->author); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->source) { snprintf(buff,sizeof(buff)-1,"Source %s\r\n",tic->source); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->max_app) for(i=0;imax_app;i++) { p=ilist_find_entry(tic->app,i); ass(p!=NULL); snprintf(buff,sizeof(buff)-1,"App %s\r\n",p); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if((tic->origin).zone!=0) { nodetoftn(ftmp,&(tic->origin)); snprintf(buff,sizeof(buff)-1,"Origin %s\r\n",ftmp); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if((tic->from).zone!=0) { nodetoftn(ftmp,&(tic->from)); snprintf(buff,sizeof(buff)-1,"From %s%s%s\r\n", ftmp,tic->from_pwd?" ":"",tic->from_pwd?tic->from_pwd:""); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if((tic->to).zone!=0) { nodetoftn(ftmp,&(tic->to)); snprintf(buff,sizeof(buff)-1,"To %s\r\n",ftmp); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->created) { snprintf(buff,sizeof(buff)-1,"Created %s\r\n",tic->created); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->max_via) for(i=0;imax_via;i++) { p=ilist_find_entry(tic->via,i); ass(p!=NULL); str_truncate(256,p); if(fwrite(p,1,strlen(p),fp)!=strlen(p)) return 1; } if(tic->max_path) { list_t *dupes; dupes=list_init(); for(i=0;imax_path;i++) { char smallbuff[256],*p_fuck; p=ilist_find_entry(tic->path,i); ass(p!=NULL); strncpy(smallbuff,p,sizeof(smallbuff)-1); if((p_fuck=strchr(smallbuff,' '))) { *(p_fuck+1)=0; /* FIXME: buffer overflow check */ if(list_find(dupes,smallbuff)) continue; list_add(dupes,smallbuff,""); } snprintf(buff,sizeof(buff)-1,"Path %s\r\n",p); str_truncate(256,p); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) { list_free(dupes); return 1; } } list_free(dupes); } if(tic->seenby) for(i=0;iseenby);i++) { ltmp=list_get(tic->seenby,i); ass(ltmp!=NULL); p=list_key(ltmp); ass(p!=NULL); snprintf(buff,sizeof(buff)-1,"SeenBy %s\r\n",p); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } if(tic->pw) { if(strcmp(tic->pw,"*")) /* see Notes2 */ { snprintf(buff,sizeof(buff)-1,"Pw %s\r\n",tic->pw); str_truncate(256,buff); if(fwrite(buff,1,strlen(buff),fp)!=strlen(buff)) return 1; } } return 0; }