/****************************************************************************** * Metal Enter (send) message routine. * * File name: MESEND.C version 1.20a * * Copyright (c) 1984 Tim Gary * Delphi Data Systems * All rights reserved. * * * This module contains the message entry routine (enter, reply, etc) * ***************************************************************************** * * 1.20a 11/07/84 Subject confirmation on reply. * 1.20a 11/04/84 Apply stuff added, private msg to sysop. * 1.10e 11/02/84 Fixed for new get/put counters. * 1.10e 10/30/84 Added privmsgs counter. * 1.10b 10/02/84 Cosmetics (deleted extra spaces). * 1.10a 9/28/84 Edit bug looked into. * 1.10a 9/27/84 More cosmetic fixes. * 1.10a 9/14/84 Added simplistic line edit of message text... * 1.10a 9/01/84 Routine taken from MS.C for overlay metal. * * 1.01a 7/14/84 Message editing bugs fixed (delete line.. movmem changed). * Added subject truncation notice on message entry. * 1.01a 6/30/84 Cleaned up more functions. * 1.01a 6/26/84 Cleaned up a few functions, and added MULTI_USER stuff. * 1.01a 6/10/84 Fixed to work with Aztec C 1.06. Started Multi-user stuff. * * 1.0b 4/13/84 Modified for upper/lower case names, and added check for * maximum messages allowed (killed and active ones). * * 1.0a 3/16/84 Fixed reply bug. * * 1.0 1/20/84 New format of Message file headers. * p3.0 12/14/83 pre-release version 3.0 mods for MCONFIG.. * *****************************************************************************/ #include "xpm.h" #include "hmh.h" #include "hmconfg.h" #include "ctype.h" static char *lp[MAXMLINES]; /* array of pointers to msg text lines */ /************************************************************************** * enter a message, or reply to a message... mode=0 to enter, -1 to reply * * or msg # to reply without asking for #.. (ie for read/reply) * ************************************************************************** * if func=0, then reply or enter, if func=1 then APPLY command, private * message to sysop. */ ovmain(func,mode) int func; /* definition required, but variable not used */ unsigned mode; { char *ptr,temp[81],*reserve; /* reserve=reserved alloc block for files */ int a,b; register int loop,line; if (O.user_types[user.type].postmsg==NO && func!=1) { send("You may not enter a message until the system operator approves it.\ \nLeave comments to the sysop if you would like this ability.\n"); return; } if ((totalmsgs>=O.MAXTOTMSGS) || (msgcount>=O.MAXMSGS)) { send("\nSorry, the message base is full.\nPlease try to leave your message at a later time."); return; } if (mode==0) /* regular msg entry */ { if (func!=1) { ask("Who to (RETURN for all) ?", message.receiver,FNAMELEN+LNAMELEN+1,UPLOW); capstr(message.receiver); if (message.receiver[0]=='\0') strcpy(message.receiver,"ALL USERS"); } else { strcpy(message.receiver,"Sysop"); send("To: Sysop\n"); } if (get_topic(message.topic)==ERROR) return; } else { /* reply to message */ if ((int)mode==-1) /* regular reply command.. */ { ask("Reply to what message ? ",temp,6,UP); if (!isdigit(*temp)) return; /* not alpha, return to command */ mode=atoi(temp); /* convert to number */ if (!mode) return; /* invalid message #=0 */ messages=open(MESSAGES,F_RD | F_UNLOCK); /* the following assumes open file */ } /* both regular and read/reply use the following */ /* mode=message number replying to */ /* file must be open before... from read, or whatever.. */ a=getindex(mode); /* get index into msg array, of msg mode */ if (a==ERROR) { close(messages); send("\n[Message not found]\n"); return; } setarec(messages,msg[a].seek); /* seek to message replying to */ read(messages,0); /* get the header */ movmem(bufloc(messages),&message,128); /* get stuff into structure */ sprintf(message.receiver,"%s %s",message.fsend,message.lsend); send("\nTo: "); send(message.receiver); putchar('\n'); send("Subject: "); send(message.topic); close(messages); /* close the file */ send("\n[Is the subject ok (y/n)? ] "); if (tolower(getd())=='n') { send("[no]\n"); if (get_topic(message.topic)==ERROR) return; } else send("[yes]\n"); if (message.status==DEADMSG) mode=0; /* make rest of stuff nonrep */ } /* end of initial reply stuff all the rest of entermsg is as it was, except to end where pointers are setup to the reply */ if (func==1) { send("\nMessage will be Private.\n"); message.status=PRIVMSG; } else do { message.status=NORMMSG; /* default to normal message */ send("(Private/Normal) ?"); getl(buffer,UP); *buffer=tolower(*buffer); if (*buffer=='p') message.status=PRIVMSG; /* private msg */ else if (*buffer=='?') { send("\nTo make the message readable only by the person\n\ it is addressed to, enter P for private.\n\n\ Anything else will make the message public (normal).\n\n"); continue; /* and ask again */ } else if (*buffer!='n') send("[Normal assumed]\n"); break; /* what, you say??? yeh, yeh.. see the continue above?? */ } while (1); if (user.parm.expert==POFF) /* not expert.. tell him what to do */ { sprintf(buffer, "\nEnter message text following each line number.\ \nTo edit or end, hit RETURN alone on a line.\ \nUp to %d characters (letters/numbers) on a line,\ \nand %d lines maximum.\n",O.MAXMSGLINE,O.MLINES); send(buffer); } reserve=malloc(2*(sizeof(FILE))+10); /* make sure there's room for files */ /********************************/ /* Lines may be up to MAXMSGLINE long, and up to MLINES lines */ /* can be entered... limitted by avaliable memory only! */ /********************************/ /* Main loop */ /****************/ for (line=1; line<=O.MLINES; line++) { cont: printf("%2d: ",line); getl(buffer,UPLOW+MSGLINE); /* get line up to MAXLINE long */ if (*buffer=='\0') break; /* return alone. get enter command */ if (save_line(line,buffer)==ERROR) break; /* above allocs space, and puts line there if room.. ERROR==no room */ } do { if (user.parm.expert==POFF) { send("\n(A)bort, (C)ontinue, (D)elete, (E)dit,\n(I)nsert, (L)ist, (R)eplace, (S)ave"); if (user.status==SYSOP) send("\n(F)ile read"); send(" :: Select"); } else if (user.status!=SYSOP) send("\nA,C,D,E,I,L,R,S"); else send("\nA,C,D,E,I,L,R,S,F"); sepstr=' '; ask(" ? ",temp,10,UP); sepstr='\0'; switch (*temp) { case '?': send("(A)bort message entry (C)ontinue entering message\ \n(D)elete line of the message (E)dit message text\ \n(I)nsert a line of text (L)ist the message\ \n(R)eplace line with new one (S)ave the message"); if (user.status==SYSOP) send("\n(F)ile transfer to message text\n"); break; case 'A': for (loop=0; loopTOPICLEN) /* tell him it's too long.. */ { temp[TOPICLEN]='\0'; /* truncate topic */ printf("\nSubject truncated to: %s\n",temp); ask("Is this ok (y/n)? ",temp+TOPICLEN+2,2,UP); if (temp[TOPICLEN+2]=='N') goto about; /* ask topic again */ if (temp[TOPICLEN+2]!='Y') send("[Yes assumed]\n"); } /* I'm sick of slandering goto, in certain cases, it makes life much easier... */ strcpy(message.topic,temp); if (message.topic[0]=='\0') return ERROR; /* return hit? yep->return */ return NULL; } /******************************************************** * save line pointed to by buf, in message buffer.. * ********************************************************/ save_line(line,buf) register int line; register char *buf; { if ((lp[line-1]=malloc(strlen(buf)+2))==0) /* try to get space */ { send("\n[Message buffer full!! Line not entered]\n\ [Please save message, and continue in a new one]\n"); return ERROR; /* and exit to enter command mode */ } strcpy(lp[line-1],buf); /* setup line pointer for later use */ return NULL; } /***************************************** * read in a message from a regular file * *****************************************/ read_file(line) register int line; { char file[20]; register FILE *fd; register int oline; char *bp; int i; oline=line; /* for ending output of # lines read */ ask("\nFile to copy to message text? ",file,19,UP); if ((fd=open(file,0))!=NULL) /* try to open file */ { read(fd,1); /* fgets needs initial read */ while (line<=O.MLINES && i!=0x1a && i!=EOF) { bp=buffer; while (1) { if ((i=getc(fd))==EOF) break; if (i=='\r' || i==0x1a) break; if (i!='\n') *bp++=i; } *bp='\0'; /* terminate string */ if (save_line(line,buffer)==ERROR) break; /* no space */ send("\n"); /* to allow ^s */ printf("%2d: %s",line++,buffer); } printf("\n\n[%d lines read from %s]\n",line-oline,file); close(fd); } else send("[File NOT found]"); return line; } ins_line(cline) register int cline; { register char *ptr; register int ln,loop; char temp[11]; if (cline0) && (ln<=cline)) { printf("%3d: ",ln); getl(buffer,UPLOW+MSGLINE); if ((ptr=malloc(strlen(buffer)+2))==0) { send("\n[Message buffer FULL, line not entered!]\n"); return cline; } /* move line pos pointers up a line */ for (loop=cline+2; loop>=ln; loop--) lp[loop]=lp[loop-1]; lp[ln-1]=ptr; strcpy(ptr,buffer); /* insert the line */ cline++; /* one more line */ } else send("\n[Invalid line]"); } else { sprintf(buffer,"\n[Max of %d lines!!]",O.MLINES); send(buffer); } return cline; } /* ins_line */ del_line(cline) register int cline; { register int ln ,i; char temp[11]; ask("Delete which line ?",temp,10,UP); putchar('\n'); ln=atoi(temp); if ((ln>0) && (ln0) && (ln0) && (lnO.MAXMSGLINE) { send("\nNew line to long. Edit aborted.\n"); return; } printf("\n%3d: %s\n",ln,buffer); free(lp[ln-1]); save_line(ln,buffer); } else send("\n[Invalid line]"); } /* edit_line */ /* End of file */