home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / SUBEDIT.C < prev    next >
C/C++ Source or Header  |  1995-04-25  |  21KB  |  817 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.  
  15.  
  16.  
  17. #include "vars.h"
  18.  
  19. #pragma hdrstop
  20.  
  21. #include "subxtr.h"
  22.  
  23.  
  24. void save_subs(void)
  25. {
  26.   char s[100],s1[100],s2[100];
  27.   int f,i,i1,i2,onn;
  28.   FILE *fp, *al, *su, *nn;
  29.   xtrasubsnetrec *xnp;
  30.  
  31.   onn=net_num;
  32.  
  33.   for (i=0; i<num_subs; i++) {
  34.     subboards[i].type=0;
  35.     subboards[i].age &= 0x7f;
  36.     if (status.net_version<32) {
  37.       if (xsubs[i].num_nets) {
  38.         subboards[i].type=xsubs[i].nets[0].type;
  39.         subboards[i].age |= 0x80;
  40.         subboards[i].name[40]=xsubs[i].nets[0].net_num;
  41.         subboards[i].name[39]=0;
  42.       }
  43.     }
  44.   }
  45.  
  46.   sprintf(s,"%sSUBS.DAT",syscfg.datadir);
  47.   f=sh_open(s,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  48.   if (f<0) {
  49.     pl(get_string(164));
  50.     pausescr();
  51.   } else {
  52.     i=sh_write(f,(void *)&subboards[0], num_subs * sizeof(subboardrec));
  53.     if (i!=(num_subs*sizeof(subboardrec))) {
  54.       pl(get_string(165));
  55.       pausescr();
  56.     }
  57.     sh_close(f);
  58.   }
  59.  
  60.   sprintf(s,"%sSUBS.XTR",syscfg.datadir);
  61.   unlink(s);
  62.   fp=fsh_open(s,"w");
  63.   if (fp) {
  64.     for (i=0; i<num_subs; i++) {
  65.       if (xsubs[i].num_nets) {
  66.         fprintf(fp,"!%u\n@%s\n#%lu\n",i,
  67.           xsubs[i].desc,(xsubs[i].flags&XTRA_MASK));
  68.         for (i1=0; i1<xsubs[i].num_nets; i1++) {
  69.           fprintf(fp,"$%s %s %lu %u %u\n",
  70.             net_networks[xsubs[i].nets[i1].net_num].name,
  71.             xsubs[i].nets[i1].stype,
  72.             xsubs[i].nets[i1].flags,
  73.             xsubs[i].nets[i1].host,
  74.             xsubs[i].nets[i1].category);
  75.         }
  76.       }
  77.     }
  78.     fsh_close(fp);
  79.   }
  80.  
  81.   for (i=0; i<net_num_max; i++) {
  82.     set_net_num(i);
  83.  
  84.     sprintf(s,"%sALLOW.NET", net_data); unlink(s);
  85.     sprintf(s1,"%sSUBS.PUB", net_data); unlink(s1);
  86.     sprintf(s2,"%sNNALL.NET", net_data); unlink(s2);
  87.  
  88.     if (status.net_version<32) {
  89.       al=su=nn=NULL;
  90.       for (i1=0; i1<num_subs; i1++) {
  91.         for (i2=0,xnp=xsubs[i1].nets; i2<xsubs[i1].num_nets; i2++,xnp++) {
  92.           if (xnp->net_num==net_num) {
  93.             if (xnp->flags & XTRA_NET_AUTO_ADDDROP) {
  94.               if (!al)
  95.                 al=fsh_open(s,"w");
  96.               if (al)
  97.                 fprintf(al,"%s\n",xnp->stype);
  98.             }
  99.             if (xnp->flags & XTRA_NET_AUTO_INFO) {
  100.               if (!su)
  101.                 su=fsh_open(s1,"w");
  102.               if (s)
  103.                 fprintf(su,"%s\n",xnp->stype);
  104.             }
  105.             if (xnp->host) {
  106.               if (!nn)
  107.                 nn=fsh_open(s2,"w");
  108.               if (nn)
  109.                 fprintf(nn,"%-7s %-6u          %s\n",xnp->stype, xnp->host,
  110.                         xsubs[i1].desc?xsubs[i1].desc:subboards[i1].name);
  111.             }
  112.           }
  113.         }
  114.       }
  115.       if (al) fsh_close(al);
  116.       if (su) fsh_close(su);
  117.       if (nn) fsh_close(nn);
  118.     }
  119.   }
  120.  
  121.   set_net_num(onn);
  122. }
  123.  
  124. /****************************************************************************/
  125.  
  126. void boarddata(int n, char *s)
  127. {
  128.   char x,y,k,i;
  129.   subboardrec r;
  130.  
  131.   r=subboards[n];
  132.   if (r.ar==0)
  133.     x=32;
  134.   else {
  135.     for (i=0; i<16; i++)
  136.       if ((1 << i) & r.ar)
  137.         x='A'+i;
  138.   }
  139.   switch(r.anony & 0x0f) {
  140.     case 0: y='N'; break;
  141.     case anony_enable_anony: y='Y'; break;
  142.     case anony_enable_dear_abby: y='D'; break;
  143.     case anony_force_anony: y='F'; break;
  144.     case anony_real_name: y='R'; break;
  145.   }
  146.   if (r.key==0)
  147.     k=32;
  148.   else
  149.     k=r.key;
  150.   sprintf(s,"%4d %1c  %-37.37s %-8s %-3d %-3d %-2d %-5d %7s",
  151.             n,x,stripcolors(r.name),r.filename,r.readsl,r.postsl,r.age&0x7f,
  152.             r.maxmsgs,xsubs[n].num_nets?xsubs[n].nets[0].stype:"");
  153.   x=k; x=y; /* leave in old code but ignore warning */
  154. }
  155.  
  156. void showsubs(void)
  157. {
  158.   int abort,i;
  159.   char s[180];
  160.  
  161.   outchr(12);
  162.   abort=0;
  163.   pla(get_string(166),
  164.       &abort);
  165.   pla(get_string(167),
  166.       &abort);
  167.   for (i=0; (i<num_subs) && (!abort); i++) {
  168.     subboards[i].anony &= ~anony_require_sv;
  169.     boarddata(i,s);
  170.     pla(s,&abort);
  171.   }
  172. }
  173.  
  174.  
  175.  
  176. void modify_sub(int n)
  177. {
  178.   subboardrec r;
  179.   char s[81],s1[81],s2[81],ch,ch2,ch3;
  180.   int i,done;
  181.   xtrasubsnetrec *xnp;
  182.  
  183.   r=subboards[n];
  184.   done=0;
  185.   do {
  186.     outchr(12);
  187.     outstr(get_string(62)); pl(r.name);
  188.     outstr(get_string(63)); pl(r.filename);
  189.     if (r.key==0)
  190.       strcpy(s,get_string(168));
  191.     else {
  192.       s[0]=r.key;
  193.       s[1]=0;
  194.     }
  195.     outstr(get_string(169)); pl(s);
  196.     outstr(get_string(170)); pln(r.readsl);
  197.     outstr(get_string(171)); pln(r.postsl);
  198.     switch(r.anony & 0x0f) {
  199.       case 0: strcpy(s,str_no); break;
  200.       case anony_enable_anony: strcpy(s,str_yes); break;
  201.       case anony_enable_dear_abby: strcpy(s,get_string(172)); break;
  202.       case anony_force_anony: strcpy(s,get_string(173)); break;
  203.       case anony_real_name: strcpy(s,get_string(174)); break;
  204.       default: strcpy(s,get_string(175)); break;
  205.     }
  206.     outstr(get_string(176)); pl(s);
  207.     outstr(get_string(177)); pln(r.age&0x7f);
  208.     outstr(get_string(178)); pln(r.maxmsgs);
  209.     strcpy(s,get_string(5));
  210.     if (r.ar!=0) {
  211.       for (i=0; i<16; i++)
  212.         if ((1 << i) & r.ar)
  213.           s[0]='A'+i;
  214.       s[1]=0;
  215.     }
  216.     outstr(get_string(179)); pl(s);
  217.     outstr(get_string(180));
  218.     if (xsubs[n].num_nets) {
  219.       npr("\r\n      %-12.12s %-7.7s %-6.6s  %s\r\n",
  220.           get_string(181), get_string(182), get_string(183), get_string(184));
  221.       for (i=0,xnp=xsubs[n].nets; i<xsubs[n].num_nets; i++,xnp++) {
  222.         if (xnp->host==0)
  223.           strcpy(s,get_string(185));
  224.         else
  225.           sprintf(s,"%u ",xnp->host);
  226.         if (xnp->category)
  227.           sprintf(s1,"%s(%d)",get_string(187),xnp->category);
  228.         else
  229.           strcpy(s1,get_string(187));
  230.         npr("   %c) %-12.12s %-7.7s %-6.6s  %s%s\r\n",
  231.             i+'a',
  232.             net_networks[xnp->net_num].name,
  233.             xnp->stype,
  234.             s,
  235.             (xnp->flags&XTRA_NET_AUTO_ADDDROP)?get_string(186):"",
  236.             (xnp->flags&XTRA_NET_AUTO_INFO)?s1:"");
  237.       }
  238.     } else {
  239.       pl(get_string(188));
  240.     }
  241.  
  242.     outstr(get_string(189)); pln(r.storage_type);
  243.     outstr(get_string(190)); pl((r.anony & anony_val_net)?str_yes:str_no);
  244.     outstr(get_string(191)); pl((r.anony & anony_ansi_only)?str_yes:str_no);
  245.     outstr(get_string(192)); pl((r.anony & anony_no_tag)?str_yes:str_no);
  246.     outstr(get_string(193)); pl((xsubs[n].desc[0])?xsubs[n].desc:get_string(5));
  247.     nl();
  248.     prt(2,get_string(194));
  249.     ch=onek("QABCDEFGHIJKLMNO[]");
  250.     switch(ch) {
  251.       case 'Q':done=1; break;
  252.       case '[':
  253.         subboards[n]=r;
  254.         if (--n<0)
  255.           n=num_subs-1;
  256.         r=subboards[n];
  257.         break;
  258.       case ']':
  259.         subboards[n]=r;
  260.         if (++n>=num_subs)
  261.           n=0;
  262.         r=subboards[n];
  263.         break;
  264.       case 'A':
  265.         nl();
  266.         prt(2,get_string(69));
  267.         if (status.net_version<32)
  268.           inputl(s,39);
  269.         else
  270.           inputl(s,40);
  271.         if (s[0])
  272.           strcpy(r.name,s);
  273.         break;
  274.       case 'B':
  275.         nl();
  276.         prt(2,get_string(72));
  277.         inputf(s,8);
  278.         if ((s[0]!=0) && (strchr(s,'.')==0)) {
  279.           sprintf(s2,"%s",r.filename);
  280.           strcpy(r.filename,s);
  281.           sprintf(s,"%s%s.SUB",syscfg.datadir,r.filename);
  282.           sprintf(s1,"%s%s.DAT",syscfg.msgsdir,r.filename);
  283.           if ((r.storage_type==2) && (!exist(s)) && (!exist(s1)) &&
  284.             (strcmp(r.filename,"NONAME")!=0)) {
  285.             prt(2,get_string(973));
  286.             if (yn()) {
  287.               sprintf(s,"%s%s.SUB",syscfg.datadir,s2);
  288.               sprintf(s1,"%s%s.SUB",syscfg.datadir,r.filename);
  289.               rename(s,s1);
  290.               sprintf(s,"%s%s.DAT",syscfg.msgsdir,s2);
  291.               sprintf(s1,"%s%s.DAT",syscfg.msgsdir,r.filename);
  292.               rename(s,s1);
  293.             }
  294.           }
  295.         }
  296.         break;
  297.       case 'C':
  298.         nl();
  299.         prt(2,get_string(195));
  300.         ch2=onek("@%^&()_=\\|;:'\",` ");
  301.         if (ch2==32)
  302.           r.key=0;
  303.         else
  304.           r.key=ch2;
  305.         break;
  306.       case 'D':
  307.         nl();
  308.         prt(2,get_string(196));
  309.         input(s,3);
  310.         i=atoi(s);
  311.         if ((i>=0) && (i<256) && (s[0]))
  312.           r.readsl=i;
  313.         break;
  314.       case 'E':
  315.         nl();
  316.         prt(2,get_string(197));
  317.         input(s,3);
  318.         i=atoi(s);
  319.         if ((i>=0) && (i<256) && (s[0]))
  320.           r.postsl=i;
  321.         break;
  322.       case 'F':
  323.         nl();
  324.         prt(2,get_string(198));
  325.         strcpy(s,"NYDFR");
  326.         s[0]=str_no[0];
  327.         s[1]=str_yes[0];
  328.         ch2=onek(s);
  329.         if (ch2==str_no[0])
  330.           ch2=0;
  331.         else if (ch2==str_yes[0])
  332.           ch2=1;
  333.         r.anony &= 0xf0;
  334.         switch(ch2) {
  335.           case 0: break;
  336.           case 1: r.anony |= anony_enable_anony; break;
  337.           case 'D': r.anony |= anony_enable_dear_abby; break;
  338.           case 'F': r.anony |= anony_force_anony; break;
  339.           case 'R': r.anony |= anony_real_name; break;
  340.         }
  341.         break;
  342.       case 'G':
  343.         nl();
  344.         prt(2,get_string(77));
  345.         input(s,3);
  346.         i=atoi(s);
  347.         if ((i>=0) && (i<128) && (s[0]))
  348.           r.age=(r.age&0x80)|(i&0x7f);
  349.         break;
  350.       case 'H':
  351.         nl();
  352.         prt(2,get_string(199));
  353.         input(s,5);
  354.         i=atoi(s);
  355.  
  356.         if (i>254) {
  357.           if ((status.net_version<34) && (xsubs[n].num_nets)) {
  358.             pl(get_string(1433));
  359.             pausescr();
  360.             break;
  361.           }
  362.         }
  363.  
  364.         if ((i>0) && (i<16384) && (s[0])) {
  365.           r.maxmsgs=i;
  366.         }
  367.         break;
  368.       case 'I':
  369.         nl();
  370.         prt(2,get_string(80));
  371.         ch2=onek("ABCDEFGHIJKLMNOP ");
  372.         if (ch2==32)
  373.           r.ar=0;
  374.         else
  375.           r.ar=1 << (ch2-'A');
  376.         break;
  377.       case 'J':
  378.         subboards[n]=r;
  379.         if (xsubs[n].num_nets) {
  380.           nl();
  381.           prt(2,get_string(200));
  382.           ch2=onek("QAMD");
  383.         } else
  384.           ch2='A';
  385.  
  386.         if (ch2=='A') {
  387.           if ((status.net_version<32) && (xsubs[n].num_nets)) {
  388.             nl();
  389.             pl(get_string(201));
  390.             nl();
  391.             pausescr();
  392.           } else if ((status.net_version<34) && (r.maxmsgs>254)) {
  393.             nl();
  394.             pl(get_string(1433));
  395.             pl(get_string(1434));
  396.             nl();
  397.             pausescr();
  398.           } else
  399.             sub_xtr_add(n, -1);
  400.         } else if ((ch2=='D') || (ch2=='M')) {
  401.           nl();
  402.           ansic(2);
  403.           if (ch2=='D')
  404.             outstr(get_string(202));
  405.           else
  406.             outstr(get_string(203));
  407.           npr("%c",'a'+xsubs[n].num_nets-1);
  408.           outstr(get_string(204));
  409.           s[0]=' ';
  410.           for (i=0; i<xsubs[n].num_nets; i++)
  411.             s[i+1]='A'+i;
  412.           s[i+1]=0;
  413.           ansic(0);
  414.           ch3=onek(s);
  415.           if (ch3!=' ') {
  416.             i=ch3-'A';
  417.             if ((i>=0) && (i<xsubs[n].num_nets)) {
  418.               if (ch2=='D') {
  419.                 sub_xtr_del(n, i, 1);
  420.               } else {
  421.                 sub_xtr_del(n, i, 0);
  422.                 sub_xtr_add(n, i);
  423.               }
  424.             }
  425.           }
  426.         }
  427.         r=subboards[n];
  428.         break;
  429.       case 'K':
  430.         nl();
  431.         prt(2,get_string(205));
  432.         input(s,4);
  433.         i=atoi(s);
  434.         if ((s[0]) && (i>=0) && (i<=2))
  435.           r.storage_type=i;
  436.         break;
  437.       case 'L':
  438.         nl();
  439.         prt(5,get_string(206));
  440.         r.anony &= ~anony_val_net;
  441.         if (yn())
  442.           r.anony |= anony_val_net;
  443.         break;
  444.       case 'M':
  445.         nl();
  446.         prt(5,get_string(207));
  447.         r.anony &= ~anony_ansi_only;
  448.         if (yn())
  449.           r.anony |= anony_ansi_only;
  450.         break;
  451.       case 'N':
  452.         nl();
  453.         prt(5,get_string(208));
  454.         r.anony &= ~anony_no_tag;
  455.         if (yn())
  456.           r.anony |= anony_no_tag;
  457.         break;
  458.       case 'O':
  459.         nl();
  460.         prt(2,get_string(209));
  461.         inputl(s,60);
  462.         if (s[0])
  463.           strcpy(xsubs[n].desc,s);
  464.         else {
  465.           nl();
  466.           prt(2,get_string(994));
  467.           if (yn())
  468.             xsubs[n].desc[0]=0;
  469.         }
  470.         break;
  471.     }
  472.   } while ((!done) && (!hangup));
  473.   subboards[n]=r;
  474. }
  475.  
  476.  
  477. void swap_subs(int sub1, int sub2)
  478. {
  479.   int i,i1,i2,nu;
  480.   unsigned long *qsc, *qsc_p, *qsc_n, *qsc_q, tl;
  481.   subboardrec sbt;
  482.   xtrasubsrec xst;
  483.   SUBCONF_TYPE sub1conv,sub2conv;
  484.  
  485.   sub1conv=(SUBCONF_TYPE) sub1;
  486.   sub2conv=(SUBCONF_TYPE) sub2;
  487.  
  488.   if ((sub1<0) || (sub1>=num_subs) || (sub2<0) || (sub2>=num_subs))
  489.     return;
  490.  
  491.   update_conf(CONF_SUBS, &sub1conv, &sub2conv, CONF_UPDATE_SWAP);
  492.  
  493.   sub1=(int) sub1conv;
  494.   sub2=(int) sub2conv;
  495.  
  496.   nu=number_userrecs();
  497.  
  498.   qsc=(unsigned long *)malloca(syscfg.qscn_len);
  499.   if (qsc) {
  500.     for (i=1; i<=nu; i++) {
  501.       read_qscn(i,qsc,1);
  502.       qsc_n=qsc+1;
  503.       qsc_q=qsc_n+(max_dirs+31)/32;
  504.       qsc_p=qsc_q+(max_subs+31)/32;
  505.  
  506.       if (qsc_q[sub1/32] & (1L<<(sub1%32)))
  507.         i1=1;
  508.       else
  509.         i1=0;
  510.       if (qsc_q[sub2/32] & (1L<<(sub2%32)))
  511.         i2=1;
  512.       else
  513.         i2=0;
  514.       if (i1+i2==1) {
  515.         qsc_q[sub1/32] ^= (1L<<(sub1%32));
  516.         qsc_q[sub2/32] ^= (1L<<(sub2%32));
  517.       }
  518.  
  519.       tl=qsc_p[sub1];
  520.       qsc_p[sub1]=qsc_p[sub2];
  521.       qsc_p[sub2]=tl;
  522.  
  523.       write_qscn(i,qsc,1);
  524.     }
  525.     close_qscn();
  526.     bbsfree(qsc);
  527.   }
  528.  
  529.   sbt=subboards[sub1];
  530.   subboards[sub1]=subboards[sub2];
  531.   subboards[sub2]=sbt;
  532.  
  533.   tl=sub_dates[sub1];
  534.   sub_dates[sub1]=sub_dates[sub2];
  535.   sub_dates[sub2]=tl;
  536.  
  537.   xst=xsubs[sub1];
  538.   xsubs[sub1]=xsubs[sub2];
  539.   xsubs[sub2]=xst;
  540.  
  541.   save_subs();
  542. }
  543.  
  544.  
  545. void insert_sub(int n)
  546. {
  547.   subboardrec r;
  548.   int i,i1,i2,nu;
  549.   unsigned long *qsc, *qsc_n, *qsc_q, *qsc_p, m1, m2, m3;
  550.   SUBCONF_TYPE nconv;
  551.  
  552.   nconv=(SUBCONF_TYPE) n;
  553.  
  554.   if ((n<0) || (n>num_subs))
  555.     return;
  556.  
  557.   update_conf(CONF_SUBS, &nconv, NULL, CONF_UPDATE_INSERT);
  558.  
  559.   n=(int) nconv;
  560.  
  561.   for (i=num_subs-1; i>=n; i--) {
  562.     subboards[i+1]=subboards[i];
  563.     sub_dates[i+1]=sub_dates[i];
  564.     xsubs[i+1]=xsubs[i];
  565.   }
  566.   strcpy(r.name,get_string(210));
  567.   strcpy(r.filename,get_string(82));
  568.   r.key=0;
  569.   r.readsl=10;
  570.   r.postsl=20;
  571.   r.anony=0;
  572.   r.age=0;
  573.   r.maxmsgs=50;
  574.   r.ar=0;
  575.   r.type=0;
  576.   r.storage_type=2;
  577.   subboards[n]=r;
  578.   memset((void *) &(xsubs[n]),0, sizeof(xtrasubsrec));
  579.   ++num_subs;
  580.   nu=number_userrecs();
  581.  
  582.   qsc=(unsigned long *)malloca(syscfg.qscn_len);
  583.   if (qsc) {
  584.     qsc_n=qsc+1;
  585.     qsc_q=qsc_n+(max_dirs+31)/32;
  586.     qsc_p=qsc_q+(max_subs+31)/32;
  587.  
  588.     m1=1L<<(n%32);
  589.     m2=0xffffffff<<((n%32)+1);
  590.     m3=0xffffffff>>(32-(n%32));
  591.  
  592.     for (i=1; i<=nu; i++) {
  593.       read_qscn(i,qsc, 1);
  594.  
  595.       if ((*qsc!=999) && (*qsc>=n))
  596.         (*qsc)++;
  597.  
  598.       for (i1=num_subs-1; i1>n; i1--)
  599.         qsc_p[i1]=qsc_p[i1-1];
  600.       qsc_p[n]=0;
  601.  
  602.       for (i2=num_subs/32; i2>n/32; i2--) {
  603.         qsc_q[i2]=(qsc_q[i2]<<1) | (qsc_q[i2-1]>>31);
  604.       }
  605.       qsc_q[i2]=m1 | (m2 & (qsc_q[i2]<<1)) | (m3 & qsc_q[i2]);
  606.  
  607.       write_qscn(i,qsc,1);
  608.     }
  609.     close_qscn();
  610.     bbsfree(qsc);
  611.   }
  612.  
  613.   save_subs();
  614.  
  615.   if (curlsub>=n)
  616.     curlsub++;
  617. }
  618.  
  619.  
  620. void delete_sub(int n)
  621. {
  622.   int i,i1,i2,nu;
  623.   unsigned long *qsc, *qsc_n, *qsc_q, *qsc_p, m2, m3;
  624.   SUBCONF_TYPE nconv;
  625.  
  626.   nconv=(SUBCONF_TYPE) n;
  627.  
  628.   if ((n<0) || (n>=num_subs))
  629.     return;
  630.  
  631.   update_conf(CONF_SUBS, &nconv, NULL, CONF_UPDATE_DELETE);
  632.  
  633.   n=(int) nconv;
  634.  
  635.   while (xsubs[n].num_nets)
  636.     sub_xtr_del(n, 0, 1);
  637.   if ((xsubs[n].nets) && (xsubs[n].flags & XTRA_MALLOCED))
  638.     bbsfree(xsubs[n].nets);
  639.  
  640.   for (i=n; i<num_subs; i++) {
  641.     subboards[i]=subboards[i+1];
  642.     sub_dates[i]=sub_dates[i+1];
  643.     xsubs[i]=xsubs[i+1];
  644.   }
  645.   --num_subs;
  646.   nu=number_userrecs();
  647.  
  648.   qsc=(unsigned long *)malloca(syscfg.qscn_len+4);
  649.   if (qsc) {
  650.     qsc_n=qsc+1;
  651.     qsc_q=qsc_n+(max_dirs+31)/32;
  652.     qsc_p=qsc_q+(max_subs+31)/32;
  653.  
  654.     m2=0xffffffff<<(n%32);
  655.     m3=0xffffffff>>(32-(n%32));
  656.  
  657.     for (i=1; i<=nu; i++) {
  658.       read_qscn(i,qsc, 1);
  659.  
  660.       if (*qsc!=999) {
  661.         if (*qsc==n)
  662.           *qsc=999;
  663.         else if (*qsc>n)
  664.           (*qsc)--;
  665.       }
  666.  
  667.       for (i1=n; i1<num_subs; i1++)
  668.         qsc_p[i1]=qsc_p[i1+1];
  669.  
  670.       qsc_q[n/32]=(qsc_q[n/32]&m3) | ((qsc_q[n/32]>>1)&m2) |
  671.                   (qsc_q[(n/32)+1]<<31);
  672.  
  673.       for (i2=(n/32)+1; i2<=(num_subs/32); i2++) {
  674.         qsc_q[i2]=(qsc_q[i2]>>1) | (qsc_q[i2+1]<<31);
  675.       }
  676.  
  677.       write_qscn(i,qsc,1);
  678.     }
  679.     close_qscn();
  680.     bbsfree(qsc);
  681.   }
  682.  
  683.   save_subs();
  684.  
  685.   if (curlsub==n)
  686.     curlsub=-1;
  687.   else if (curlsub>n)
  688.     curlsub--;
  689. }
  690.  
  691.  
  692. void boardedit(void)
  693. {
  694.   int i,i1,i2,done, confchg=0;
  695.   char s[81],s1[81],ch;
  696.   SUBCONF_TYPE iconv;
  697.  
  698.   if (!checkpw())
  699.     return;
  700.   showsubs();
  701.   done=0;
  702.   read_status();
  703.   do {
  704.     nl();
  705.     prt(2,get_string(211));
  706.     ch=onek("QSDIM?");
  707.     switch(ch) {
  708.       case '?':
  709.         showsubs();
  710.         break;
  711.       case 'Q':
  712.         done=1;
  713.         break;
  714.       case 'M':
  715.         nl();
  716.         prt(2,get_string(212));
  717.         input(s,4);
  718.         i=atoi(s);
  719.         if ((s[0]!=0) && (i>=0) && (i<num_subs))
  720.           modify_sub(i);
  721.         break;
  722.       case 'S':
  723.         if (num_subs<max_subs) {
  724.           nl();
  725.           prt(2,get_string(1275));
  726.           input(s,4);
  727.           i1=atoi(s);
  728.           if ((!s[0]) || (i1<0) || (i1>=num_subs))
  729.             break;
  730.           nl();
  731.           prt(2,get_string(1276));
  732.           input(s,4);
  733.           i2=atoi(s);
  734.           if ((!s[0]) || (i2<0) || (i2%32==0) || (i2>num_subs) ||
  735.              (i1==i2) || (i1+1==i2))
  736.             break;
  737.           nl();
  738.           if (i2<i1)
  739.             i1++;
  740.           write_qscn(usernum,qsc,1);
  741.           prt(1,get_string(1277));
  742.           insert_sub(i2);
  743.           swap_subs(i1,i2);
  744.           delete_sub(i1);
  745.           confchg=1;
  746.           showsubs();
  747.         } else {
  748.           nl();
  749.           pl(get_string(1278));
  750.         }
  751.         break;
  752.       case 'I':
  753.         if (num_subs<max_subs) {
  754.           nl();
  755.           prt(2,get_string(213));
  756.           input(s,4);
  757.           i=atoi(s);
  758.           if ((s[0]!=0) && (i>=0) && (i<=num_subs)) {
  759.             insert_sub(i);
  760.             modify_sub(i);
  761.             confchg=1;
  762.             if (subconfnum>1) {
  763.               nl();
  764.              list_confs(CONF_SUBS,0);
  765.               i2=select_conf(get_string(1160),CONF_SUBS, 0);
  766.               if (i2>=0)
  767.                 if (in_conference(i,&subconfs[i2])<0) {
  768.                   iconv=(SUBCONF_TYPE) i;
  769.                   addsubconf(CONF_SUBS, &subconfs[i2], &iconv);
  770.                   i=(int) iconv;
  771.                 }
  772.             } else {
  773.               if (in_conference(i,&subconfs[0])<0) {
  774.                 iconv=(SUBCONF_TYPE) i;
  775.                 addsubconf(CONF_SUBS, &subconfs[0], &iconv);
  776.                 i=(int) iconv;
  777.               }
  778.             }
  779.           }
  780.         }
  781.         break;
  782.       case 'D':
  783.         nl();
  784.         prt(2,get_string(214));
  785.         input(s,4);
  786.         i=atoi(s);
  787.         if ((s[0]!=0) && (i>=0) && (i<num_subs)) {
  788.           nl();
  789.           sprintf(s1,"%s %s? ",get_string(215), subboards[i].name);
  790.           prt(5,s1);
  791.           if (yn()) {
  792.             strcpy(s,subboards[i].filename);
  793.             delete_sub(i);
  794.             confchg=1;
  795.             nl();
  796.             prt(5,get_string(216));
  797.             if (yn()) {
  798.               sprintf(s1,"%s%s.SUB",syscfg.datadir, s);
  799.               unlink(s1);
  800.               sprintf(s1,"%s%s.DAT",syscfg.msgsdir,s);
  801.               unlink(s1);
  802.             }
  803.           }
  804.         }
  805.         break;
  806.     }
  807.   } while ((!done) && (!hangup));
  808.   save_subs();
  809.   if (!wfc)
  810.     changedsl();
  811.   subchg=1;
  812.   gatfn[0]=0;
  813.   if (confchg)
  814.     save_confs(CONF_SUBS, -1, NULL);
  815. }
  816.  
  817.