/****************************************************************************** * METAL Message section... * * File name: MES.C * * Metal and Metal Message System are Trademarked and * Copyright (c) 1984, 1985, 1986 Tim Gary * All rights reserved. * * * This module contains common message base routines (read, msgheader, etc) * ***************************************************************************** * * 1.50xx 03/14/86 Split the message header to avoid overflow. * 1.50xx 03/10/86 Cosmetics to read header format.. * 1.50xx 03/08/86 Header function updated to allow groups.. * 1.50xx 03/04/86 Support for date/time read for message header.. * 1.50xx 03/01/86 msgheader parms changed.. Tagged and Mail messages.. * 1.40xx 02/28/86 Started removal of msg.reply value.. Use msg_reply subr. * 1.40xx 02/10/86 Put help in library help file.. * 1.40xx 01/26/86 Fixed for new time/date and other stuff.. * 1.31a 10/13/85 Release version. Fixed bug in getheader(), moved read * message functions to overlay. * 1.30xx 6/23/85 Spelling error fixed. * 1.30xx 3/03/85 Z3 stuff added, fixed prompts for ignoring controls. * 1.20b 01/21/85 Message read fixed for sysop '<' function.. * 1.20b 01/11/85 Swap order of sender/recipient in summary. * 1.20b 01/09/85 Really fixed search function. Added & op to search. * Added sysop link of a message to a file.. * 1.20b 01/07/85 Search function fixed, Quiet read mode, novice help, * extended abort checking during search operations, and * summary function output changed. * 1.20a 11/11/84 Nothing found message fixed in selective read. * 1.20 11/09/84 [Nothing found/not addressed to ya/dead] msg in read. * 1.20 11/04/84 Fixed timefix routine for no clock. * 1.10e 11/01/84 Allow for reading of dead msgs. * 1.10e 10/31/84 Width stuff changed in msgheader, fixed for unkill. * 1.10c 10/12/84 Made a few functions here overlays to conserve space. * 1.10b 10/09/84 Complete reworking of read message routines (internal only). * 1.10b 10/04/84 More cosmetics.. Should be it for a while. * 1.10a 9/28/84 Fixed reply problem (msg shown after reply..). * 1.10a 9/26/84 Added a few cosmetic changes (y/n)? and selective read help. * 1.10a 9/24/84 Fixed edit user/kill this msg, bugs.. (introduced 8/31/84) * 1.10a 9/12/84 Eliminated Reverse read bug (replies not listed) * 1.10a 9/12/84 Cosmetic changes. * 1.10a 9/09/84 Cosmetic changes. * 1.10a 9/07/84 Added Kill previous message to selective read for sysop. * 1.10a 9/06/84 Changed Edit/delete user on read for previous message. * 1.10a 8/31/84 Split for overlays, now contains readmsg() and commons. * * 1.01a 8/05/84 Got things going, added delete user, and edit user during * message read (prompted mode). * 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/20/84 (cont) Added msearch, for string search for msgs.. * 1.0b 4/13/84 Modified for upper/lower case names, and added check for * maximum messages allowed (killed and active ones). * * 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" /* i/o operations related defs */ #include "megen.h" /* general defines */ #include "meglob.h" /* global variable definitions */ #include "meovfn.h" /* overlay function numbers */ #include "mefiles.h" /* file names */ #include "ctype.h" #define SRCHHELP "MSGSRCH HLP" char msearch(); getindex(m) register unsigned m; { register int a; /* a rather long/cryptic statement.. if m!=0, then loop til m is found */ if (m) for (a=0; agt_num) return msg[i].number; return 0; /* if we are here, it wasn't found */ } #ifdef MULTI_USER /********************************************************* * Check for new messages, update counters/array if some * are actually found. Used only in Multi-user systems *********************************************************/ mu_update() { register unsigned tn_msg; register msg_record *mptr; register int rval=0; /* return value # of new msgs */ unsigned new_msgs(); if (!(tn_msg=new_msgs())) return rval; /* check if counters updated */ /* tn_msg will contain # of new 'nextmsg' counter, from counters file */ printf("\n%u new messages entered by other users.\n",tn_msg-nextmsg); summary=open(SUMMARY,F_RD | F_UNLOCK); mptr=bufloc(summary); toeof(summary); setrrec(summary,nextmsg-tn_msg); /* backup # msgs */ rval=tn_msg-nextmsg; while ((nextmsg++)status!=DEADMSG) { msg[mindex].number=mptr->number; msg[mindex].seek=mptr->seek; msg[mindex].parent=mptr->parent; ++totalmsgs; ++msgcount; if (thisis(mptr->reciever)) printf("\n#%u from %s is for you.\n",mptr->number, mptr->sander); } /* if */ } /* while */ close(summary); lmsg=msg[mindex-1].number; putchar('\n'); return rval; /* # of new msgs */ } /* mu_update */ /********************************************************* * check for differing (in nextmsg) counters file * returns new nextmsg *********************************************************/ unsigned new_msgs() { register FILE *counters; unsigned tnext=0,*uptr; if ((counters=open(COUNTERS,F_RD | F_UNLOCK))!=NULL) { uptr=bufloc(counters); tnext=uptr[2]; /* next message */ /* sscanf(bufloc(counters),"%*d %*d %d",&tnext); */ close(counters); if (tnext==nextmsg) tnext=0; } return tnext; } #endif /* multi user */ /**************************************************************** * format message header info * * formats. 0=Quick Summary format 1=Full summary format * * 2=Read Message format 3=Kill message format * * 4=unkill.. * ****************************************************************/ get_header(mode,buf) register int mode; register char *buf; { char tstr[30]; register int a; *tstr='\0'; /* if (message.parent) if ( getindex(message.parent)==ERROR ) message.parent=0; */ if (!mode) sprintf(buf,"\n%u %s",message.number,message.topic); else if (mode==1) { if (message.parent) sprintf(tstr,"[R/%u]",message.parent); *(message.date_entr+5)='\0'; /* chop off year... */ sprintf(buf,"\n%4u %s %s%s \"%s\"(%d) To: %s %s%sFrom: %s", message.number,ascdate(message.date_entr), (msg[getindex(message.number)].flags & TAGGED) ? "[t] " : "", tstr,message.topic,message.lines,message.receiver, (message.status==PRIVMSG ? "" : message.status==DEADMSG ? "" : ""), user.width<80 ? "\n " : " ",message.sender); if (user.width>=80) buf[user.width]='\0'; /* cut off at 80 chars */ } else if ((mode!=3 && mode!=4) || !(user.flags&EXPERT) ) { char tstr2[50],tstr3[15]; if (message.parent) sprintf(tstr," [reply to #%u]",message.parent); if (message.status==PRIVMSG) strcpy(tstr3,"private"); else if (message.status==DEADMSG) strcpy(tstr3,"deleted"); else *tstr3='\0'; if (message.date_read[0]!=0x00) sprintf(tstr2," [%s%sread %s%s%s]", tstr3,*tstr3 ? " - " : "", ascdate(message.date_read), O.RTC ? " at " : "", O.RTC ? asctime(message.time_read) : ""); else if (*tstr3) sprintf(tstr2," [%s]",tstr3); else *tstr2='\0'; sprintf(buf,"\n-------\nMessage #%u ** %s **%s\ \nPosted: %s %s%s\ \n From: %s",message.number, message.groupprivflags & READPRIV)) : (!(user.type_ptr->privflags & KILLFLAG)) ) && (ustrcmp(message.sender,user.name)) ) return NULL; if (fixed_mode==3 && !thisis(message.receiver) && ustrcmp(message.sender,user.name) && !(user.type_ptr->privflags & KILLFLAG)) return NULL; if (message.group=startmsg || startmsg==0) { */ if (msearch(0)==0) return NULL; /* no match.. ret */ get_header(fixed_mode,buffer); if ((fixed_mode!=3 && fixed_mode!=4) || !(user.flags&EXPERT) ) /* write line */ if (send(buffer)==ERROR) return ERROR; /* } else return NULL; */ return message.lines ? message.lines : 1; /* if 0 lines, fake it.. */ } search_help() /* display help for search functions */ { ltype(METHELP,SRCHHELP); } /************************************************************************ * Search for string in message variables if passed string ptr=0, * else, setup the string to be compared to the message variables later. * string, if passed, format of: * : s or g=subject/group search * f=from search t=to search d=date search * *=search all above fields &=perform 'and' search on * examples: ALL fields...sorry * s:for sale ft:tim gary d:09-02-84 * t:all &s:for sale t:tim gary s:metal * g:general * in read operations: * rs;30+ s:wanted r;223+ *:sysop etc... * * returns: bit 0 ON for SUBJECT match bit 1 ON for DATE match * bit 2 ON for FROM match bit 3 ON for TO match * bit 8 ON if no search.. ************************************************************************/ char msearch(sstr) char *sstr; { char *ps,*t_sstr; register char ret_flag; static char f_pattern[NAMELEN+1]; static char t_pattern[NAMELEN+1]; static char s_pattern[TOPICLEN+2]; static char d_pattern[10]; static int field_flag,and_flag; ret_flag=0; if (sstr) /* if not null ptr, setup search string */ { (*t_pattern)=(*f_pattern)=(*s_pattern)=(*d_pattern)='\0'; /* make empty at first */ field_flag=and_flag=NO; /* all off */ for (t_sstr=sstr; (ps=index(t_sstr,':')) && (t_sstr!=1); t_sstr=index(t_sstr,':')+1) /* '=' IS ON PURPOSE!!!!!!!! */ { while (--ps>=t_sstr) /* backwards parse from ':' */ { switch (*ps) { case 'S': case 'G': /* group too. */ field_flag|=1; get_pat(ps,s_pattern,TOPICLEN); break; case 'D': field_flag|=2; /* DATE */ get_pat(ps,d_pattern,8); break; case 'F': field_flag|=4; get_pat(ps,f_pattern,NAMELEN); break; case 'T': field_flag|=8; get_pat(ps,t_pattern,NAMELEN); break; case '&': and_flag=YES; break; case '*': field_flag=15; /* all bits on */ get_pat(ps,t_pattern,NAMELEN); get_pat(ps,f_pattern,NAMELEN); get_pat(ps,d_pattern,8); get_pat(ps,s_pattern,TOPICLEN); break; default: ps=t_sstr; /* stop loop here */ } /* switch */ } /* while loop */ } /* for loop */ ret_flag=field_flag; } /* main 'string passed' if */ else { /* no string passed, compare with message fields */ if (!field_flag) ret_flag=128; /* flag bit 7 if no compare */ else { char tstr[MAXLINE+1]; /* used for sender string */ if (field_flag&1) { ret_flag|=(usindex(s_pattern,message.topic) ? 1 : 0); if (message.grouptp1); else tp2=tp1+strlen(tp1); --tp2; while (tp1<=tp2 && (tp1-s_cop)<=max_len) *(dest++)=*(tp1++); *dest='\0'; /* terminate */ } /* get_pat */ /* End of MES.C */