home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 147_01 / rbbsfn.c < prev    next >
Text File  |  1985-03-10  |  12KB  |  502 lines

  1. /****************************************************************
  2. * RBBSFN.C                            *
  3.  
  4. Release 7: RBBS 4.1 Edit 02 - getname takes a prompt argument
  5. Release 5: RBBS 4.1 Edit 00 - Names now one large field
  6.                 - If output killed by user in bufinmsg,
  7.                   the stacked commands are flushed.
  8.                 - Inserted PERSONLY in dispsum
  9. Release 4: RBBS 4.0 Edit 21 - changed displ_subj to list across
  10. Release 1: RBBS 4.0 Edit 18
  11.  
  12. * This file contains the functions:
  13.  
  14. * get_date    gets the current date into the global sysdate
  15.  
  16. * displ_subj    displays the contents of SUBJECTS.CCC
  17.  
  18. * load_cntrl    creates the .MSG if none exists, else calls loadsum
  19.  
  20. * loadsum    calls readsum and fills the mndx and mno arrays
  21.  
  22. * dispsum    displays the one-liner summaries
  23.  
  24. * msg_info    gets the stats on the current .MSG file and
  25.                 optionally displays them
  26.  
  27. * prnt_txt    displays the text of a message optionally with
  28.                 line numbers
  29.  
  30. * setptr    sets up the line number pointers
  31.  
  32. * readtxt    reads the text of a message and prints it
  33.  
  34. * readsum    reads the header record and fills the summary
  35.                 structure for that message
  36.  
  37. * prnt_sum    displays the header of a message
  38.  
  39. * ritemsg    writes the header (via ritesum) and text to .MSG
  40.  
  41. * ritesum    writes the header to .MSG
  42.  
  43. * readrec    calls seek_blk and read(s a record)
  44.  
  45. * openfile    opens requested file and displays error msg on failure
  46.  
  47. * getname    prompts for and returns name
  48.  
  49. * seek_blk    calls seek and displays error msg on failure
  50.  
  51. * formrec    fills character array with blanks ending with CRLF
  52.  
  53. * Rriterec    writes a "random" record
  54.  
  55. * bufinmsg    fgets and outstr contents of file.CCC with pause
  56.  
  57. * ioerr        displays error messages
  58.  
  59. * rexit        chains to AUTO.COM
  60.  
  61. * hexit        chains to HANGUP.COM
  62.  
  63. ****************************************************************/
  64. #include    <bdscio.h>
  65. #include    "rbbs4.h"
  66.  
  67. /****************************************************************/
  68. get_date()        /* gets a date in format mm/dd/yy    */
  69. {
  70. #if    DATETIME
  71.     sprintf(sysdate,"%s %s",daytim(),ZONE);
  72. #else
  73.     int    mo,da,yr;
  74.     int    error;
  75.     int    leap;
  76.  
  77.     do
  78.     {
  79.         error = FALSE;
  80.         outstr("Date <MM/DD/YY>: ",5);
  81.         instr("",sysdate,9);
  82.         crlf(1);
  83.         if(*(sysdate+2) != '/' || *(sysdate+5) != '/')
  84.             error = TRUE;
  85.         *(sysdate+2) = *(sysdate+5) = 0;
  86.         mo = atoi(sysdate);
  87.         da = atoi(sysdate+3);
  88.         yr = atoi(sysdate+6);
  89.         leap = yr%4;
  90.         if ( (mo < 1) || (mo > 12) )
  91.             error = TRUE;
  92.         else
  93.         {
  94.             switch(mo)
  95.             {
  96.                 case 4:
  97.                 case 6:
  98.                 case 9:
  99.                 case 11:        
  100.                     if ( (da < 1) || (da > 30) )
  101.                         error = TRUE;
  102.                     break;
  103.                 case 2:
  104.                     if ( (da < 1) || (da > 28+leap) )
  105.                         error = TRUE;
  106.                     break;
  107.                 default:
  108.                     if ( (da < 1) || (da > 31) )
  109.                         error = TRUE;
  110.                     break;
  111.             }
  112.         }
  113.     } while(error);
  114.     *(sysdate+2) = *(sysdate+5) = '/';
  115. #endif
  116. }
  117. /***************************************************************/
  118. displ_subj(fd,n,rec)
  119. int    fd,n;
  120. char    *rec;
  121. {
  122.     int    i;
  123.  
  124.     crlf(1);
  125.     for ( i = 1; i <= n; i++)
  126.     {
  127.         sprintf(tmpstr,"<%2d>: %8.8s",i,rec+8*i);
  128.         outstr(tmpstr,0);
  129.         if ( !(i % 4))
  130.             crlf(1);
  131.         else
  132.             outstr("    ",0);
  133.     }
  134.     crlf(1);
  135. }
  136. /****************************************************************/
  137. load_cntrl(msgct,s)
  138. int    msgct;
  139. struct    _sum    *s;
  140. {
  141.     int    msgfd;
  142.  
  143.     if ( (msgfd = open(msgfile,2)) == ERROR)
  144.     {
  145.         sprintf(tmpstr,"Creating %s",msgfile);
  146.         outstr(tmpstr,1);
  147.         if ( (msgfd = creat(msgfile)) == ERROR)
  148.             ioerr("Creating msgfile");
  149.         mno[1] = mndx[1] = 0;
  150.         if (close(msgfd) == ERROR)
  151.             ioerr("Closing Msg");
  152.         return 0;
  153.     }
  154.     msgct = loadsum(msgfd,s);
  155.     if (close(msgfd) == ERROR)
  156.         ioerr("Closing Msg");
  157.     return msgct;
  158. }
  159. /***************************************************************/
  160. loadsum(fd,s)
  161. int    fd;
  162. struct    _sum    *s;
  163. {
  164.     int    ct, i, siz;
  165.  
  166.     ct = siz = 0;
  167.     for ( i = 1; i< MAXMSGS; i++)
  168.     {
  169.         if ( (ct = readsum(fd,ct,s)) == ERROR)
  170.         {
  171.             mndx[i] = mndx[i-1] + siz;
  172.             mno[i] = 0;
  173.             return (i-1);
  174.         }
  175.         if (i)
  176.             mndx[i] = mndx[i-1] + siz;
  177.         else
  178.             mndx[0] = 0;
  179.         siz = (s->lct+3)/2;
  180.         if (s->mstat)
  181.             mno[i] = s->msgno;
  182.         else
  183.             mno[i] = 0;
  184.     }
  185. }
  186. /***************************************************************/
  187. dispsum(s)
  188. struct    _sum    *s;
  189. {
  190.     char    temp[NAMELGTH+1];
  191.     char    temp1[NAMELGTH+1];
  192.  
  193.     sprintf(tmpstr,"%4d %2d  ",s->msgno,s->lct+5);
  194.     outstr(tmpstr,0);
  195.     sprintf(tmpstr,"%.9s  ",s->date);
  196.     outstr(tmpstr,0);
  197.     if (!strcmp(s->fnm,"SYSOP"))
  198.         outstr("SYSOP     ",0);
  199.     else
  200.     {
  201.         sscanf(s->fnm,"%s %s",temp1,temp);
  202.         sprintf(tmpstr,"%-10s",temp);
  203.         outstr(tmpstr,0);
  204.     }
  205.     outstr(" -> ",0);
  206.     if (!strcmp(s->tnm,"SYSOP"))
  207.         outstr("SYSOP       ",0);
  208.     else
  209. #if    !PERSONLY
  210.         if (!strcmp(s->tnm,"ALL"))
  211.             outstr("ALL         ",0);
  212.         else
  213. #endif
  214.         {
  215.             sscanf(s->tnm,"%s %s",temp1,temp);
  216.             sprintf(tmpstr,"%-10s  ",temp);
  217.             outstr(tmpstr,0);
  218.         }
  219.     sprintf(tmpstr,"%.30s",s->subj);
  220.     outstr(tmpstr,1);
  221. }
  222. /****************************************************************/
  223. msg_info(msgct,print)
  224. int    msgct,print;
  225. {
  226.     int    i;
  227.  
  228.     sprintf(tmpstr,"Current Message file: %s",cmsgfile);
  229.     outstr(tmpstr,2);
  230.     for ( i = 1; (i <= msgct) && (!mno[i]); i++);
  231.     frstmsg = mno[i];
  232.     for ( i = msgct; (i >= 1) && (!mno[i]); i--);
  233.     lastmsg = mno[i];
  234.     for ( i = 1, actmsg = 0; i <= msgct; i++)
  235.         if(mno[i])
  236.             ++actmsg;
  237.     if (print)
  238.     {
  239. sprintf(tmpstr,"First Active Msg #: %3d   No. of Active Msgs: %3d",frstmsg,actmsg);
  240.         outstr(tmpstr,2);
  241. sprintf(tmpstr," Last Active Msg #: %3d    Total No. of Msgs: %3d",lastmsg,msgct);
  242.         outstr(tmpstr,1);
  243.     }
  244. }
  245. /***************************************************************/
  246. prnt_txt(s,linenum)    /* print the output of the text buffer */
  247. struct    _sum    *s;    /* the structure s               */
  248. int    linenum;    /* the line number or 0 to suppress    */
  249. {
  250.     int    i;
  251.  
  252.     crlf(1);
  253.     for ( i = 1; i <= s->lct; i++)
  254.     {
  255.         *(lp[i]+MLINESIZ-1) = 0;
  256.         *tmpstr = 0;
  257.         if (linenum)
  258.             sprintf(tmpstr,"%2d>: ",i);
  259.         strcat(tmpstr,lp[i]);
  260.         outstr(tmpstr,1);
  261.     }
  262. }
  263. /****************************************************************/
  264. setptr(m,p)        /* Set ptrs to lines of message        */
  265. char    *m,*p[];
  266. {
  267.     int    i;
  268.  
  269.     p[0] = m;
  270.     for ( i = 1; i <= MLINELIM; i++)
  271.         p[i] = p[i-1]+MLINESIZ;
  272. }
  273. /***************************************************************/
  274. readtxt(fd,recno,s)
  275. int    fd, recno;
  276. struct    _sum    *s;
  277. {
  278.     int    i,j,blks;
  279.  
  280.     blks = (s->lct + 1)/2;
  281.     for ( i = 1, j = 1; i <= blks; i++)
  282.     {
  283.         readrec(fd,recno+i,tmpstr,1);
  284.         outstr(tmpstr,1);
  285.         if(++j <= s->lct)
  286.         {
  287.             outstr(tmpstr+SECSIZ/2,1);
  288.             ++j;
  289.         }
  290.     }
  291. }
  292. /***************************************************************/
  293. readsum(fd,recno,s)
  294. int    fd,recno;
  295. struct    _sum    *s;
  296. {
  297.     int    blks;
  298.  
  299.     if ( readrec(fd,recno,tmpstr,1) == ERROR)
  300.         return(ERROR);
  301.  
  302.     /* SSCANF CONSTANT INFORMATION */
  303.     sscanf(tmpstr,"%d ",&s->msgno);        /* MSG:    */
  304.     sscanf(tmpstr+LNS,"%d ",&s->lct);    /* LNS:    */
  305.     sscanf(tmpstr+STAT,"%d ",&s->mstat);    /* STAT:*/
  306.     sscanf(tmpstr+DT,"%s",s->date);        /* DT:    */
  307.     sscanf(tmpstr+FM,"%s",s->fnm);        /* FM:    */
  308.     sscanf(tmpstr+TO,"%s",s->tnm);        /* TO:    */
  309.     sscanf(tmpstr+SU,"%s",s->subj);        /* SU:    */
  310.     blks = (s->lct+3)/2;
  311.     return(recno+blks);
  312. }
  313. /****************************************************************/
  314. prnt_sum(s)
  315. struct    _sum    *s;
  316. {
  317.     sprintf(tmpstr,"Msg#: %d  (%d lines)",s->msgno,s->lct+5);
  318.     outstr(tmpstr,1);
  319.     sprintf(tmpstr,"Date: %s",s->date);
  320.     outstr(tmpstr,1);
  321.     sprintf(tmpstr,"From: %s",s->fnm);
  322.     outstr(tmpstr,1);
  323.     sprintf(tmpstr,"To:   %s",s->tnm);
  324.     outstr(tmpstr,1);
  325.     sprintf(tmpstr,"Re:   %s",s->subj);
  326.     outstr(tmpstr,1);
  327. }
  328. /****************************************************************/
  329. ritemsg(fd,recno,s,source)
  330. int    fd,recno;
  331. struct    _sum    *s;
  332. char    *source;
  333. {
  334.     int    blks,nextrec;
  335.  
  336.     nextrec = ritesum(fd,recno,s);
  337.     blks = (s->lct + 1)/2;
  338.     seek_blk(fd,recno+1);
  339.     if ( write(fd,source,blks) == ERROR)
  340.     {
  341.         sprintf(tmpstr,"Rite err in fd: %d,  rec: %d",fd,recno);
  342.         outstr(tmpstr,1);
  343.         rexit();
  344.     }
  345.     return (nextrec);
  346. }
  347. /***************************************************************/
  348. ritesum(fd,recno,s)        /* WRITE A ONE BLOCK SUMMARY     */
  349. int    fd,recno;        /* RECORD TO THE LOC'N 'RECNO'    */
  350. struct    _sum    *s;    
  351. {
  352.     int    blks;
  353.  
  354.     formrec(tmpstr,SECSIZ);
  355.     sprintf(tmpstr,"%04d ",s->msgno);    /* MSG:    */
  356.     sprintf(tmpstr+LNS,"%02d ",s->lct);    /* LNS:    */
  357.     sprintf(tmpstr+STAT,"%1d ",s->mstat);    /* STAT:*/
  358.     sprintf(tmpstr+DT,"%s",s->date);    /* DT:    */
  359.     sprintf(tmpstr+FM,"%s",s->fnm);        /* FM:    */
  360.     sprintf(tmpstr+TO,"%s",s->tnm);        /* TO:    */
  361.     sprintf(tmpstr+SU,"%s",s->subj);    /* SU:    */
  362.     seek_blk(fd,recno);
  363.     if ( write(fd,tmpstr,1) == ERROR)
  364.         ioerr("Writing to Summary");
  365.     blks = (s->lct+3)/2;
  366.     return(recno+blks);
  367. }
  368. /****************************************************************/
  369. readrec(fd,recno,dest,blks)
  370. int    fd,recno;
  371. char    *dest;
  372. int    blks;
  373. {
  374.     int    err;
  375.  
  376.     seek_blk(fd,recno);
  377.     err = read(fd,dest,blks);
  378.     if ( (!err) || err == ERROR)
  379.         return(ERROR);
  380.     else
  381.         return(TRUE);
  382. }
  383. /***************************************************************/
  384. openfile(fn)        /* OPENS A FILE FOR READING & WRITING    */
  385. char    *fn;        
  386. {
  387.     int    d;
  388.  
  389.     if ( (d = open(fn,2)) == ERROR)
  390.     {
  391.         sprintf(tmpstr,"Opening %s Error: %s  Quit",fn,errmsg(errno()));
  392.         if (getyn(tmpstr))
  393.             rexit();
  394.     }
  395.     return(d);
  396. }
  397. /****************************************************************/
  398. getname(name,prompt)        /*GET WHOLE NAME, CONVERT    */
  399. char    *name;            /*TO CAPS             */
  400. char    *prompt;
  401. {
  402.     outstr(prompt,5);
  403.     instr("",name,NAMELGTH);
  404.     capstr(name);
  405.     if (!strlen(name) || !strcmp(name,"ALL"))
  406.         return(TRUE);
  407.     return(FALSE);
  408. }
  409. /****************************************************************/
  410. seek_blk(fd,blk)    /*SEEKS TO THE FILE AND BLOCK & PRINTS    */
  411. int    fd,blk;        /*ERROR MESSAGE IF SEEK IS BAD        */
  412. {
  413.     if ( seek(fd,blk,0) == ERROR)
  414.     {
  415.         sprintf(tmpstr,"Seek error in fd %d, rec: %d",fd,blk);
  416.         outstr(tmpstr,1);
  417.         rexit();
  418.     }
  419. }
  420. /***************************************************************/
  421. Rriterec(fd,blk,nbl,source)
  422. int    fd,blk,nbl;
  423. char    *source;
  424. {
  425.     if ( seek(fd,blk,0) == ERROR)
  426.         ioerr("Seek error in random rite");
  427.     if ( write(fd,source,nbl) == ERROR)
  428.         ioerr("Rite error in random rite");
  429. }
  430. /***************************************************************/
  431. formrec(ptr,siz)    /* FORMS A BLANK RECORD WITH STRING TERM*/
  432. char    *ptr;
  433. int    siz;
  434. {
  435.     setmem(ptr,siz,' ');
  436.     *(ptr+siz-2) = 13;        /* CR */
  437.     *(ptr+siz-1) = 10;        /* LF */
  438. }
  439. /***************************************************************/
  440. bufinmsg(f)
  441. char    *f;
  442. {
  443.     char    buf[BUFSIZ];
  444.     char    file[18];
  445.     int    i;
  446.  
  447.     i = 0;
  448.     sprintf(file,"%s%s%s",DRIVE,f,".CCC");
  449.     if (fopen(file,buf) != ERROR)
  450.     {
  451.         if (!expert)
  452. outstr("Hit CTL-S or s to Pause; any key to Resume.  Hit CTL-K or k to Abort.",2);
  453.         crlf(1);
  454.         while ( (fgets(tmpstr,buf)) ) 
  455.         {
  456.             *(tmpstr+strlen(tmpstr)-1) = 0;
  457.             if (outstr(tmpstr,1))
  458.             {
  459.                 *sav = 0;
  460.                 break;
  461.             }
  462.             if (!(++i % 22))
  463.                 if (!getyn("More"))
  464.                     break;
  465.         }
  466.         fclose(buf);
  467.         crlf(1);
  468.         return TRUE;
  469.     }
  470.     return FALSE;
  471. }
  472. /***************************************************************/
  473. ioerr(s)
  474. char    *s;
  475. {
  476.     sprintf(tmpstr,"%s. Error: %s.  Quit",s,errmsg(errno()));
  477.     if (getyn(tmpstr))
  478.         rexit();
  479. }
  480. /****************************************************************/
  481. rexit()
  482. {
  483.     poke(0,0xc3);
  484.  
  485. #if    CHAINEXIT
  486.     exec(CHAIN);
  487. #endif
  488.     exit();
  489. }
  490. /****************************************************************/
  491. hexit()
  492. {
  493.     poke(0,0xc3);
  494.     poke(0x5b,0);
  495.  
  496. #if    HANGUP
  497.     exec(HANG);
  498. #endif
  499.     exit();
  500. }
  501. /****************************************************************/
  502. sprint