/******************************************************************** Copyright (C) 2000 Bassoukos Tassos This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_TIME_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #include #include "network.h" #include "protocol.h" #include "tasks.h" #include "tasklist.h" /* =============================== */ /* generic destroys */ #ifdef DEBUG static void print_string(char *buf,int len){ int i; for(i=0;i126)?'.':buf[i]); } #endif static void destroy_ptr(HLObject *o,gpointer data){ if(o->data.string!=NULL) free(o->data.string); } static HLObject *read_ptr(HLObject *o,unsigned char *buf, int len,gpointer data){ union { int i; char c[4]; } s; s.i=len; o->data.string=malloc(len+4); memcpy(o->data.string+4,buf,len); memcpy(o->data.string,&s.c,4); #ifdef DEBUG { int i; printf(_(" Unknown object type %d size %d\n"),o->type,s.i); for(i=0;i126)?'.':buf[i]); if((i&3)==3) printf(" "); if((i&15)==15) printf("\n"); } } #endif return o; } static int write_ptr(HLObject *o,unsigned char **buf,gpointer data){ union { int i; char c[4]; } s; memcpy(&s.c,o->data.string,4); *buf=malloc(s.i); memcpy(*buf,o->data.string+4,s.i); return s.i; } static void destroy_NONE(HLObject *o,gpointer data){} /* =============================== */ /* strings */ static HLObject *read_string(HLObject *o,unsigned char *buf, int len,gpointer data){ o->data.string=malloc(len+1); memcpy(o->data.string,buf,len); if(data!=NULL){ int i; for(i=0;idata.string[i]^=0xff; } o->data.string[len]=0; #ifdef DEBUG if(len<=64){ printf(" "); print_string(o->data.string,len); } #endif return o; } static int write_string(HLObject *o,unsigned char **buf,gpointer data){ int len=strlen(o->data.string); *buf=(unsigned char *)malloc(len); memcpy(*buf,o->data.string,len); if(data!=NULL){ int i; for(i=0;itype=type; o->data.string=strdup(what); return o; } void string_net_to_unix(HLObject *o){ static unsigned char tbl[256]= {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0d,0x0b,0x0c,0x0a,0x0e,0x0f, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0xc4,0xc5,0xc7,0xc9,0xd1,0xd6,0xdc,0xe1,0xe0,0xe2,0xe4,0xe3,0xe5,0xe7,0xe9,0xe8, 0xea,0xeb,0xed,0xec,0xee,0xef,0xf1,0xf3,0xf2,0xf4,0xf6,0xf5,0xfa,0xf9,0xfb,0xfc, 0x2a,0xb0,0xa2,0xa3,0xa7,0x2a,0xb6,0xdf,0xae,0xa9,0x3f,0xb4,0xa8,0x3f,0xc6,0xd8, 0x3f,0xb1,0x3f,0x3f,0xa5,0xb5,0x3f,0x3f,0x3f,0x3f,0x3f,0xaa,0xba,0x3f,0xe6,0xf8, 0xbf,0xa1,0xac,0x3f,0x3f,0x3f,0x3f,0xab,0xbb,0x3f,0xa0,0xc0,0xc3,0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0xf7,0x3f,0xff,0x3f,0x3f,0xa4,0x3f,0x3f,0x3f,0x3f, 0x3f,0xb7,0x3f,0x3f,0x3f,0xc2,0xca,0xc1,0xcb,0xc8,0xcd,0xce,0xcf,0xcc,0xd3,0xd4, 0x3f,0xd2,0xda,0xdb,0xd9,0x3f,0x3f,0x3f,0xaf,0x3f,0x3f,0x3f,0xb8,0x3f,0x3f,0x3f}; unsigned char *s=o->data.string; while((*s++=tbl[*s])!=0); } void string_unix_to_net(HLObject *o){ static unsigned char tbl[256]= {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0d,0x0b,0x0c,0x0a,0x0e,0x0f, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, 0xca,0xc1,0xa2,0xa3,0xdb,0xb4,0x3f,0xa4,0xac,0xa9,0xaa,0xc7,0xc2,0xad,0xa8,0xf8, 0xa1,0xb1,0xb2,0xb3,0xab,0xb5,0xa6,0xb7,0xb8,0xb9,0xba,0xc8,0x3f,0xbd,0x3f,0xc0, 0xcb,0xe7,0xe5,0xc3,0x80,0x81,0xae,0x82,0xe9,0x83,0xe6,0xe8,0xed,0xcd,0xce,0xcf, 0xd0,0x84,0xd2,0xd3,0xd4,0xd5,0x85,0xd7,0xaf,0xd9,0xda,0xf3,0x86,0xdd,0xde,0xa7, 0x88,0x87,0x89,0x8b,0x8a,0x8c,0xbe,0x8d,0x8f,0x8e,0x90,0x91,0x93,0x92,0x94,0x95, 0xf0,0x96,0x98,0x97,0x99,0x9b,0x9a,0xd6,0xbf,0x9d,0x9c,0x9e,0x9f,0xfd,0xfe,0xd8}; unsigned char *s=o->data.string; while((*s++=tbl[*s])!=0); } /* ========================== */ /* numbers..... */ static HLObject *read_number(HLObject *o,unsigned char *buf, int len,gpointer data){ gint32 a; gint16 b; switch(len){ case 2: memcpy(&b,buf,2); a=GINT16_FROM_BE(b); break; case 4: memcpy(&a,buf,4); a=GINT32_FROM_BE(a); break; default: printf(_("Number with %d bytes received (should be 2 or 4)...\n"),len); return NULL; } o->data.number=a; #ifdef DEBUG printf(" %d",a); #endif return o; } static int write_number(HLObject *o,unsigned char **buf,gpointer data){ int size=4; gint32 a=o->data.number; gint16 b=a&0xffff; *buf=malloc(sizeof(guint32)); if(a==b || data!=NULL){ size=2; b=GINT16_TO_BE(b); memcpy(*buf,&b,2); } else { a=GINT32_TO_BE(a); memcpy(*buf,&a,4); size=4; } return size; } HLObject *create_number(int type,int what){ HLObject *o=(HLObject *)malloc(sizeof(HLObject)); o->type=type; o->data.number=what; return o; } /*=========================*/ static HLObject *read_date(HLObject *o,unsigned char *buf, int len,gpointer data){ if(len!=sizeof(DateTime)){ printf(_("DateTime: expected %d bytes, got %d\n"),sizeof(DateTime),len); return NULL; } o->data.datetime=(DateTime *)malloc(sizeof(DateTime)); memcpy(o->data.datetime,buf,sizeof(DateTime)); o->data.datetime->base_year=GINT16_FROM_BE(o->data.datetime->base_year); o->data.datetime->seconds=GINT32_FROM_BE(o->data.datetime->seconds); return o; } static int write_date(HLObject *o,unsigned char **buf,gpointer data){ DateTime *dt=(DateTime *)malloc(sizeof(DateTime)); dt->pad=0; dt->base_year=GINT16_TO_BE(o->data.datetime->base_year); dt->seconds=GINT32_TO_BE(o->data.datetime->seconds); *buf=(unsigned char *)dt; return sizeof(DateTime); } time_t date_to_unix(DateTime *dt){ struct tm time_tm; if(dt->base_year==1970) return dt->seconds; if(dt->base_year==1904) return dt->seconds-2082844800U; /* FIXME: works only on 32 bit time_t's... */ if(dt->base_year==2000) return dt->seconds+946684800U; memset(&time_tm,0,sizeof(time_tm)); time_tm.tm_sec=dt->seconds; time_tm.tm_year=dt->base_year-1900; return mktime(&time_tm); } void date_to_hotline(DateTime *dt,time_t time){ /* could be something smarter, but hey, it works... */ if(time>946684800U){ dt->base_year=2000; dt->seconds=time-946684800U; } else { dt->base_year=1904; dt->seconds=time+2082844800U; /* FIXME: works only on 32 bit time_t's... */ } } /* ======================= */ static HLObject *read_privs(HLObject *o,unsigned char *buf, int len,gpointer data){ if(len!=sizeof(Privileges)){ printf(_("Privileges: expected %d bytes, got %d\n"),sizeof(Privileges),len); return NULL; } o->data.privileges=(Privileges *)malloc(sizeof(Privileges)); memcpy(o->data.privileges,buf,sizeof(Privileges)); return o; } static int write_privs(HLObject *o,unsigned char **buf,gpointer data){ Privileges *p=(Privileges *)malloc(sizeof(Privileges)); memcpy(p,o->data.privileges,sizeof(Privileges)); *buf=(unsigned char *)p; return sizeof(Privileges); } /* ======================= */ static HLObject *read_resinfo(HLObject *o,unsigned char *buf, int len,gpointer data){ ResumeData dat; if(len!=RESUME_INFO_SIZE){ if(len==RESUME_INFO_SIZE-16){ o->data.resumeinfo=(ResumeInfo *)malloc(sizeof(ResumeInfo)); memcpy(&dat,buf+RESUME_DATA_OFFSET,RESUME_DATA_SIZE-16); o->data.resumeinfo->data_resume_offset=GUINT32_FROM_BE(dat.data_resume_offset); o->data.resumeinfo->resource_resume_offset=0; return o; } printf(_("ResumeInfo: expected %d bytes, got %d\n"),RESUME_INFO_SIZE,len); return NULL; } o->data.resumeinfo=(ResumeInfo *)malloc(sizeof(ResumeInfo)); memcpy(&dat,buf+RESUME_DATA_OFFSET,RESUME_DATA_SIZE); o->data.resumeinfo->data_resume_offset= GUINT32_FROM_BE(dat.data_resume_offset); o->data.resumeinfo->resource_resume_offset= GUINT32_FROM_BE(dat.resource_resume_offset); return o; } static int write_resinfo(HLObject *o,unsigned char **buf,gpointer dummy){ ResumeHdr hdr; ResumeData dat; unsigned char *ri=(unsigned char *)malloc(RESUME_INFO_SIZE); memset(&hdr,0,sizeof(hdr)); memset(&dat,0,sizeof(dat)); memset(ri,0,RESUME_INFO_SIZE); memcpy(hdr.RFLT,"RFLT",4); hdr.one=GUINT16_TO_BE(1); hdr.two=GUINT16_TO_BE(2); memcpy(dat.DATA,"DATA",4); memcpy(dat.MACR,"MACR",4); dat.data_resume_offset= GUINT32_TO_BE(o->data.resumeinfo->data_resume_offset); dat.resource_resume_offset= GUINT32_TO_BE(o->data.resumeinfo->resource_resume_offset); memcpy(ri,&hdr,RESUME_DATA_OFFSET); memcpy(ri+RESUME_DATA_OFFSET,&dat,RESUME_DATA_SIZE); *buf=(unsigned char *)ri; return RESUME_INFO_SIZE; } void resinfo_get_offsets(HLObject *o,int *data,int *res){ if(data!=NULL) *data=o->data.resumeinfo->data_resume_offset; if(res!=NULL) *res=o->data.resumeinfo->resource_resume_offset; } HLObject *resinfo_new(int data,int res){ HLObject *o=(HLObject *)malloc(sizeof(HLObject)); o->type=HLO_RESUMEINFO; o->data.resumeinfo=(ResumeInfo *)malloc(sizeof(ResumeInfo)); o->data.resumeinfo->data_resume_offset=data; o->data.resumeinfo->resource_resume_offset=res; return o; } /* ======================= */ static HLObject *read_ule(HLObject *o,unsigned char *buf, int len,gpointer data){ WireUserlistEntry *w; o->data.userlistentry=(UserlistEntry *)malloc(sizeof(UserlistEntry)); w=&o->data.userlistentry->u; memcpy(w,buf,sizeof(WireUserlistEntry)); buf+=sizeof(WireUserlistEntry); w->socket=GINT16_FROM_BE(w->socket); w->icon=GINT16_FROM_BE(w->icon); w->status=GINT16_FROM_BE(w->status); w->nickname_length=GINT16_FROM_BE(w->nickname_length); o->data.userlistentry->name=malloc(w->nickname_length+1); memcpy(o->data.userlistentry->name,buf,w->nickname_length); o->data.userlistentry->name[w->nickname_length]=0; #ifdef DEBUG if((w->status&15)!=w->status) printf("ule->status>15... %s : %d",o->data.userlistentry->name,w->status); printf(" %s %x %x %d ", o->data.userlistentry->name,w->socket,w->status,w->icon); #endif return o; } static int write_ule(HLObject *o,unsigned char **buf,gpointer data){ WireUserlistEntry *w; int size; o->data.userlistentry->u.nickname_length=strlen(o->data.userlistentry->name); size=sizeof(WireUserlistEntry)+o->data.userlistentry->u.nickname_length; w=(WireUserlistEntry *)malloc(size); memcpy(&w[1],o->data.userlistentry->name, o->data.userlistentry->u.nickname_length); w->socket=GINT16_TO_BE(o->data.userlistentry->u.socket); w->icon=GINT16_TO_BE(o->data.userlistentry->u.icon); w->status=GINT16_TO_BE(o->data.userlistentry->u.status); w->nickname_length=GUINT16_TO_BE(o->data.userlistentry->u.nickname_length); *buf=(unsigned char *)w; return size; } static void destroy_ule(HLObject *o,gpointer data){ if(o->data.userlistentry!=NULL){ if(o->data.userlistentry->name!=NULL) free(o->data.userlistentry->name); free(o->data.userlistentry); } } HLObject *userlistentry_new(int socket,int icon,int status,char *nickname){ HLObject *o=malloc(sizeof(HLObject)); UserlistEntry *w; o->type=HLO_USERLISTENTRY; o->data.userlistentry=w=(UserlistEntry *)malloc(sizeof(UserlistEntry)); o->data.userlistentry->name=strdup(nickname); w->u.nickname_length=strlen(nickname); w->u.socket=socket; w->u.icon=icon; w->u.status=status; return o; } /* ======================= */ static HLObject *read_fileentry(HLObject *o,unsigned char *buf, int len,gpointer data){ FilelistEntry *f; o->data.filelistentry=f=(FilelistEntry *)malloc(sizeof(FilelistEntry)); memcpy(&f->f,buf,sizeof(WireFilelistEntry)); f->f.size=GUINT32_FROM_BE(f->f.size); f->f.filename_size=GUINT32_FROM_BE(f->f.filename_size); f->name=(char *)malloc(f->f.filename_size+1); memcpy(f->name,buf+sizeof(WireFilelistEntry),f->f.filename_size); f->name[f->f.filename_size]=0; return o; } static int write_fileentry(HLObject *o,unsigned char **buf,gpointer data){ int size; WireFilelistEntry *w; size=o->data.filelistentry->f.filename_size= strlen(o->data.filelistentry->name); size+=sizeof(WireFilelistEntry); w=(WireFilelistEntry *)malloc(size); memcpy(w->type,o->data.filelistentry->f.type,4); memcpy(w->creator,o->data.filelistentry->f.creator,4); w->size=GUINT32_TO_BE(o->data.filelistentry->f.size); w->pad=0; w->filename_size=GUINT32_TO_BE(o->data.filelistentry->f.filename_size); memcpy(&w[1],o->data.filelistentry->name, o->data.filelistentry->f.filename_size); *buf=(char *)w; return size; } static void destroy_fileentry(HLObject *o,gpointer data){ free(o->data.filelistentry->name); free(o->data.filelistentry); } /* ======================= */ static HLObject *read_path(HLObject *o,unsigned char *buf, int len,gpointer data){ int i,j=2; Path *p; char **vec; guint16 size; o->data.path=p=(Path *)malloc(sizeof(Path)); memcpy(&p->dir_levels,buf,sizeof(guint16)); p->dir_levels=GUINT16_FROM_BE(p->dir_levels); p->directories=vec=(char **)malloc(sizeof(char *)*p->dir_levels); for(i=0;idir_levels;i++){ j++; /* skip pad */ memcpy(&size,buf+j,sizeof(guint16)); j+=sizeof(guint16); size=GUINT16_FROM_BE(size); vec[i]=malloc(size+1); memcpy(vec[i],buf+j,size); j+=size; vec[i][size]=0; } #ifdef DEBUG printf(" "); for(i=0;idir_levels;i++) printf("/%s",p->directories[i]); #endif return o; } static int write_path(HLObject *o,unsigned char **buf,gpointer data){ int size,i,l; guint16 t; unsigned char *b; size=sizeof(guint16)+ (sizeof(guint8)+sizeof(guint16))*o->data.path->dir_levels; for(i=0;idata.path->dir_levels;i++) size+=strlen(o->data.path->directories[i]); *buf=b=malloc(size); t=GUINT16_TO_BE(o->data.path->dir_levels); memcpy(b,&t,sizeof(guint16)); b+=sizeof(guint16); for(i=0;idata.path->dir_levels;i++){ *b++=0; l=strlen(o->data.path->directories[i]); t=GUINT16_TO_BE(l); memcpy(b,&t,sizeof(guint16)); b+=sizeof(guint16); memcpy(b,o->data.path->directories[i],l); b+=l; } return size; } void path_destroy(Path *p){ int i; for(i=0;idir_levels;i++) free(p->directories[i]); free(p->directories); free(p); } static void destroy_path(HLObject *o,gpointer data){ path_destroy(o->data.path); } HLObject *path_parent(HLObject *o){ Path *p; HLObject *w; int i; if(o->data.path->dir_levels<=1) return NULL; w=(HLObject *)malloc(sizeof(HLObject)); w->data.path=p=(Path *)malloc(sizeof(Path)); w->type=HLO_PATH; p->dir_levels=o->data.path->dir_levels-1; p->directories=(char **)malloc(sizeof(char *)*p->dir_levels); for(i=0;idir_levels;i++) p->directories[i]=strdup(o->data.path->directories[i]); return w; } HLObject *path_add(HLObject *o,char *path_append){ Path *p; HLObject *w; int i; w=(HLObject *)malloc(sizeof(HLObject)); w->data.path=p=(Path *)malloc(sizeof(Path)); w->type=HLO_PATH; p->dir_levels=o->data.path->dir_levels+1; p->directories=(char **)malloc(sizeof(char *)*p->dir_levels); for(i=0;idir_levels-1;i++) p->directories[i]=strdup(o->data.path->directories[i]); p->directories[p->dir_levels-1]=strdup(path_append); return w; } HLObject *path_new(char **paths,int num_paths){ Path *p; HLObject *w; int i; w=(HLObject *)malloc(sizeof(HLObject)); w->data.path=p=(Path *)malloc(sizeof(Path)); w->type=HLO_PATH; p->dir_levels=num_paths; p->directories=(char **)malloc(sizeof(char *)*(p->dir_levels+1)); for(i=0;idir_levels;i++) p->directories[i]=strdup(paths[i]); p->directories[p->dir_levels]=NULL; return w; } HLObject *path_dup(HLObject *o){ HLObject *w; w=path_new(o->data.path->directories,o->data.path->dir_levels); w->type=o->type; return w; } /* ======================= */ static void destroy_nfi(HLObject *o,gpointer data){ free(o->data.newsfolderitem->name); free(o->data.newsfolderitem); } static HLObject *read_nfi(HLObject *o,unsigned char *buf, int len,gpointer data){ NewsFolderItem *nfi=o->data.newsfolderitem=malloc(sizeof(NewsFolderItem)); nfi->type=buf[0]; nfi->name=malloc(len); memcpy(nfi->name,buf+1,len-1); nfi->name[len-1]=0; return o; } static int write_nfi(HLObject *o,unsigned char **buf,gpointer data){ int size=1+strlen(o->data.newsfolderitem->name); *buf=malloc(size); (*buf)[0]=o->data.newsfolderitem->type; memcpy(*buf+1,o->data.newsfolderitem->name, size-1); return size; } /* ======================= */ static void destroy_ci(HLObject *o,gpointer data){ free(o->data.catalogitem->name); free(o->data.catalogitem); } static HLObject *read_ci(HLObject *o,unsigned char *buf, int len,gpointer data){ int slen; char *ptr; CatalogItem *ci=o->data.catalogitem=malloc(sizeof(CatalogItem)); memcpy(&ci->w,buf,sizeof(WireCatItem)); ci->w.type=GINT16_FROM_BE(ci->w.type); ci->w.post_count=GINT16_FROM_BE(ci->w.post_count); if(ci->w.type==3){ slen=buf[28]; ptr=buf+29; } else { slen=buf[4]; ptr=buf+5; } ci->name=malloc(slen+2); memcpy(ci->name,ptr,slen); ci->name[slen]=0; return o; } static int write_ci(HLObject *o,unsigned char **buf,gpointer data){ WireCatItem w=o->data.catalogitem->w; int size=5+strlen(o->data.catalogitem->name); w.type=GINT16_TO_BE(w.type); w.post_count=GINT16_TO_BE(w.post_count); if(o->data.catalogitem->w.type==3) size+=29; *buf=malloc(size); memset(*buf,0,size); memcpy(*buf,&w,sizeof(w)); if(o->data.catalogitem->w.type==3){ (*buf)[28]=strlen(o->data.catalogitem->name); strcpy((*buf)+29,o->data.catalogitem->name); } else { strcpy((*buf)+5,o->data.catalogitem->name); } return size; } /* ======================= */ static void destroy_newsgroup(HLObject *o,gpointer dummy){ int i,j; NewsGroup *ng=o->data.newsgroup; if(ng==NULL) return; for(i=0;ipost_count;i++){ for(j=0;jposts[i].partcount;j++) free(ng->posts[i].parts[j].mime_type); free(ng->posts[i].sender); free(ng->posts[i].subject); free(ng->posts[i].parts); } if(ng->posts!=NULL) free(ng->posts); free(ng); } static HLObject *read_newsgroup(HLObject *o,unsigned char *buf, int len,gpointer data){ NewsGroup *ng=(NewsGroup *)malloc(sizeof(NewsGroup)); unsigned char *ptr=buf+4; NewsItem *ni; guint32 u32; guint16 u16; int p,j; #define get_short(ret) memcpy(&u16,ptr,2);ptr+=2;ret=GUINT16_FROM_BE(u16) #define get_long(ret) memcpy(&u32,ptr,4);ptr+=4;ret=GUINT32_FROM_BE(u32) #define get_pstring(ret) if(*ptr==0){ret=NULL;}else{ret=malloc(1+*ptr);memcpy(ret,ptr+1,*ptr);(ret)[*ptr]=0;ptr+=*ptr;} ptr++ o->data.newsgroup=ng; get_long(ng->post_count); ptr+=*ptr; ptr+=2; if(ng->post_count==0){ ng->posts=NULL; return o; } ng->posts=(NewsItem *)malloc(sizeof(NewsItem)*ng->post_count); for(p=0,ni=ng->posts;ppost_count;p++,ni++){ get_long(ni->postid); get_short(ni->date.base_year); get_short(ni->date.pad); get_long(ni->date.seconds); get_long(ni->parentid); ptr+=4; get_short(ni->partcount); get_pstring(ni->subject); get_pstring(ni->sender); ni->parts=malloc(sizeof(ni->parts[0])*ni->partcount); ni->size=0; for(j=0;jpartcount;j++){ get_pstring(ni->parts[j].mime_type); get_short(ni->parts[j].size); ni->size+=ni->parts[j].size; } } return o; } /* ======================= */ static ObjectDef wire_objects[]={ {0, read_ptr,write_ptr,destroy_ptr,NULL}, {HLO_ERRORMSG, read_string,write_string,destroy_ptr,NULL}, {HLO_MESSAGE, read_string,write_string,destroy_ptr,NULL}, {HLO_NICK, read_string,write_string,destroy_ptr,NULL}, {HLO_SOCKET, read_number,write_number,destroy_NONE,NULL}, {HLO_ICON, read_number,write_number,destroy_NONE,NULL}, {HLO_LOGIN, read_string,write_string,destroy_ptr,GINT_TO_POINTER(1)}, {HLO_PASSWD, read_string,write_string,destroy_ptr,GINT_TO_POINTER(1)}, {HLO_XFERID, read_number,write_number,destroy_NONE,NULL}, {HLO_XFERSIZE, read_number,write_number,destroy_NONE,NULL}, {HLO_PARAMETER, read_number,write_number,destroy_NONE,NULL}, {HLO_PRIVS, read_privs,write_privs,destroy_ptr,NULL}, {HLO_STATUS, read_number,write_number,destroy_NONE,NULL}, {HLO_BAN, read_number,write_number,destroy_NONE,GINT_TO_POINTER(2)}, {HLO_CHATWINDOW,read_number,write_number,destroy_NONE,NULL}, {HLO_SUBJECT, read_string,write_string,destroy_ptr,NULL}, {HLO_QUEUED, read_number,write_number,destroy_NONE,NULL}, {HLO_BANNERTYPE,read_string,write_string,destroy_ptr,NULL}, {HLO_BANNERURL, read_string,write_string,destroy_ptr,NULL}, {HLO_OMITAGREEMENT, read_number, write_number, destroy_NONE, NULL}, {HLO_VERSION, read_number,write_number,destroy_NONE,NULL}, {HLO_SERVERQUEUE,read_number,write_number,destroy_NONE,NULL}, {HLO_SERVERNAME,read_string,write_string,destroy_ptr,NULL}, {HLO_FILEENTRY, read_fileentry,write_fileentry,destroy_fileentry,NULL}, {HLO_FILENAME, read_string,write_string,destroy_ptr,NULL}, {HLO_PATH, read_path,write_path,destroy_path,NULL}, {HLO_RESUMEINFO,read_resinfo,write_resinfo,destroy_ptr,NULL}, {HLO_RESUMEFLAG,read_number,write_number,destroy_NONE,GINT_TO_POINTER(2)}, {HLO_INFOLONGTYPE,read_string,write_string,destroy_ptr,NULL}, {HLO_INFOCREATOR,read_string,write_string,destroy_ptr,NULL}, {HLO_INFOSIZE, read_number,write_number,destroy_NONE,NULL}, {HLO_INFOCREATED,read_date,write_date,destroy_ptr,NULL}, {HLO_INFOMODIFIED,read_date,write_date,destroy_ptr,NULL}, {HLO_COMMENT, read_string,write_string,destroy_ptr,NULL}, {HLO_NEWFILENAME,read_string,write_string,destroy_ptr,NULL}, {HLO_TARGETPATH,read_path,write_path,destroy_path,NULL}, {HLO_INFOTYPE, read_string,write_string,destroy_ptr,NULL}, {HLO_QUOTE, read_string,write_string,destroy_ptr,NULL}, {HLO_USERLISTENTRY,read_ule,write_ule,destroy_ule,NULL}, {HLO_NEWSFOLDERITEM,read_nfi,write_nfi,destroy_nfi,NULL}, // TODO: add write support for newsgroups {HLO_CATLIST, read_newsgroup,NULL,destroy_newsgroup,NULL}, {HLO_CATEGORY, read_string,write_string,destroy_ptr,NULL}, {HLO_CATEGORYITEM, read_ci,write_ci,destroy_ci,NULL}, {HLO_NEWSPATH, read_path,write_path,destroy_path,NULL}, {HLO_THREADID, read_number,write_number,destroy_NONE,NULL}, {HLO_NEWSTYPE, read_string,write_string,destroy_ptr,NULL}, {HLO_NEWSSUBJECT,read_string,write_string,destroy_ptr,NULL}, {HLO_NEWSAUTHOR,read_string,write_string,destroy_ptr,NULL}, {HLO_NEWSDATE, read_date,write_date,destroy_ptr,NULL}, {HLO_PREVTHREAD,read_number,write_number,destroy_NONE,NULL}, {HLO_NEXTTHREAD,read_number,write_number,destroy_NONE,NULL}, {HLO_NEWSDATA, read_string,write_string,destroy_ptr,NULL}, {HLO_PARENT_POST,read_number,write_number,destroy_NONE,NULL}, {HLO_CHILD_POST,read_number,write_number,destroy_NONE,NULL}, {-1,NULL,NULL,NULL,NULL} }; ObjectDef *find_object_type(int type){ ObjectDef *o; for(o=wire_objects;o->type!=-1;o++) if(o->type==type) return o; if(type!=0) return find_object_type(0); return NULL; } HLObject *read_object(int type,int size,unsigned char *buf){ HLObject *o,*o2; ObjectDef *od=find_object_type(type); if(od==NULL){ #ifdef DEBUG int i; printf(_("Unknown object type %d size %d\n"),type,size); for(i=0;i0) printf(" "); if((i&15)==0 && i>0) printf("\n"); } printf("\n"); for(i=0;i0) printf(" "); if((i&15)==0 && i>0) printf("\n"); } printf("\n"); #endif return NULL; } o=malloc(sizeof(HLObject)); o->type=type; if(!(o2=od->read(o,buf,size,od->data))) { free(o); return NULL; } /* FIXME check return values [more seriously] ...*/ return o; } void object_set_type(HLObject *o,int type){ o->type=type; } void object_destroy(HLObject *o){ ObjectDef *od; if(o==NULL) return; od=find_object_type(o->type); if(od==NULL){ printf(_("Trying to free unknown object type %d.\n"),o->type); return; } od->destroy(o,od->data); free(o); } void objects_destroy(HLObject **ob){ HLObject **o=ob; if(ob==NULL) return; for(;*ob!=NULL;ob++) object_destroy(*ob); free(o); }