/*
tic files support
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <unistd.h>
#include <dirent.h>
#include <time.h>
#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;i<j;i++)
if(isalpha(v[i]) && islower(v[i]))
break;
if(i==j)
for(i=0;i<j;i++)
v[i]=tolower(v[i]);
/* Security check: remove / * ? [ ] from filename */
strremove(v,"/");
strremove(v,"*");
strremove(v,"?");
strremove(v,"[");
strremove(v,"]");
cur->file=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;i<ticlist_list_max;i++)
{
tmp=ilist_find(ticlist_list,i);
ass(tmp!=NULL);
ass(list_entry(tmp)!=NULL);
/*printf("DEBUG: %d\r",i);*/
/*fflush(stdout);*/
readtic((ticlist_t *)list_entry(tmp));
}
}
#define TICPATTERN "*.tic"
static void _readticlist_readdir(char *dirname,int ticlist_type)
{
DIR *dir; struct dirent *dirp; struct stat stat_buf;
char buff[PATH_MAX]; ticlist_t *cur;
dir=opendir(dirname);
if(dir==NULL && ticlist_type==TICLIST_BADDIR) return;
if(dir==NULL) e_printf("unable to read inbound dir %s",dirname);
ass(dir!=NULL);
while(1)
{
dirp=readdir(dir);
if(!dirp) break;
if(wildmat_icase(dirp->d_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;i<ticlist_list_max;i++)
{
tl_tmp=ilist_find_entry(ticlist_list,i);
ass(tl_tmp!=NULL);
if(tl_tmp->badname) 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;i<max;i++)
{
ctmp=ilist_find_entry(lst,i);
if(ctmp==NULL)
{
e_printf("internal freeing-%s error [ilist_find==NULL or"
"ilist_entry(tmp)==NULL] (tic->file=%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;i<tic->max_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;i<tic->max_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;i<tic->max_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;i<tic->max_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;i<tic->max_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;i<list_head_max(tic->seenby);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;i<tic->max_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;i<tic->max_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;i<tic->max_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;i<tic->max_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;i<tic->max_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;i<list_head_max(tic->seenby);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;
}
syntax highlighted by Code2HTML, v. 0.9.1