home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / INSTMSG.C < prev    next >
Text File  |  1995-05-12  |  13KB  |  569 lines

  1. /*****************************************************************************
  2.  
  3.                                WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12. *****************************************************************************/
  13.  
  14. #include "vars.h"
  15.  
  16. #pragma hdrstop
  17.  
  18. #include <dir.h>
  19. #include <errno.h>
  20.  
  21. /****************************************************************************/
  22.  
  23. void send_inst_msg(inst_msg_header *ih, unsigned char *msg)
  24. {
  25.   int f,i;
  26.   unsigned char s[81], tfn[81];
  27.  
  28.   sprintf(tfn,"%sTMSG%3.3d.%3.3d",syscfg.datadir, instance, ih->dest_inst);
  29.   f=sh_open1(tfn,O_RDWR | O_BINARY | O_CREAT);
  30.   if (f>=0) {
  31.     sh_lseek(f,0L,SEEK_END);
  32.     if (ih->msg_size>0)
  33.       if (!msg)
  34.         ih->msg_size=0;
  35.     sh_write(f,(void *)ih,sizeof(inst_msg_header));
  36.     if (ih->msg_size>0)
  37.       sh_write(f, (void *)msg,ih->msg_size);
  38.     f=sh_close(f);
  39.  
  40.     for (i=0; i<1000; i++) {
  41.       sprintf(s,"%sMSG%5.5d.%3.3d",syscfg.datadir,i,ih->dest_inst);
  42.       if (!rename(tfn, s) || (errno!=EACCES)) {
  43.         break;
  44.       }
  45.     }
  46.   }
  47. }
  48.  
  49. /****************************************************************************/
  50.  
  51. void send_inst_str1(unsigned short m, int whichinst, unsigned char *sendstr)
  52. {
  53.   inst_msg_header ih;
  54.  
  55.   ih.main=m;
  56.   ih.minor=0;
  57.   ih.from_inst=instance;
  58.   ih.from_user=usernum;
  59.   ih.msg_size=strlen(sendstr)+1;
  60.   ih.dest_inst=whichinst;
  61.   time((long *)&ih.daten);
  62.  
  63.   send_inst_msg(&ih,sendstr);
  64. }
  65.  
  66. /****************************************************************************/
  67.  
  68. void send_inst_str(int whichinst, unsigned char *sendstr)
  69. {
  70.   send_inst_str1(INST_MSG_STRING, whichinst, sendstr);
  71. }
  72.  
  73. /****************************************************************************/
  74.  
  75. void send_inst_sysstr(int whichinst, unsigned char *sendstr)
  76. {
  77.   send_inst_str1(INST_MSG_SYSMSG, whichinst, sendstr);
  78. }
  79.  
  80. /****************************************************************************/
  81.  
  82. void send_inst_shutdown(int whichinst)
  83. {
  84.   inst_msg_header ih;
  85.  
  86.   ih.main=INST_MSG_SHUTDOWN;
  87.   ih.minor=0;
  88.   ih.from_inst=instance;
  89.   ih.from_user=usernum;
  90.   ih.msg_size=0;
  91.   ih.dest_inst=whichinst;
  92.   time((long *)&ih.daten);
  93.  
  94.   send_inst_msg(&ih,NULL);
  95. }
  96.  
  97. /****************************************************************************/
  98.  
  99. /*
  100.  * "Broadcasts" a message to all online instances.
  101.  */
  102.  
  103. void broadcast(unsigned char *sendstr)
  104. {
  105.   int i,ni;
  106.   instancerec ir;
  107.  
  108.   ni=num_instances();
  109.   for (i=1;i<=ni;i++) {
  110.     if (i==instance)
  111.       continue;
  112.     if (get_inst_info(i, &ir)) {
  113.       if (inst_available(&ir))
  114.         send_inst_str(i,sendstr);
  115.     }
  116.   }
  117. }
  118.  
  119. /****************************************************************************/
  120.  
  121. /*
  122.  * Handles one inter-instance message, based on type, returns inter-instance
  123.  * main type of the "packet".
  124.  */
  125.  
  126. int handle_inst_msg(inst_msg_header *ih, unsigned char *msg)
  127. {
  128.   unsigned short i;
  129.   char xl[81], cl[81], atr[81], cc;
  130.   userrec u;
  131.  
  132.   if ((!ih) || ((ih->msg_size>0) && (msg==NULL)))
  133.     return(-1);
  134.  
  135.   switch (ih->main) {
  136.     case INST_MSG_STRING:
  137.     case INST_MSG_SYSMSG:
  138.       if ((ih->msg_size>0) && useron && (!hangup)) {
  139.         savel(cl, atr, xl, &cc);
  140.         nln(2);
  141.         read_user(ih->from_user,&u);
  142.         if (ih->main==INST_MSG_STRING)
  143.           npr("1%.12s (%d)0> 2",nam(&u,ih->from_user), ih->from_inst);
  144.         else
  145.           outstr(get_string(1503));
  146.         i=0;
  147.         while (i<ih->msg_size)
  148.           outchr(msg[i++]);
  149.         nln(2);
  150.         restorel(cl, atr, xl, &cc);
  151.       }
  152.       break;
  153.     /* Handle this one in process_inst_msgs */
  154.     case INST_MSG_SHUTDOWN:
  155.     default:
  156.       break;
  157.   }
  158.   return(ih->main);
  159. }
  160.  
  161. /****************************************************************************/
  162.  
  163. void process_inst_msgs(void)
  164. {
  165.   int f1,done=0,hi;
  166.   unsigned char s1[81],*m;
  167.   inst_msg_header ih;
  168.   unsigned long l,l1=0L;
  169.   int oiia;
  170.   struct ffblk ff;
  171.  
  172.   if ((x_only) || (!inst_msg_waiting()))
  173.     return;
  174.  
  175.   last_iia=timer1();
  176.  
  177.   oiia=iia;
  178.   setiia(0);
  179.   m=NULL;
  180.   sprintf(s1,"%sMSG*.%3.3d",syscfg.datadir,instance);
  181.   done = findfirst(s1,&ff,0);
  182.   while ((done==0) && (!hangup)) {
  183.     sprintf(s1,"%s%s",syscfg.datadir,ff.ff_name);
  184.     f1=sh_open1(s1,O_RDONLY | O_BINARY);
  185.     if (f1==-1)
  186.       continue;
  187.     l=filelength(f1);
  188.     l1=0;
  189.     while (l1<l) {
  190.       m=NULL;
  191.       sh_read(f1,&ih,sizeof(inst_msg_header));
  192.       l1+=sizeof(inst_msg_header);
  193.       if (ih.msg_size>0) {
  194.         m=malloca(ih.msg_size);
  195.         if (m==NULL) {
  196.           break;
  197.         }
  198.         sh_read(f1,m,ih.msg_size);
  199.         l1+=ih.msg_size;
  200.       }
  201.       hi=handle_inst_msg(&ih,m);
  202.       if (m) {
  203.         bbsfree(m);
  204.         m=NULL;
  205.       }
  206.       if (hi==INST_MSG_SHUTDOWN) {
  207.         if (useron) {
  208.           tmp_disable_pause(1);
  209.           nln(2);
  210.           existprint("OFFLINE");
  211.           if (useron>0) {
  212.             if (usernum==1)
  213.               fwaiting=thisuser.waiting;
  214.             write_user(usernum,&thisuser);
  215.             write_qscn(usernum,qsc,0);
  216.           }
  217.           tmp_disable_pause(0);
  218.         }
  219.         sh_close(f1);
  220.         unlink(s1);
  221.         topline=0;
  222.         clrscrb();
  223.         hangup=1;
  224.         hang_it_up();
  225.         holdphone(0);
  226.         wait1(18);
  227.         end_bbs(QUIT_LEVEL);
  228.       }
  229.     }
  230.     sh_close(f1);
  231.     unlink(s1);
  232.     done=findnext(&ff);
  233.   }
  234.   setiia(oiia);
  235. }
  236.  
  237. /****************************************************************************/
  238.  
  239. void chat_room(void)
  240. {
  241.   int oiia=iia,toinst,ni,i,defun=-1,ti;
  242.   unsigned char cmsg[120],ts[120];
  243.   instancerec ir;
  244.   userrec u;
  245.  
  246.   if (thisuser.restrict & restrict_iichat) {
  247.     nl();
  248.     pl(get_string(1364));
  249.     return;
  250.   }
  251.  
  252.   tmp_disable_pause(1);
  253.  
  254.   if (menu_on())
  255.     printmenu(314);
  256.  
  257.   setiia(9);
  258.   helpl=44;
  259.   outchr(12);
  260.   pl(get_string(1164));
  261.   nl();
  262.  
  263.   while (!hangup) {
  264.     checkhangup();
  265.     if (inst_msg_waiting())
  266.       process_inst_msgs();
  267.     prt(2,":");
  268.     ansic(0);
  269.     inputl(cmsg,60);
  270.     if (cmsg[0]) {
  271.       if (stricmp(cmsg,"/q")==0) {
  272.         nl();
  273.         pl(get_string(1165));
  274.         nl();
  275.         break;
  276.       } else
  277.       if (stricmp(cmsg,"/w")==0) {
  278.         ni=num_instances();
  279.         setiia(0);
  280.         nl();
  281.         pl(get_string(1166));
  282.         for (i=1; i<=ni; i++) {
  283.           if (get_inst_info(i, &ir)) {
  284.             if (inst_available(&ir)) {
  285.               if ((ir.user < syscfg.maxusers) && (ir.user > 0)) {
  286.                 read_user(ir.user,&u);
  287.                 if ((u.sl<255) || (sysop1()) || so())
  288.                   npr("1%s %3d0: 9%s\r\n",
  289.                       get_string(1626),i,nam(&u,ir.user));
  290.               }
  291.             }
  292.           }
  293.         }
  294.         nl();
  295.         setiia(9);
  296.       } else {
  297.         if (!cmsg[0])
  298.           continue;
  299.         ti=wordcount(cmsg, DELIMS_WHITE);
  300.         if (ti>1) {
  301.           strncpy(ts,extractword(1,cmsg,DELIMS_WHITE),sizeof(ts));
  302.           ti=atoi(ts);
  303.           if (ti>0) {
  304.             if (get_inst_info(ti, &ir)) {
  305.               if (inst_available(&ir))
  306.                 defun=ti;
  307.               else {
  308.                 pl(get_string(1167));
  309.                 continue;
  310.               }
  311.             }
  312.             memmove(&cmsg[0],&cmsg[strlen(ts)+1],strlen(cmsg)-strlen(ts));
  313.           }
  314.         } else {
  315.           if (ti==1) {
  316.             strncpy(ts,extractword(1,cmsg,DELIMS_WHITE),sizeof(ts));
  317.             ti=atoi(ts);
  318.             if ((ti>0) && (ti!=instance)) {
  319.               defun=ti;
  320.               continue;
  321.             }
  322.           }
  323.         }
  324.         if (cmsg[0]=='\\') {
  325.           if (strlen(cmsg)>1)
  326.             broadcast(&cmsg[1]);
  327.         } else {
  328.           toinst=defun;
  329.           if (toinst<=0)
  330.             continue;
  331.           if (get_inst_info(toinst, &ir)) {
  332.             if (inst_available(&ir))
  333.               send_inst_str(toinst, cmsg);
  334.           }
  335.         }
  336.       }
  337.     }
  338.   }
  339.   setiia(oiia);
  340.   tmp_disable_pause(0);
  341.   cleared = NEEDCLEAR;
  342. }
  343.  
  344. /****************************************************************************/
  345.  
  346. /*
  347.  * Gets instancerec for specified instance, returns in ir.
  348.  */
  349.  
  350. int get_inst_info(int wi, instancerec *ir)
  351. {
  352.   char s[81];
  353.   int i, f;
  354.  
  355.   if (!ir)
  356.     return(0);
  357.  
  358.   memset(ir, 0, sizeof(instancerec));
  359.  
  360.   sprintf(s,"%sINSTANCE.DAT",syscfg.datadir);
  361.   f=sh_open1(s,O_RDONLY | O_BINARY);
  362.   if (f<0)
  363.     return(0);
  364.   i=(int)(filelength(f)/sizeof(instancerec));
  365.   if (i<(wi+1)) {
  366.     f=sh_close(f);
  367.     return(0);
  368.   }
  369.   sh_lseek(f,(long) (wi) * sizeof(instancerec),SEEK_SET);
  370.   sh_read(f,(void *)ir,sizeof(instancerec));
  371.   f=sh_close(f);
  372.   return(1);
  373. }
  374.  
  375. /****************************************************************************/
  376.  
  377. /*
  378.  * Returns 1 if inst_no has user online that can receive msgs, else 0
  379.  */
  380.  
  381. int inst_available(instancerec *ir)
  382. {
  383.   if (!ir)
  384.     return(0);
  385.  
  386.   if ((ir->flags & INST_FLAGS_ONLINE) && (ir->flags & INST_FLAGS_MSG_AVAIL))
  387.     return(1);
  388.   else
  389.     return(0);
  390. }
  391.  
  392. /****************************************************************************/
  393.  
  394. /*
  395.  * Returns 1 if inst_no has user online in chat, else 0
  396.  */
  397.  
  398. int inst_available_chat(instancerec *ir)
  399. {
  400.   if (!ir)
  401.     return(0);
  402.  
  403.   if ((ir->flags & INST_FLAGS_ONLINE) &&
  404.       (ir->flags & INST_FLAGS_MSG_AVAIL) &&
  405.       (ir->loc == INST_LOC_CHATROOM))
  406.     return(1);
  407.   else
  408.     return(0);
  409. }
  410.  
  411. /****************************************************************************/
  412.  
  413. /*
  414.  * Returns max instance number.
  415.  */
  416.  
  417. int num_instances(void)
  418. {
  419.   char s[81];
  420.   int i, f;
  421.  
  422.   sprintf(s,"%sINSTANCE.DAT",syscfg.datadir);
  423.   f=sh_open(s,O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
  424.   if (f<0)
  425.     return(0);
  426.   i=(int)(filelength(f)/sizeof(instancerec))-1;
  427.   f=sh_close(f);
  428.   return(i);
  429. }
  430.  
  431. /****************************************************************************/
  432.  
  433. /*
  434.  * Returns 1 if usernum un is online, and returns instance user is on in
  435.  * wi, else returns 0.
  436.  */
  437.  
  438. int user_online(int un, int *wi)
  439. {
  440.   int i, ni;
  441.   instancerec ir;
  442.  
  443.   ni=num_instances();
  444.   for (i=1;i<=ni;i++) {
  445.     if (i==instance)
  446.       continue;
  447.     get_inst_info(i, &ir);
  448.     if ((ir.user==un) && (ir.flags & INST_FLAGS_ONLINE)) {
  449.       if (wi)
  450.         *wi=i;
  451.       return(1);
  452.     }
  453.   }
  454.   if (wi)
  455.     *wi=-1;
  456.   return(0);
  457. }
  458.  
  459. /****************************************************************************/
  460.  
  461. /*
  462.  * Allows sending some types of messages to other instances, or simply
  463.  * viewing the status of the other instances.
  464.  */
  465.  
  466. void instance_edit(void)
  467. {
  468.   int done=0,ni,i;
  469.   unsigned char ch, s[81];
  470.   instancerec ir;
  471.  
  472.   if (!checkpw())
  473.     return;
  474.  
  475.   ni=num_instances();
  476.  
  477.   while ((!done) && (!hangup)) {
  478.     checkhangup();
  479.     nl();
  480.     pl(get_string(1411));
  481.     pl(get_string(1412));
  482.     pl(get_string(1413));
  483.     pl(get_string(1414));
  484.     nl();
  485.     ansic(1);
  486.     outstr(get_string(1385));
  487.     ch=onek("Q123");
  488.     switch (ch) {
  489.       case '1':
  490.         nl();
  491.         ansic(1);
  492.         pl(get_string(1415));
  493.         multi_instance();
  494.         break;
  495.       case '2':
  496.         nl();
  497.         ansic(2);
  498.         outstr(get_string(1416));
  499.         mpl(3);
  500.         input(s,3);
  501.         if (!s[0])
  502.           break;
  503.         i=atoi(s);
  504.         if ((!i) || (i>ni)) {
  505.           nl();
  506.           ansic(6);
  507.           pl(get_string(1417));
  508.           break;
  509.         }
  510.         if (i==instance) {
  511.           topline=0;
  512.           clrscrb();
  513.           hangup=1;
  514.           hang_it_up();
  515.           holdphone(0);
  516.           wait1(18);
  517.           end_bbs(QUIT_LEVEL);
  518.           break;
  519.         }
  520.         if (get_inst_info(i,&ir)) {
  521.           if (ir.loc!=INST_LOC_DOWN) {
  522.             nl();
  523.             ansic(2);
  524.             npr("%s%d",get_string(1418),i);
  525.             nl();
  526.             send_inst_shutdown(i);
  527.           } else {
  528.             nl();
  529.             ansic(6);
  530.             pl(get_string(1419));
  531.           }
  532.         } else {
  533.           nl();
  534.           ansic(6);
  535.           pl(get_string(1417));
  536.         }
  537.         break;
  538.       case '3':
  539.         nl();
  540.         ansic(5);
  541.         outstr(get_string(465));
  542.         if (yn()) {
  543.           nl();
  544.           ansic(2);
  545.           pl(get_string(1420));
  546.           for (i=1;i<=ni;i++) {
  547.             if (i!=instance) {
  548.               if (get_inst_info(i, &ir))
  549.                 if (ir.loc != INST_LOC_DOWN)
  550.                   send_inst_shutdown(i);
  551.             }
  552.           }
  553.           topline=0;
  554.           clrscrb();
  555.           hangup=1;
  556.           hang_it_up();
  557.           holdphone(0);
  558.           wait1(18);
  559.           end_bbs(QUIT_LEVEL);
  560.         }
  561.         break;
  562.       case 'Q':
  563.       default:
  564.         done=1;
  565.         break;
  566.     }
  567.   }
  568. }
  569.