#include #include "fido.h" #include "fidomem.h" #include #include "proto.h" /* Unpack a message packet, put the messages into the mail area. Return true if it unpacked OK. */ int unpacket(fn) char *fn; /* packet filename */ { int file,i,n; char *cp,buff[SS]; struct _pkthdr pkthdr; /* header from incoming packet */ struct _node d; /* "clean" source node, from pkt header */ file= open(fn,0); if (file == -1) { /* packet disappeared? */ clprintf(SM+45,fn); return(0); } n= read(file,&pkthdr,sizeof(struct _pkthdr)); if (n != sizeof(struct _pkthdr)) { /* complain about bad packets */ if (n) clprintf(SM+106,fn,n); close(file); delete(fn); /* kill it */ return(1); } d.zone= pkthdr.orig_zone; if (! d.zone) d.zone= id.zone; d.net= pkthdr.orig_net; d.number= pkthdr.orig_number; d.point= 0; clprintf(SM+107,str_node(&d)); /* got a packet */ n= 0; while ((i= unpmsg(file)) > 0) ++n; /* unpack each msg, */ close(file); /* close the file */ clprintf(SM+108,n); /* number of messages */ /* If a bad packet, rename the .IN file to .BAD. Don't overwrite any existing .BAD files -- locate the highest .BAD filename already there first. */ if (i != 0) { /* if a bad packet */ strip_path(buff,fn); /* rename \xxx.IN */ sprintf(&buff[strlen(buff)],0,"%d.BAD", /* to \yyy.BAD */ next_bad()); rename(fn,buff); /* rename(old,new) */ clprintf(SM+109,fn,buff); return(0); /* something went wrong */ } delete(fn); /* done, kill it */ /* If any files were attached, add them to FILES.BBS. */ strcpy(buff,fn); /* create the file list name */ for (cp= buff; *cp; ++cp) /* find the dot "." */ if (*cp == '.') break; strcpy(cp,".FLI"); /* make that .FLI */ unfile(buff,&d); /* process any .FLI files */ return(1); } /* Return the next .BAD file number. */ static next_bad() { int i,n; struct _xfbuf xfbuf; char buff[SS]; n= i= xfbuf.s_attrib= 0; makefname(buff,"*.BAD"); while (_find(buff,i++,&xfbuf)) { if (atoi(xfbuf.name) > n) n= atoi(xfbuf.name); } return(n + 1); } /* Process a .FLI file and add the names to FILES.BBS. Return 0 if error. */ unfile(fn,d) char *fn; /* .FLI file name */ struct _node *d; /* who it's from */ { int file,f,n; char c,buff[SS],ln[SS]; file= open(fn,0); if (file == -1) return(1); makefname(buff,"FILES.BBS"); f= append(buff); /* open/create FILES.BBS */ if (f == -1) { clprintf(SM+10,buff); /* "cant create..." */ close(file); /* oops */ return(0); } while (1) { /* process all filenames */ n= 0; /* filename length */ while (read(file,&c,1)) { /* get a filename */ if (delim(c)) { /* if a blank etc */ if (n) break; /* stop if end of filename */ continue; /* else leading garbage */ } ln[n++]= c; /* filename character */ } ln[n]= NUL; /* terminate the line */ if (! n) break; /* file empty */ cpyarg(ln,strip_path(buff,ln)); /* skip past the pathname */ ln[14]= NUL; /* clip long names */ stoupper(ln); /* make upper case */ if (! is_us(d)) sprintf(&ln[strlen(ln)],SM+111,str_node(d)); strcat(ln,"\r\n"); write(f,ln,strlen(ln)); /* write it, */ clputs(" "); clputs(ln); /* log it */ } close(f); close(file); delete(fn); /* done, kill it */ return(1); } /* Unpack a message from the message file; the message type (0 is end-of-packet) or -1 if error or the message type. */ unpmsg(file) int file; { int msgtype; char *p; char c,name[SS],buff[SS]; int f,n,i; msgtype= 0; /* in case read error, */ read(file,&msgtype,sizeof(msgtype)); switch (msgtype) { case 0: return(0); /* type == end of packet */ break; case 1: /* incompatible version */ clprintf(SM+112); return(-1); break; case 2: /* v10 - v11 */ break; default: /* unknown msg type */ clprintf(SM+113,msgtype); return(-1); break; } p= (char *) &msg; /* clear the sucker out */ for (n= 0; n < sizeof(struct _msg); ++n) *p++= NUL; msg.orig_node= cgeti(file); /* v10 ... */ msg.dest_node= cgeti(file); msg.orig_net= cgeti(file); msg.dest_net= cgeti(file); /* ... v10 */ msg.attr= cgeti(file); /* get attributes */ msg.cost= cgeti(file); /* get msg cost as entered */ msg.attr &= MSGMASK; /* strip some bits */ if (cgets(file,msg.date,sizeof(msg.date)) == 0) return(-1); if (cgets(file,msg.to,sizeof(msg.to)) == 0) return(-1); if (cgets(file,msg.from,sizeof(msg.from)) == 0) return(-1); if (cgets(file,msg.subj,sizeof(msg.subj)) == 0) return(-1); if (shared()) { /* if shared or multitasking */ msgcount(); /* recount messages */ } sprintf(buff,0,"%d.MSG",*msg_highest() + 1); makemname(name,buff); f= creat(name,2); /* create the message file, */ if (f == -1) { clprintf(SM+10,name); /* "can't create" */ frc_abort(); } ++*msg_highest(); /* account for it */ ++*msg_total(); if (write(f,&msg,sizeof(struct _msg)) != sizeof(struct _msg)) { clprintf(SM+115,name); /* "disk full!" */ frc_abort(); } n= 0; while (c= cgetc(file)) { /* copy the msg text */ if (write(f,&c,1) != 1) { /* byte by byte */ clprintf(SM+115,name); /* "disk full!" */ frc_abort(); } } write(f,"",1); /* terminating null */ close(f); return(msgtype); } /* Read a string from the packet file, including the null. Return 0 if we hit EOF. Make sure we dont write too many characters into the string; toss the extra chars from the string if necessary. */ cgets(f,s,len) int f; char *s; int len; { int n; char c; do { n= read(f,&c,1); /* read one, */ if (len > 1) { /* if string not full */ *s++= c; /* store it */ *s= NUL; /* (terminate the string) */ --len; } } while (n && c); return(n); } /* Read an integer from the packet file. */ cgeti(f) int f; { int i; read(f,&i,sizeof(i)); return(i); } /* Read a character from the packet file. Return null if EOF or null read. */ cgetc(file) int file; { char c; if (read(file,&c,1) == 0) return(NUL); else return(c); }