/************************************************************************ * Metal Sysop Routines for METAL * * FILE: MESYSOP.C * * Metal and Metal Message System are Trademarked and * Copyright (c) 1984, 1985, 1986 Tim Gary * All rights reserved * ************************************************************************ * * 1.50xx 08/14/86 Fixed for new free_space() function.. * 1.50xx 03/09/86 Fixed for reply stuff, and no comments file.. * 1.40xx 01/26/86 New format of a few things.. * 1.31a 10/13/85 Release version. Security improved for '!' command. * Space on disk, and write error checks made during purge. * Purge function is now AT LEAST TWICE AS FAST.. * 1.30xx 6/23/85 BAK files deleted before rename.. * 1.30xx 3/03/85 Z3 stuff looked into for this module * 1.20b 01/07/85 Double purge bug corrected. * 1.20a 11/07/84 Purge message after effects muffled. * 1.20a 11/04/84 Few more safeguards added. * 1.10e 11/03/84 Ho hum, added info about disk reset, etc.. * 1.10e 11/02/84 Make purge function work!.. (after yesterday) * 1.10e 11/01/84 Reset disk performed before purge.. * 1.10e 10/31/84 Added sostat() and readcomm(). * Fixed purge messages to allow seperate output * drive for message file. * 1.10c 10/12/84 Modified to use msg[] table for reply/parent * in case of conficts found earlier. * 1.10b * 1.10a 9/26/84 Fixed purge to allow messages on drives * than A: * 1.10a 9/01/84 Split from mutil.c for overlay Metal. * * 1.01c 8/16/84 Improved bad record handling, and patchup. * * 1.01b 8/03/84 Fixed to handle message purge cases when a * summary file is unavailable, or destroyed.. * This is handled by removing or renaming the * the destroyed summary file, and index will be * built from message file directly. * * 1.01a 6/10/84 Fixed for Aztec C 1.06. * ***********************************************************************/ #include "xpm.h" /* CPMIO header file for i/o operations.*/ #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" /* Main dispatcher */ ovmain(func,parm) int func,parm; { switch (func) { case PURGE: if (user.status!=SYSOP) return; return destroy(parm); case SOSTAT: return sostat(parm); default: send("\nUnknown overlay function called for.\n"); break; } return ERROR; } /* main */ FILE *msource,*mdest; static int new_index,nmsg_rec; /* index variable, last+1 rec of msg file */ destroy(parm) int parm; { int tindex,err_flag; unsigned total; char temp[50],msgdest[30],sumdest[30],countdest[30],*tp,newdrive[10]; msg_record *mptr; new_index=total=0; if (!lmsg) { send("\nNo messages to purge.\n"); return; } msource=open(MESSAGES,0); printf("\nThere are %d active messages, and %d deleted messages (unpurged).\n", msgcount,mindex-msgcount); if (msource) { toeof(msource); nmsg_rec=getrec(msource); total=(nmsg_rec+7)>>3; printf("\nMessage file now %dk",total); } if (summary=open(SUMMARY)) { toeof(summary); total+=(getrec(summary)+7)>>3; printf(", Summary file is %dk\n",(getrec(summary)+7)>>3); close(summary); } /* check if possible problem with purge to same drive */ printf("\nFree space on same drive is %uK\n",free_space(summary->_fcb.f_drive)); if ( total+2 > free_space(summary->_fcb.f_drive) ) printf("\nWARNING: Space remaining on same drive is less than the total space used\nby the current summary, messages and counters files."); /* make sure the person still wants to do the purge */ close(msource); /* cause gotta close for reset disk */ ask("\n\nPurge messages (y/n) ?",temp,1,UP); if (*temp!='Y') return; send("\nPress any key to perform a disk reset and continue.\n(swap disks NOW if you need to!) --> "); getchar(); reset_disk(0); msource=open(MESSAGES,0); mptr=bufloc(msource); *newdrive='\0'; /* nothing */ do { ask("\n\nUser area/Drive to place new files on ( uu/d: )\n(RETURN=same as message source files)? ",temp,8,UP); if (index(temp,':') || index(temp,'/')) { sprintf(buffer,"\nNew user/drive = '%s', ok (y/n)? ",temp); ask(buffer,temp+10,2,UP); if (temp[10]=='Y') { strcpy(newdrive,temp); /* put in place */ break; } continue; } else if (*temp=='\0') break; } while (1); send("\n\n[Purging messages]\n"); if (!*newdrive) { unlink("summary.bak"); rename(SUMMARY,"summary.bak"); /* backup of summary file */ summary=open(SUMMARY,1); /* make new summary file */ } else { sprintf(sumdest,"%ssummary",newdrive); unlink(sumdest); /* make sure no file previously */ summary=open(sumdest,1); } *msgdest='\0'; if (tp=index(MESSAGES,':')) /* THIS = IS ON PURPOSE !!! */ { strncpy(msgdest,MESSAGES,tp-MESSAGES+1); msgdest[tp-MESSAGES+1]='\0'; /* terminate */ } if (*newdrive) { sprintf(msgdest,"%smessages",newdrive); sprintf(countdest,"%scounters",newdrive); unlink(countdest); unlink(msgdest); } else { strcat(msgdest,"messages.new"); unlink("counters.bak"); rename(COUNTERS,"counters.bak"); /* backup counters */ *countdest='\0'; } if (*newdrive) printf("\nOutput message file is %s.\nOutput summary file is %s.\n\ Output counters file is %s.\n",msgdest,sumdest,countdest); mdest=open(msgdest,1); if (!(msource && mdest && summary)) { printf("\nCan't open all files...\nMESSAGES=%s NEWMESS=%s SUMMARY=%s \n\n", msource ? "" : "", mdest ? "" : "", summary ? "" : ""); close(msource); close(mdest); close(summary); return; } sprintf(bufloc(summary),"%u",msgcount); write(summary,1); tindex=0; while (tindexstatus!=DEADMSG) if ((err_flag=wrtmsg(mdest,tindex))==ERROR) /* out to file */ break; /* stop here.. */ ++tindex; } mindex=new_index; if (err_flag!=ERROR) printf("\n\nMessage file now %dk, Summary file is %dk\n\n[Finishing up]\n", (getrec(mdest)+7)/8,(getrec(summary)+7)/8); close(mdest); close(summary); close(msource); if (!*newdrive) { if (err_flag!=ERROR) { unlink("messages.bak"); rename(MESSAGES,"messages.bak"); /* backup message file */ rename(msgdest,MESSAGES); } else { unlink(msgdest); rename("counters.bak",COUNTERS); unlink(SUMMARY); rename("summary.bak",SUMMARY); } } if (err_flag!=ERROR) pcounters(*countdest ? countdest : 0); else send("\n\n*** ERROR encountered while writing new file. Operation ABORTED ***\n"); send("\nPress any key to return to command mode.\n(swap disks back NOW if you need to!) --> "); getchar(); reset_disk(0); /* make sure buffers flushed */ if (err_flag==ERROR) { send("\n\nSince an error was encountered, tables will now be rebuilt using the\nmessage alert function....\n"); ovovload(OVINFREQ,MSGALERT,0); /* fix tables after a bad purge */ } printf("\n\n[done]\n"); } /* destroy */ wrtmsg(fil,tindex) FILE *fil; int tindex; { msg_record *mptr; int len,tlen; char *buf,*tbuf; mptr=bufloc(msource); sprintf(buffer,"\r[Processing %5u]",mptr->number); send(buffer); msg[new_index].number=mptr->number; msg[new_index].seek=mptr->seek=getrec(fil); /* fix seek loc */ msg[new_index].parent=mptr->parent=msg[tindex].parent; /* fix if bombed */ msg[new_index++].group=mptr->group=msg[tindex].group; movmem(bufloc(msource),bufloc(fil),128); /* copy to output buffer */ if (write(fil,1)!=128) return ERROR; movmem(bufloc(msource),bufloc(summary),128); if (write(summary,1)!=128) return ERROR; /* if last, use global eof rec pointer to compute size.. */ if (tindex>=mindex-1) len=nmsg_rec-getrec(msource); else len=msg[tindex+1].seek-getrec(msource); tlen=len; if ( (tbuf=buf=malloc(len*128+20))==(char *)0) { /* we do it the slower way if not enuf space */ while (len--) { if (read(msource,1)!=128) break; movmem(bufloc(msource),bufloc(fil),128); if (write(fil,1)!=128) return ERROR; } } else /* we can do it the fastest way... */ { while (len--) { if (read(msource,1)!=128) { tlen=tlen-len-1; /* point to actual number read */ break; } movmem(bufloc(msource),tbuf,128); tbuf+=128; } tbuf=buf; while (tlen--) { movmem(tbuf,bufloc(fil),128); tbuf+=128; if (write(fil,1)!=128) { free(buf); return ERROR; } } free(buf); } /* most efficient way else.. */ } /* write message */ /*********************** * Toggle sysop status * ***********************/ extern char ostat,sotries; /* these are defined in metal.c */ sostat(n) register int n; { if (user.status==SYSOP) { if (ostat!=0) { user.status=ostat; user.type_ptr=get_tp(user.status); } else { ostat=user.status=SPECIAL; user.type_ptr=get_tp(SPECIAL); } send("[Sysop status Off]"); #ifdef Z3 if (O.ZCPR==3) ovovloader(OVZ3,INITZ3,TRUE); #endif return; } ask("Prove it! ",buffer,PASSLEN+1,UP+NOECHO); /* why not */ if (!strcmp(buffer,O.SOPASS)) { ostat=user.status; /* save original status and type */ user.status=SYSOP; user.type_ptr=get_tp(SYSOP); sotries=0; send("[Sysop status On]"); } else if (++sotries>=O.MAXTRIES) hangup(0); /* dump after x tries */ *maxuser=user.type_ptr->maxuser; #ifdef Z3 if (O.ZCPR==3) ovovloader(OVZ3,INITZ3,TRUE); /* reset environment */ #endif } /* End of file */