home *** CD-ROM | disk | FTP | other *** search
- /* XSCAN -- compile in Compact model */
-
- #include "msgg.h"
-
- char * pascal stristr (char *t, char *s);
- int pascal export (char *,word,char *);
- int pascal import (char *,word,char *);
- char * pascal rstrip (char *);
- char * pascal lstrip (char *);
- char * pascal stripcr (char *);
- void pascal getone (char *,FILE *,word);
- void pascal strip (char *,int);
- void pascal read_control (char *);
- int cdecl break_handler (void);
- void cdecl close_em (void);
- void pascal make_attach (char *filetosend);
- char * pascal unpack_msg (char **hold);
- char * pascal pack_msg (char *hold,struct _xmsg *msg);
-
- char area_tag[48];
- int no_strip=0;
- int nofillin=0;
- int net=0;
- int rescanning=0;
- int process_assoc=0;
- long pos=0;
- FILE *pf;
- char *nodes;
- char outbound[133];
- word compress_size=0;
- word textsize;
- word codesize;
-
- /* Notes on msg handling with XBBS:
- First, when I import a message, I set the MSGORPHAN bit if:
- 1. The message had stripping done to it (eliminating SEEN-BYs, etc.)
- 2. The message was too long (>64K) to import in its entirity.
- Setting the MSGORPHAN bit guarantees a message will never be reexported.
-
- Second, on import I reset MSGLOCAL. This ensures that imported messages
- will never be reexported unless a rescan is requested.
-
- Third, on export I set the MSGLOCAL bit. oMMM won't touch a message with
- its MSGLOCAL bit unset, so it might affect other programs farther down
- line. Better safe than sorry.
-
- Fourth, after export I set the MSGSCANNED bit in msg.m_attr. This is
- XBBS' version of a high-water mark, and tells XST which messages have
- already been sent. XSCAN would override the scanned bit only if a
- rescan has been requested, and the message is a candidate for exporting
- (i.e. doesn't have MSGORPHAN set).
-
- The MSGSENT bit isn't really used other than as information to the sysop.
-
- Note that the msg.length value is a byte larger than you might think.
- XBBS uses the extra byte to assure null termination even if the message
- was grunged (local XBBS use only).
- */
-
-
-
- void cdecl main (argc,argv)
-
- int argc;
- char *argv[];
-
- {
-
- word register x;
- char do_import=0;
- char do_export=0;
- static char configfile[132]="XAREAS.BBS";
- static char s[512];
- static char messdir[120]="";
- word areasprocessed=0;
- word lineno=0;
- word boardno;
- static char directory[120];
-
- ctrlbrk(break_handler);
- atexit(close_em);
-
- printf("\n\n\x1b[0;1;37mXSCAN copyright (c) 1989/90 by M. Kimes--All Rights Reserved\x1b[0;2;37m\n");
- printf("Compiled: %s %s\n",__DATE__,__TIME__);
-
- for (x=1;x<(word)argc;x++) { /* Parse command line */
- strupr(argv[x]);
- if (!strncmp(argv[x],"-I",2)) do_import=1;
- else if (!strncmp(argv[x],"-E",2)) do_export=1;
- else if (!strncmp(argv[x],"-F",2)) strcpy(configfile,&argv[x][2]);
- else if (!strncmp(argv[x],"-Z",2)) no_strip=1;
- else if (!strncmp(argv[x],"-N",2)) nofillin=1;
- else if (!strncmp(argv[x],"-R",2)) {
- do_export=1;
- rescanning=1;
- }
- else if (!strncmp(argv[x],"-C",2)) {
- compress_size=(word)atol(&argv[x][2]);
- if(compress_size<1024)compress_size=1024;
- }
- else if (!strncmp(argv[x],"-A",2)) process_assoc=1;
- else printf("\nUnknown parameter `%s'\n",argv[x]);
- }
-
- if (!do_import && !do_export) {
- printf("\nXSCAN is the link between XBBS X*.### msg area files and *.MSG msg files\n");
- printf(" Please note that XST is recommended over XSCAN where it will work!\n");
- printf("\nIt'd be a good idea to specify -Import and/or -Export\n");
- printf("You can also specify a config file with -F<filename>\n");
- printf("and/or tell me not to strip SEEN-BYs and other extraneous info with -Z\n");
- printf("I will fill in incomplete message headers from kludge lines unless you say -N\n");
- printf("Rescans can be had by passing -Rescan, but use *carefully*!\n");
- printf("Msgs that had SEEN-BYs stripped when imported cannot be rescanned.\n");
- printf("-C<#bytes> tells me how big a msg must be before compressing (none default)\n");
- printf("Associated msgs can be processed if you pass the -Assoc argument.\n");
- printf("Associated filepath look up uses ASSOC.BBS in the default directory.\n");
- printf("ASSOC.BBS should be in the form Area_Tag File_Path<cr><lf>\n");
- printf("\x1b[0;1;37m(NOTE: at this time, -Assoc is not supported)\x1b[0;2;37m\n");
- goto Something_Bad;
- }
- if(rescanning) printf("\nRescan activated...hope you know what you're doing...");
- if (!do_import && do_export) printf("\nExporting messages...");
- if (do_import && !do_export) printf("\nImporting messages...");
- if (do_import && do_export) printf("\nImporting and exporting messages...");
- printf("\nConfig file is: %s\n",configfile);
-
- if(!(pf=fopen(configfile,"r"))) {
- printf("\nCan't open ctl file\n");
- exit(4);
- }
- getone(s,pf,lineno);
- if (!*s) {
- printf("\nBig bad goof in config file\n");
- Something_Bad:
- printf("\nConfig file format: (Default: XAREAS.BBS)\n\nFirst line: Drive:\\XBBS_message_directory_path\\");
- printf("\nSecond line: Drive:\\Outbound_directory_path\\ (used with -Assoc)");
- printf("\nSubsequent lines:\n Area# Drive:\\MSG_Directory\\ Area_tag <and then nodes if using -Assoc>\n");
- printf("\nUse reserved area name *NETMAIL* (including *'s) for netmail areas.\n");
- exit(4);
- }
- lstrip(s);
- stripcr(s);
- rstrip(s);
- if (s[strlen(s)-1]!='\\') strcat(s,"\\");
- strcpy(messdir,s);
- getone(s,pf,lineno);
- if(!*s) goto Something_Bad;
- lstrip(s);
- stripcr(s);
- rstrip(s);
- if (s[strlen(s)-1]!='\\') strcat(s,"\\");
- strcpy(outbound,s);
- do {
- pos=ftell(pf); /* In case rewind sometime required */
- getone(s,pf,lineno);
- if (!*s) break;
- lstrip(s);
- stripcr(s);
- rstrip(s);
- strupr(s);
- boardno=(word)atol(strtok(s,"; "));
- if (!boardno) {
- printf("\nError in ctl file line#%u",lineno);
- continue;
- }
- strcpy(directory,strtok(0," "));
- if (directory[strlen(directory)-1]!='\\') strcat(directory,"\\");
- strcpy(area_tag,strtok(0," "));
- nodes=strtok(0,"\n"); /* Point to trailing list of nodes, if any */
- printf("\nProcessing area %s",area_tag);
- if(!strcmp(area_tag,"*NETMAIL*")) net=1;
- else net=0;
- if (do_import) {
- printf("\nImporting...");
- import(messdir,boardno,directory);
- }
- if (do_export) {
- printf("\nExporting...");
- export(messdir,boardno,directory);
- }
- areasprocessed++;
- } while (*s);
-
- printf("\nProcessed mail in %u areas.\n",areasprocessed);
-
- }
-
-
-
-
- int cdecl break_handler (void)
-
- {
-
- return 1;
-
- }
-
-
-
- void cdecl close_em (void) {
-
- fcloseall();
-
- }
-
-
- int pascal export (dir,base,filedir)
-
- char *dir;
- word base;
- char *filedir;
-
- {
-
- static char filename[132]; /* static vars are just to speed things up (?) */
- static char textname[132];
- static char file[132];
- static struct _xmsg msg;
- FILE *fp;
- FILE *pf;
- FILE *pp=NULL;
- char once;
- char *hold;
- struct ffblk filestat;
- register word messno;
- word nomess;
- char msgto[133];
- register word number=1;
-
- sprintf(filename,"%sXDATA.%03x",dir,base);
- sprintf(textname,"%sXTEXT.%03x",dir,base);
-
- if (findfirst(filename,&filestat,0)!=0) {
- printf("\nCannot find %s",filename);
- return 0;
- }
- nomess=(word)(filestat.ff_fsize/(long)sizeof(struct _xmsg));
- if (!nomess) return 0;
-
- if(!(pf=fopen(textname,"rb"))) {
- printf("\nCannot open %s",textname);
- return (0);
- }
-
- if(!(fp=fopen(filename,"r+b"))) {
- if (!(fp=fopen(filename,"a+b"))) {
- fclose(pf);
- printf("\nCannot open %s",filename);
- return(0);
- }
- }
-
- for (messno=1;messno<nomess+1;messno++) {
- if ((fseek(fp,(long)(messno-1)*(long)sizeof(struct _xmsg),SEEK_SET)!=0) || (fread(&msg,sizeof(struct _xmsg),1,fp)!=1)) {
- if (ferror(fp)) perror ("\nXDATA SEEK ERROR");
- fclose(fp);
- fclose(pf);
- if (pp) fclose(pp);
- return(0);
- }
- if(msg.attr & MSGORPHAN) continue;
- if(((msg.m_attr & MSGSCANNED) || !(msg.attr & MSGLOCAL)) && !rescanning) continue;
- if(!net){
- if ((msg.m_attr & MSGDELETED) || (!(msg.m_attr & MSGECHO))) continue;
- }
- else if ((msg.m_attr & MSGDELETED) || (!(msg.m_attr & MSGNET))) continue;
-
- do {
- if (number>=65534) {
- printf("\nOut of message numbers...\n");
- return 0;
- }
- if(!net)number++;
- sprintf(file,"%s%u.MSG",filedir,number);
- } while (!findfirst(file,&filestat,0));
-
- printf("%5d.MSG\x1b[9D",number);
-
- if ((fseek(fp,(long)(messno-1)*(long)sizeof(struct _xmsg),SEEK_SET)!=0)) {
- if (ferror(fp)) perror ("\nXDATA SEEK ERROR");
- fclose(fp);
- fclose(pf);
- if (pp) fclose(pp);
- return(0);
- }
- /* if(!net)msg.m_attr = msg.m_attr & (~MSGECHO); */ /* Unmark echo bit */
- /* else msg.m_attr = msg.m_attr & (~MSGNET); */
-
- if(net) {
- if(msg.attr & MSGKILL) msg.m_attr = (msg.m_attr | MSGDELETED);
- }
-
- msg.m_attr = (msg.m_attr | MSGSCANNED); /* Set scanned bit */
- msg.attr = (msg.attr | MSGSENT);
-
- fwrite(&msg,sizeof(struct _xmsg),1,fp); /* Update header */
-
- msg.attr = (msg.attr & (~MSGSENT));
-
- if(!(pp=fopen(file,"wb"))) {
- fclose (fp);
- fclose (pf);
- printf("\nCannot open %s",file);
- return 0;
- }
-
- once=0;
- TryThatOver:
- if (fseek(pf,msg.start,SEEK_SET)!=0) {
- if (ferror(pf)) {
- if (!once) {
- once++;
- goto TryThatOver;
- }
- else {
- perror ("\nXTEXT SEEK ERROR");
- fclose(fp);
- fclose(pf);
- fclose(pp);
- exit(3);
- }
- }
- }
- hold=(char *)malloc(msg.length+1);
- if (hold==NULL) {
- printf("\nOut of memory.\n");
- fclose(pf);
- fclose(fp);
- fclose(pp);
- exit(4);
- }
- fread(hold,msg.length,1,pf);
- hold[msg.length-1]=0;
-
- if(msg.m_attr & MSGPACKED) {
- unpack_msg(&hold);
- if(hold==NULL) continue; /* Compression error, screw it */
- msg.length=strlen(hold)+1;
- }
-
- if(process_assoc && nodes) {
- /* Associated msg file attaching... */
-
- char assocfile[13]="";
- char filepath[133]="";
- char *p;
- struct ffblk f;
- FILE *fp;
-
- if((p=(strstr(hold,"\01ASSOC: ")))) {
- p+=8;
- strncpy(assocfile,p,13);
- assocfile[12]=0;
- if(!(p=(strstr(hold,"\r\01REPLY: ")))) {
- fp=fopen("ASSOC.BBS","rt");
- if(fp) {
- while (!feof(fp) && stricmp(strtok(filepath," "),area_tag)) {
- if(!fgets(filepath,133,fp)) break;
- filepath[132]=0;
- stripcr(filepath);
- }
- fclose(fp);
- if(!stricmp(filepath,area_tag)) {
- p=strtok(filepath,"\n");
- if(p) {
- strncpy(filepath,p,133);
- filepath[119]=0;
- }
- else *filepath=0;
- }
- else *filepath=0;
- }
- }
- }
- if(*assocfile && *filepath) {
- strcat(filepath,assocfile);
- make_attach(filepath);
- }
- }
- if(net) { /* Construct MSGTO for bomb runs, carbons */
- if(!stristr(hold,"\01MSGTO: ")) {
- sprintf(msgto,"\01MSGTO: %u:%u/%u.%u\r",msg.d_zone,msg.dest_net,msg.dest,msg.d_point);
- }
- else *msgto=0;
- }
- else *msgto=0;
- msg.length=0;
- msg.start=0;
- msg.d_point=0;
- msg.o_point=0;
- msg.d_zone=0;
- msg.o_zone=0;
- msg.attr = msg.attr | MSGLOCAL;
- fwrite(&msg,sizeof(struct _xmsg),1,pp);
- if(*msgto) fwrite(msgto,strlen(msgto),1,pp);
- fwrite(hold,strlen(hold),1,pp);
- fputc('\0',pp);
- free(hold);
- fclose(pp);
- }
- fclose(pf);
- fclose(fp);
- return number;
-
- }
-
-
-
- int pascal import (char *dir,word base,char *filedir) {
-
- static char filename[132]; /* static vars are just to speed things up? */
- static char textname[132];
- static char file[132];
- static char filecheck[132];
- static struct _xmsg msg;
- FILE *fp;
- FILE *pf;
- FILE *pp=NULL;
- char once;
- char *hold;
- struct ffblk filestat;
- register word messno;
- register word number;
- struct date dos_date;
- long length;
- long pos;
-
- sprintf(filecheck,"%s0.MSG",filedir); /* In case of screw-up */
- remove(filecheck);
- if (!net) {
- sprintf(filecheck,"%s1.MSG",filedir); /* Kill high-water mark */
- remove (filecheck);
- }
-
- sprintf(filecheck,"%s*.MSG",filedir); /* Check for *.MSG Files */
- if (findfirst(filecheck,&filestat,0)) return 0;
-
- getdate(&dos_date);
-
- sprintf(filename,"%sXDATA.%03x",dir,base);
- sprintf(textname,"%sXTEXT.%03x",dir,base);
-
- if (findfirst(filename,&filestat,0)!=0) messno=0;
- else messno=(word)(filestat.ff_fsize/(long)sizeof(struct _xmsg));
- if (messno==(word)65535) {
- printf("\nMessage base is full\n");
- return 0;
- }
-
- if(!(pf=fopen(textname,"a+b"))) {
- printf("\nCannot open %s",textname);
- return (0);
- }
-
- fseek(pf,0L,SEEK_END); /* Positively position to end of file */
-
- if (!(fp=fopen(filename,"a+b"))) {
- fclose(pf);
- printf("\nCannot open %s",filename);
- return(0);
- }
-
- fseek(fp,0L,SEEK_END); /* Positively position to end of file */
-
- number=0;
- if(!net)number++;
- do {
- /* Get *.MSG's */
- number++; /* in numerical */
- printf("%5u.MSG\x1b[9D",number); /* order */
- sprintf(file,"%s%u.MSG",filedir,number);
- if (findfirst(file,&filestat,0)) {
- sprintf(file,"%s*.MSG",filedir);
- if(findfirst(file,&filestat,0)) break;
- continue;
- }
-
- if(!(pp=fopen(file,"rb"))) {
- fclose (fp);
- fclose (pf);
- printf("\nCannot open %s",file);
- return 0;
- }
- rewind(pp);
- fread(&msg,sizeof(struct _xmsg),1,pp);
- if(msg.attr & MSGORPHAN) goto Discard;
- if (filestat.ff_fsize>65100L) {
- filestat.ff_fsize=65100L;
- msg.attr = (msg.attr | MSGORPHAN);
- }
- length=(filestat.ff_fsize-(long)sizeof(struct _msg));
- if (length<1L) {
- printf("\nGrunged msg discarded...");
- goto Discard;
- }
- if(length>65100L) {
- printf("\nMsg truncated...");
- length=65100L;
- }
- msg.length=(word)(length+1L);
- msg.attr = msg.attr & (~MSGLOCAL);
- if(net) {
- msg.m_attr = (msg.m_attr | MSGNET);
- }
- else {
- msg.m_attr = (msg.m_attr | MSGECHO);
- }
- msg.start=ftell(pf);
- msg.subj[63]=0;
- msg.o_zone=0;
- msg.o_point=0;
- msg.d_point=0;
- msg.d_zone=0;
- msg.m_attr=0;
- msg.indate[0]=(char)dos_date.da_year-1989;
- msg.indate[1]=(char)dos_date.da_mon;
- msg.indate[2]=(char)dos_date.da_day;
- msg.indate[3]=0;
- msg.times=0;
-
- hold=(char *)malloc(msg.length+1); /* Allocate buffer */
- if (hold==NULL) {
- printf("\nOut of memory.\n");
- fclose(pf);
- fclose(fp);
- fclose(pp);
- exit(4);
- }
- pos=ftell(pp);
- fread(hold,msg.length,1,pp); /* Read in msg text */
- fclose(pp); /* Done with that file */
-
- hold[msg.length-1]=0; /* Make sure it's NULL terminated */
-
- {
-
- char *tempo;
-
- tempo=hold;
- while (*tempo) { /* Strip linefeeds and soft cr's FAST */
- if(*tempo=='\x8d' || *tempo=='\n') {
- if(*tempo=='\n')
- memmove(tempo,&tempo[1],msg.length-((word)tempo-(word)hold));
- else {
- if(*(tempo-1)==' ' && tempo>hold)
- memmove(tempo,&tempo[1],msg.length-((word)tempo-(word)hold));
- else *tempo=' ';
- }
- }
- tempo++;
- }
- msg.m_attr = (msg.m_attr | MSGTREATED); /* Reads quicker */
- }
-
- if (!no_strip) { /* Strip SEEN-BYs, EIDs and other
- totally useless, inane bullshit */
- char *tempo=NULL;
- char *path=NULL;
- char *seenby=NULL;
- char *origin=NULL;
-
- msg.attr = (msg.attr | MSGORPHAN); /* Don't allow reexport of stripped msgs */
- tempo=hold; /* They oughta outlaw EID's */
- while ((tempo=strstr(tempo,"\01EID:"))) memmove(tempo,strchr(&tempo[1],'\r'),strlen(strchr(&tempo[1],'\r'))+1);
- origin=strstr(hold,"\r * Origin:"); /* Find the origin line */
- if (origin) { /* Ain't one; oh, well, screw it */
- while(tempo=strstr(&origin[1],"\r * Origin:")) origin=tempo; /* Find last */
- path=strstr(origin,"\r\01PATH:"); /* Find the PATH line */
- seenby=strstr(origin,"\rSEEN-BY:"); /* Find start of SEEN-BYs */
- if (!seenby) seenby=strstr(origin,"\r\01SEEN-BY:");
- if (!path) if (seenby) *seenby=0; /* Mercifully kill SEEN-BYs */
- if ((seenby && path) && seenby<path) memmove (seenby,path,strlen(path)+1); /* Keep PATH */
- }
- if (hold[strlen(hold)-1]!='\r') strcat(hold,"\r"); /* Assure trailing cr for appearance */
- }
-
- if(!nofillin) { /* Fill in header address info from kludges */
-
- char *p;
- char *tempo;
- char message[133];
-
- if ((p=strstr(hold,"\01FMPT "))) {
- strncpy(message,p,133);
- message[132]=0;
- p=message;
- msg.o_point=(char)atoi(&p[5]);
- }
- if ((p=strstr(hold,"\01INTL "))) {
- strncpy(message,p,133);
- message[132]=0;
- p=message;
- strtok(p," :");
- strtok(0," ");
- tempo=strtok(0,":");
- if(tempo)if ((word)atol(tempo)) msg.o_zone=(word)atol(tempo);
- }
- if ((p=strstr(hold,"\01MSGID: "))) {
-
- char *ispoint;
- char *isnumsign;
-
- strncpy(message,&p[7],133);
- message[132]=0;
- lstrip(rstrip(message));
- p=message;
- ispoint=strchr(p,'.');
- isnumsign=strchr(p,'#');
- if(isnumsign) { /* For [user@]domain#z:n/n.p */
- if(isnumsign<ispoint || !ispoint) {
- strtok(p,"#");
- p=strtok(0,"\n");
- }
- }
- strtok(p," :");
- p=strtok(0,":");
- if(p)msg.o_zone=(word)atol(p);
- p=strtok(0,"/");
- msg.orig_net=(word)atol(p);
- if(ispoint) p=strtok(0,".");
- else p=strtok(0,"@ ");
- if(p)msg.orig=(word)atol(p);
- if(ispoint) {
- p=strtok(0,"@ ");
- if(p && (word)atol(p) && atol(p)<65536)
- msg.o_point=(word)atol(p);
- }
- }
- if ((p=strstr(hold,"\01MSGTO: "))) {
-
- char *ispoint;
- char *isnumsign;
-
- strncpy(message,p,133);
- message[132]=0;
- lstrip(rstrip(message));
- p=message;
- ispoint=strchr(p,'.');
- isnumsign=strtok(p,"#");
- if(isnumsign<ispoint || !ispoint) {
- p=strtok(p,"#"); /* Get past domain */
- p=strtok(0,"\n");
- }
- strtok(p," :");
- p=strtok(0,":");
- if(p)msg.d_zone=(word)atol(p);
- p=strtok(0,"/");
- msg.dest_net=(word)atol(p);
- if(ispoint) p=strtok(0,".");
- else p=strtok(0,"@ ");
- if(p)msg.dest=(word)atol(p);
- if(ispoint) {
- p=strtok(0,"@ ");
- if(p && (word)atol(p) && atol(p)<65536)
- msg.d_point=(word)atol(p);
- }
- }
- }
-
- msg.length=(word)(strlen(hold))+1; /* How long the useful part is */
-
- if(compress_size && strlen(hold)>compress_size) {
-
- char *tempo;
-
- tempo=hold;
- hold=pack_msg(hold,&msg);
- if(!hold) hold=tempo;
- else {
- free(tempo);
- msg.m_attr = msg.m_attr | MSGPACKED;
- }
- }
-
- fwrite(&msg,sizeof(struct _xmsg),1,fp); /* Write header */
- messno++;
-
- fwrite(hold,msg.length,1,pf); /* Save text */
- fputc('\0',pf); /* NULL terminate */
- free(hold); /* Free buffer */
-
- Discard:
-
- remove(file); /* Get rid of pesky *.MSG */
- if (!messno) { /* Rolled over word bounds */
- printf("\nMessage base is full\n");
- return 0;
- }
- } while (number); /* Do it again... */
- fclose(pf); /* Clean up and exit */
- fclose(fp);
- return number;
-
- }
-
-
-
- void pascal getone (char *s, FILE *fp, word lineno) {
-
- /* Get one line at a time from file, skip comments, stop at eof */
-
- do {
- if (!fgets(s,512,fp)) *s=0;
- lineno++;
- } while (!feof(fp) && *s==';');
- if (feof(fp)) *s=0;
-
- }
-
-
-
- char * pascal rstrip (char *a) { /* Strip trailing blanks */
-
- register word x;
-
- x=strlen(a)-1;
- while (a[x-1]==' ' && x) a[--x]=0;
- return a;
- }
-
-
-
- char * pascal lstrip (char *a) { /* Strip leading blanks */
-
- register word x;
-
- x=strlen(a);
- while (*a && *a==' ') memmove (a,&a[1],x--);
- return (a);
- }
-
-
-
- char * pascal stripcr (char *a) /* Strip ending cr's &/| lf's */
-
- {
-
- register word x;
-
- x=strlen(a);
- while (a[x-1]=='\n' || a[x-1]=='\r') a[--x]=0;
- return a;
-
- }
-
-
- char * pascal stristr (char *t, char *s) {
-
- char *t1;
- char *s1;
-
- while(*t) {
- t1=t;
- s1=s;
- while(*s1) {
- if (toupper(*s1)!=toupper(*t)) break;
- else {
- s1++;
- t++;
- }
- }
- if (!*s1) return t1;
- t=t1+1;
- }
- return NULL;
- }
-
-
- void pascal make_attach (char *filetosend) {
-
- char *p;
-
- p=nodes; /* Point to list of nodes */
- /* This, obviously, isn't finished */
-
- }