home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / SCFG / SCFGMSG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  37.3 KB  |  1,338 lines

  1. #line 2 "SCFGMSG.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. #include "scfg.h"
  6.  
  7. /****************************************************************************/
  8. /* Converts when_t.zone into ASCII format                                    */
  9. /****************************************************************************/
  10. char *zonestr(short zone)
  11. {
  12.     static char str[32];
  13.  
  14. switch((ushort)zone) {
  15.     case 0:     return("UT");
  16.     case AST:    return("AST");
  17.     case EST:    return("EST");
  18.     case CST:    return("CST");
  19.     case MST:    return("MST");
  20.     case PST:    return("PST");
  21.     case YST:    return("YST");
  22.     case HST:    return("HST");
  23.     case BST:    return("BST");
  24.     case ADT:    return("ADT");
  25.     case EDT:    return("EDT");
  26.     case CDT:    return("CDT");
  27.     case MDT:    return("MDT");
  28.     case PDT:    return("PDT");
  29.     case YDT:    return("YDT");
  30.     case HDT:    return("HDT");
  31.     case BDT:    return("BDT");
  32.     case MID:    return("MID");
  33.     case VAN:    return("VAN");
  34.     case EDM:    return("EDM");
  35.     case WIN:    return("WIN");
  36.     case BOG:    return("BOG");
  37.     case CAR:    return("CAR");
  38.     case RIO:    return("RIO");
  39.     case FER:    return("FER");
  40.     case AZO:    return("AZO");
  41.     case LON:    return("LON");
  42.     case BER:    return("BER");
  43.     case ATH:    return("ATH");
  44.     case MOS:    return("MOS");
  45.     case DUB:    return("DUB");
  46.     case KAB:    return("KAB");
  47.     case KAR:    return("KAR");
  48.     case BOM:    return("BOM");
  49.     case KAT:    return("KAT");
  50.     case DHA:    return("DHA");
  51.     case BAN:    return("BAN");
  52.     case HON:    return("HON");
  53.     case TOK:    return("TOK");
  54.     case SYD:    return("SYD");
  55.     case NOU:    return("NOU");
  56.     case WEL:    return("WEL");
  57.     }
  58.  
  59. sprintf(str,"%02hd:%02hu",zone/60,zone<0 ? (-zone)%60 : zone%60);
  60. return(str);
  61. }
  62.  
  63. char *utos(char *str)
  64. {
  65.     static char out[128];
  66.     int i;
  67.  
  68. for(i=0;str[i];i++)
  69.     if(str[i]=='_')
  70.         out[i]=SP;
  71.     else
  72.         out[i]=str[i];
  73. out[i]=0;
  74. return(out);
  75. }
  76.  
  77. char *stou(char *str)
  78. {
  79.     static char out[128];
  80.     int i;
  81.  
  82. for(i=0;str[i];i++)
  83.     if(str[i]==SP)
  84.         out[i]='_';
  85.     else
  86.         out[i]=str[i];
  87. out[i]=0;
  88. return(out);
  89. }
  90.  
  91.  
  92.  
  93. void clearptrs(int subnum)
  94. {
  95.     char str[256];
  96.     ushort idx,ch;
  97.     int last,file,i;
  98.     long l=0L;
  99.     struct ffblk ff;
  100.  
  101. upop("Clearing Pointers...");
  102. sprintf(str,"%sUSER\\PTRS\\*.IXB",data_dir);
  103. last=findfirst(str,&ff,0);
  104. while(!last) {
  105.     if(ff.ff_fsize>=((long)sub[subnum]->ptridx+1L)*10L) {
  106.         sprintf(str,"%sUSER\\PTRS\\%s",data_dir,ff.ff_name);
  107.         if((file=nopen(str,O_WRONLY))==-1) {
  108.             errormsg(WHERE,ERR_OPEN,str,O_WRONLY);
  109.             bail(1); }
  110.         while(filelength(file)<(long)(sub[subnum]->ptridx)*10) {
  111.             lseek(file,0L,SEEK_END);
  112.             idx=tell(file)/10;
  113.             for(i=0;i<total_subs;i++)
  114.                 if(sub[i]->ptridx==idx)
  115.                     break;
  116.             write(file,&l,4);
  117.             write(file,&l,4);
  118.             ch=0xff;            /* default to scan ON for unknown sub */
  119.             if(i<total_subs) {
  120.                 if(!(sub[i]->misc&SUB_NSDEF))
  121.                     ch&=~5;
  122.                 if(!(sub[i]->misc&SUB_SSDEF))
  123.                     ch&=~2; }
  124.             write(file,&ch,2); }
  125.         lseek(file,((long)sub[subnum]->ptridx)*10L,SEEK_SET);
  126.         write(file,&l,4);    /* date set to null */
  127.         write(file,&l,4);    /* date set to null */
  128.         ch=0xff;
  129.         if(!(sub[subnum]->misc&SUB_NSDEF))
  130.             ch&=~5;
  131.         if(!(sub[subnum]->misc&SUB_SSDEF))
  132.             ch&=~2;
  133.         write(file,&ch,2);
  134.         close(file); }
  135.     last=findnext(&ff); }
  136. upop(0);
  137. }
  138.  
  139. void msgs_cfg()
  140. {
  141.     static int dflt,msgs_dflt,bar;
  142.     char str[256],str2[256],done=0,*p;
  143.     int j,k,q,s;
  144.     int i,file,ptridx,n;
  145.     long ported;
  146.     sub_t tmpsub;
  147.     static grp_t savgrp;
  148.     FILE *stream;
  149.  
  150. while(1) {
  151.     for(i=0;i<total_grps && i<MAX_OPTS;i++)
  152.         sprintf(opt[i],"%-25s",grp[i]->lname);
  153.     opt[i][0]=0;
  154.     j=WIN_ORG|WIN_ACT|WIN_CHE;
  155.     if(total_grps)
  156.         j|=WIN_DEL|WIN_DELACT|WIN_GET;
  157.     if(total_grps<MAX_OPTS)
  158.         j|=WIN_INS|WIN_INSACT|WIN_XTR;
  159.     if(savgrp.sname[0])
  160.         j|=WIN_PUT;
  161.     SETHELP(WHERE);
  162. /*
  163. Message Groups:
  164.  
  165. This is a listing of message groups for your BBS. Message groups are
  166. used to logically separate your message sub-boards into groups. Every
  167. sub-board belongs to a message group. You must have at least one message
  168. group and one sub-board configured.
  169.  
  170. One popular use for message groups is to separate local sub-boards and
  171. networked sub-boards. One might have a Local message group that contains
  172. non-networked sub-boards of various topics and also have a FidoNet
  173. message group that contains sub-boards that are echoed across FidoNet.
  174. Some sysops separate sub-boards into more specific areas such as Main,
  175. Technical, or Adult. If you have many sub-boards that have a common
  176. subject denominator, you may want to have a separate message group for
  177. those sub-boards for a more organized message structure.
  178. */
  179.     i=ulist(j,0,0,45,&msgs_dflt,&bar,"Message Groups",opt);
  180.     savnum=0;
  181.     if(i==-1) {
  182.         j=save_changes(WIN_MID);
  183.         if(j==-1)
  184.            continue;
  185.         if(!j)
  186.             write_msgs_cfg();
  187.         return; }
  188.     if((i&MSK_ON)==MSK_INS) {
  189.         i&=MSK_OFF;
  190.         SETHELP(WHERE);
  191. /*
  192. Group Long Name:
  193.  
  194. This is a description of the message group which is displayed when a
  195. user of the system uses the /* command from the main menu.
  196. */*/
  197.         strcpy(str,"Main");
  198.         if(uinput(WIN_MID|WIN_SAV,0,0,"Group Long Name",str,LEN_GLNAME
  199.             ,K_EDIT)<1)
  200.             continue;
  201.         SETHELP(WHERE);
  202. /*
  203. Group Short Name:
  204.  
  205. This is a short description of the message group which is used for the
  206. main menu and reading message prompts.
  207. */
  208.         sprintf(str2,"%.*s",LEN_GSNAME,str);
  209.         if(uinput(WIN_MID,0,0,"Group Short Name",str2,LEN_GSNAME,K_EDIT)<1)
  210.             continue;
  211.         if((grp=(grp_t **)REALLOC(grp,sizeof(grp_t *)*(total_grps+1)))==NULL) {
  212.             errormsg(WHERE,ERR_ALLOC,nulstr,total_grps+1);
  213.             total_grps=0;
  214.             bail(1);
  215.             continue; }
  216.  
  217.         if(total_grps) {    /* was total_subs (?) */
  218.             for(j=total_grps;j>i;j--)   /* insert above */
  219.                 grp[j]=grp[j-1];
  220.             for(j=0;j<total_subs;j++)   /* move sub group numbers */
  221.                 if(sub[j]->grp>=i)
  222.                     sub[j]->grp++; }
  223.  
  224.         if((grp[i]=(grp_t *)MALLOC(sizeof(grp_t)))==NULL) {
  225.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(grp_t));
  226.             continue; }
  227.         memset((grp_t *)grp[i],0,sizeof(grp_t));
  228.         strcpy(grp[i]->lname,str);
  229.         strcpy(grp[i]->sname,str2);
  230.         total_grps++;
  231.         changes=1;
  232.         continue; }
  233.     if((i&MSK_ON)==MSK_DEL) {
  234.         i&=MSK_OFF;
  235.         SETHELP(WHERE);
  236. /*
  237. Delete All Data in Group:
  238.  
  239. If you wish to delete the messages in all the sub-boards in this group,
  240. select Yes.
  241. */
  242.         j=1;
  243.         strcpy(opt[0],"Yes");
  244.         strcpy(opt[1],"No");
  245.         opt[2][0]=0;
  246.         j=ulist(WIN_MID|WIN_SAV,0,0,0,&j,0,"Delete All Data in Group",opt);
  247.         if(j==-1)
  248.             continue;
  249.         if(j==0)
  250.             for(j=0;j<total_subs;j++)
  251.                 if(sub[j]->grp==i) {
  252.                     sprintf(str,"%s.s*",sub[j]->code);
  253.                     if(!sub[j]->data_dir[0])
  254.                         sprintf(tmp,"%sSUBS\\",data_dir);
  255.                     else
  256.                         strcpy(tmp,sub[j]->data_dir);
  257.                     delfiles(tmp,str);
  258.                     clearptrs(j); }
  259.         FREE(grp[i]);
  260.         for(j=0;j<total_subs;) {
  261.             if(sub[j]->grp==i) {    /* delete subs of this group */
  262.                 FREE(sub[j]);
  263.                 total_subs--;
  264.                 k=j;
  265.                 while(k<total_subs) {    /* move all subs down */
  266.                     sub[k]=sub[k+1];
  267.                     for(q=0;q<total_qhubs;q++)
  268.                         for(s=0;s<qhub[q]->subs;s++)
  269.                             if(qhub[q]->sub[s]==k)
  270.                                 qhub[q]->sub[s]--;
  271.                     k++; } }
  272.             else j++; }
  273.         for(j=0;j<total_subs;j++)    /* move sub group numbers down */
  274.             if(sub[j]->grp>i)
  275.                 sub[j]->grp--;
  276.         total_grps--;
  277.         while(i<total_grps) {
  278.             grp[i]=grp[i+1];
  279.             i++; }
  280.         changes=1;
  281.         continue; }
  282.     if((i&MSK_ON)==MSK_GET) {
  283.         i&=MSK_OFF;
  284.         savgrp=*grp[i];
  285.         continue; }
  286.     if((i&MSK_ON)==MSK_PUT) {
  287.         i&=MSK_OFF;
  288.         *grp[i]=savgrp;
  289.         changes=1;
  290.         continue; }
  291.     done=0;
  292.     while(!done) {
  293.         j=0;
  294.         sprintf(opt[j++],"%-27.27s%s","Long Name",grp[i]->lname);
  295.         sprintf(opt[j++],"%-27.27s%s","Short Name",grp[i]->sname);
  296.         sprintf(opt[j++],"%-27.27s%.40s","Access Requirements"
  297.             ,grp[i]->ar);
  298.         strcpy(opt[j++],"Clone Options");
  299.         strcpy(opt[j++],"Export Areas...");
  300.         strcpy(opt[j++],"Import Areas...");
  301.         strcpy(opt[j++],"Message Sub-boards...");
  302.         opt[j][0]=0;
  303.         sprintf(str,"%s Group",grp[i]->sname);
  304.         savnum=0;
  305.         SETHELP(WHERE);
  306. /*
  307. Message Group Configuration:
  308.  
  309. This menu allows you to configure the security requirements for access
  310. to this message group. You can also add, delete, and configure the
  311. sub-boards of this group by selecting the Messages Sub-boards... option.
  312. */
  313.         switch(ulist(WIN_ACT,6,4,60,&dflt,0,str,opt)) {
  314.             case -1:
  315.                 done=1;
  316.                 break;
  317.             case 0:
  318.                 SETHELP(WHERE);
  319. /*
  320. Group Long Name:
  321.  
  322. This is a description of the message group which is displayed when a
  323. user of the system uses the /* command from the main menu.
  324. */*/
  325.                 strcpy(str,grp[i]->lname);    /* save incase setting to null */
  326.                 if(!uinput(WIN_MID|WIN_SAV,0,17,"Name to use for Listings"
  327.                     ,grp[i]->lname,LEN_GLNAME,K_EDIT))
  328.                     strcpy(grp[i]->lname,str);
  329.                 break;
  330.             case 1:
  331.                 SETHELP(WHERE);
  332. /*
  333. Group Short Name:
  334.  
  335. This is a short description of the message group which is used for
  336. main menu and reading messages prompts.
  337. */
  338.                 uinput(WIN_MID|WIN_SAV,0,17,"Name to use for Prompts"
  339.                     ,grp[i]->sname,LEN_GSNAME,K_EDIT);
  340.                 break;
  341.             case 2:
  342.                 sprintf(str,"%s Group",grp[i]->sname);
  343.                 getar(str,grp[i]->ar);
  344.                 break;
  345.             case 3:     /* Clone Options */
  346.                 j=0;
  347.                 strcpy(opt[0],"Yes");
  348.                 strcpy(opt[1],"No");
  349.                 opt[2][0]=0;
  350.                 SETHELP(WHERE);
  351. /*
  352. Clone Sub-board Options:
  353.  
  354. If you want to clone the options of the first sub-board of this group
  355. into all sub-boards of this group, select Yes.
  356.  
  357. The options cloned are posting requirements, reading requirements,
  358. operator requirments, moderated user requirments, toggle options,
  359. network options (including EchoMail origin line, EchoMail address,
  360. and QWK Network tagline), maximum number of messages, maximum number
  361. of CRCs, maximum age of messages, storage method, and data directory.
  362. */
  363.                 j=ulist(WIN_MID|WIN_SAV,0,0,0,&j,0
  364.                     ,"Clone Options of First Sub-board into All of Group",opt);
  365.                 if(j==0) {
  366.                     k=-1;
  367.                     for(j=0;j<total_subs;j++)
  368.                         if(sub[j]->grp==i) {
  369.                             if(k==-1)
  370.                                 k=j;
  371.                             else {
  372.                                 changes=1;
  373.                                 sub[j]->misc=(sub[k]->misc|SUB_HDRMOD);
  374.                                 strcpy(sub[j]->post_ar,sub[k]->post_ar);
  375.                                 strcpy(sub[j]->read_ar,sub[k]->read_ar);
  376.                                 strcpy(sub[j]->op_ar,sub[k]->op_ar);
  377.                                 strcpy(sub[j]->mod_ar,sub[k]->mod_ar);
  378.                                 strcpy(sub[j]->origline,sub[k]->origline);
  379.                                 strcpy(sub[j]->tagline,sub[k]->tagline);
  380.                                 strcpy(sub[j]->data_dir,sub[k]->data_dir);
  381.                                 strcpy(sub[j]->echomail_sem
  382.                                     ,sub[k]->echomail_sem);
  383.                                 sub[j]->maxmsgs=sub[k]->maxmsgs;
  384.                                 sub[j]->maxcrcs=sub[k]->maxcrcs;
  385.                                 sub[j]->maxage=sub[k]->maxage;
  386.  
  387.                                 sub[j]->faddr=sub[k]->faddr; } } }
  388.                 break;
  389.             case 4:
  390.                 k=0;
  391.                 ported=0;
  392.                 q=changes;
  393.                 strcpy(opt[k++],"SUBS.TXT    (Synchronet)");
  394.                 strcpy(opt[k++],"AREAS.BBS   (MSG)");
  395.                 strcpy(opt[k++],"AREAS.BBS   (SMB)");
  396.                 strcpy(opt[k++],"AREAS.BBS   (SBBSECHO)");
  397.                 strcpy(opt[k++],"FIDONET.NA  (Fido)");
  398.                 opt[k][0]=0;
  399.                 SETHELP(WHERE);
  400. /*
  401. Export Area File Format:
  402.  
  403. This menu allows you to choose the format of the area file you wish to
  404. export the current message group into.
  405. */
  406.                 k=0;
  407.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  408.                     ,"Export Area File Format",opt);
  409.                 if(k==-1)
  410.                     break;
  411.                 if(k==0)
  412.                     sprintf(str,"%sSUBS.TXT",ctrl_dir);
  413.                 else if(k==1 || k==2)
  414.                     sprintf(str,"AREAS.BBS");
  415.                 else if(k==3)
  416.                     sprintf(str,"%sAREAS.BBS",data_dir);
  417.                 else if(k==4)
  418.                     sprintf(str,"FIDONET.NA");
  419.                 strupr(str);
  420.                 if(k && k<4)
  421.                     if(uinput(WIN_MID|WIN_SAV,0,0,"Uplinks"
  422.                         ,str2,40,K_UPPER)<=0) {
  423.                         changes=q;
  424.                         break; }
  425.                 if(uinput(WIN_MID|WIN_SAV,0,0,"Filename"
  426.                     ,str,40,K_UPPER|K_EDIT)<=0) {
  427.                     changes=q;
  428.                     break; }
  429.                 if(fexist(str)) {
  430.                     strcpy(opt[0],"Overwrite");
  431.                     strcpy(opt[1],"Append");
  432.                     opt[2][0]=0;
  433.                     j=0;
  434.                     j=ulist(WIN_MID|WIN_SAV,0,0,0,&j,0
  435.                         ,"File Exists",opt);
  436.                     if(j==-1)
  437.                         break;
  438.                     if(j==0) j=O_WRONLY|O_TRUNC;
  439.                     else     j=O_WRONLY|O_APPEND; }
  440.                 else
  441.                     j=O_WRONLY|O_CREAT;
  442.                 if((stream=fnopen(&file,str,j))==NULL) {
  443.                     umsg("Open Failure");
  444.                     break; }
  445.                 upop("Exporting Areas...");
  446.                 for(j=0;j<total_subs;j++) {
  447.                     if(sub[j]->grp!=i)
  448.                         continue;
  449.                     ported++;
  450.                     if(k==1) {        /* AREAS.BBS *.MSG */
  451.                         if(!sub[j]->echopath[0])
  452.                             sprintf(str,"%s%s\\",echomail_dir,sub[j]->code);
  453.                         else
  454.                             strcpy(str,sub[j]->echopath);
  455.                         fprintf(stream,"%-30s %-20s %s\r\n"
  456.                             ,str,stou(sub[j]->sname),str2);
  457.                         continue; }
  458.                     if(k==2) {        /* AREAS.BBS SMB */
  459.                         if(!sub[j]->data_dir[0])
  460.                             sprintf(str,"%sSUBS\\%s",data_dir,sub[j]->code);
  461.                         else
  462.                             sprintf(str,"%s%s",sub[j]->data_dir,sub[j]->code);
  463.                         fprintf(stream,"%-30s %-20s %s\r\n"
  464.                             ,str,stou(sub[j]->sname),str2);
  465.                         continue; }
  466.                     if(k==3) {        /* AREAS.BBS SBBSECHO */
  467.                         fprintf(stream,"%-30s %-20s %s\r\n"
  468.                             ,sub[j]->code,stou(sub[j]->sname),str2);
  469.                         continue; }
  470.                     if(k==4) {        /* FIDONET.NA */
  471.                         fprintf(stream,"%-20s %s\r\n"
  472.                             ,stou(sub[j]->sname),sub[j]->lname);
  473.                         continue; }
  474.                     fprintf(stream,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
  475.                             "%s\r\n%s\r\n%s\r\n"
  476.                         ,sub[j]->lname
  477.                         ,sub[j]->sname
  478.                         ,sub[j]->qwkname
  479.                         ,sub[j]->code
  480.                         ,sub[j]->data_dir
  481.                         ,sub[j]->ar
  482.                         ,sub[j]->read_ar
  483.                         ,sub[j]->post_ar
  484.                         ,sub[j]->op_ar
  485.                         );
  486.                     fprintf(stream,"%lX\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
  487.                         ,sub[j]->misc
  488.                         ,sub[j]->tagline
  489.                         ,sub[j]->origline
  490.                         ,sub[j]->echomail_sem
  491.                         ,sub[j]->echopath
  492.                         ,faddrtoa(sub[j]->faddr)
  493.                         );
  494.                     fprintf(stream,"%lu\r\n%lu\r\n%u\r\n%u\r\n%s\r\n"
  495.                         ,sub[j]->maxmsgs
  496.                         ,sub[j]->maxcrcs
  497.                         ,sub[j]->maxage
  498.                         ,sub[j]->ptridx
  499.                         ,sub[j]->mod_ar
  500.                         );
  501.                     fprintf(stream,"***END-OF-SUB***\r\n\r\n"); }
  502.                 fclose(stream);
  503.                 upop(0);
  504.                 sprintf(str,"%lu Message Areas Exported Successfully",ported);
  505.                 umsg(str);
  506.                 changes=q;
  507.                 break;
  508.             case 5:
  509.                 ported=0;
  510.                 k=0;
  511.                 strcpy(opt[k++],"SUBS.TXT    (Synchronet)");
  512.                 strcpy(opt[k++],"AREAS.BBS   (MSG)");
  513.                 strcpy(opt[k++],"AREAS.BBS   (SMB)");
  514.                 strcpy(opt[k++],"AREAS.BBS   (SBBSECHO)");
  515.                 strcpy(opt[k++],"FIDONET.NA  (Fido)");
  516.                 opt[k][0]=0;
  517.                 SETHELP(WHERE);
  518. /*
  519. Import Area File Format:
  520.  
  521. This menu allows you to choose the format of the area file you wish to
  522. import into the current message group.
  523. */
  524.                 k=0;
  525.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  526.                     ,"Import Area File Format",opt);
  527.                 if(k==-1)
  528.                     break;
  529.                 if(k==0)
  530.                     sprintf(str,"%sSUBS.TXT",ctrl_dir);
  531.                 else if(k==1 || k==2)
  532.                     sprintf(str,"AREAS.BBS");
  533.                 else if(k==3)
  534.                     sprintf(str,"%sAREAS.BBS",data_dir);
  535.                 else if(k==4)
  536.                     sprintf(str,"FIDONET.NA");
  537.                 strupr(str);
  538.                 if(uinput(WIN_MID|WIN_SAV,0,0,"Filename"
  539.                     ,str,40,K_UPPER|K_EDIT)<=0)
  540.                     break;
  541.                 if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
  542.                     umsg("Open Failure");
  543.                     break; }
  544.                 upop("Importing Areas...");
  545.                 while(!feof(stream)) {
  546.                     if(!fgets(str,128,stream)) break;
  547.                     truncsp(str);
  548.                     if(!str[0])
  549.                         continue;
  550.                     if(k) {
  551.                         p=str;
  552.                         while(*p && *p<=SP) p++;
  553.                         if(!*p || *p==';')
  554.                             continue;
  555.                         memset(&tmpsub,0,sizeof(sub_t));
  556.                         tmpsub.misc|=
  557.                             (SUB_FIDO|SUB_NAME|SUB_TOUSER|SUB_QUOTE|SUB_HYPER);
  558.                         if(k==1) {        /* AREAS.BBS *.MSG */
  559.                             p=strrchr(str,'\\');
  560.                             if(p) *p=0;
  561.                             else p=str;
  562.                             sprintf(tmpsub.echopath,"%.*s",LEN_DIR,str);
  563.                             p++;
  564.                             sprintf(tmpsub.code,"%.8s",p);
  565.                             while(*p && *p<=SP) p++;
  566.                             sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,p);
  567.                             p=strchr(tmpsub.sname,SP);
  568.                             if(p) *p=0;
  569.                             strcpy(tmpsub.sname,utos(tmpsub.sname));
  570.                             sprintf(tmpsub.lname,"%.*s",LEN_SLNAME
  571.                                 ,tmpsub.sname);
  572.                             sprintf(tmpsub.qwkname,"%.*s",10
  573.                                 ,tmpsub.sname);
  574.                             }
  575.                         if(k==2) {        /* AREAS.BBS SMB */
  576.                             p=strrchr(str,'\\');
  577.                             if(p) *p=0;
  578.                             else p=str;
  579.                             sprintf(tmpsub.data_dir,"%.*s",LEN_DIR,str);
  580.                             p++;
  581.                             sprintf(tmpsub.code,"%.8s",p);
  582.                             while(*p && *p<=SP) p++;
  583.                             sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,p);
  584.                             p=strchr(tmpsub.sname,SP);
  585.                             if(p) *p=0;
  586.                             strcpy(tmpsub.sname,utos(tmpsub.sname));
  587.                             sprintf(tmpsub.lname,"%.*s",LEN_SLNAME
  588.                                 ,tmpsub.sname);
  589.                             sprintf(tmpsub.qwkname,"%.*s",10
  590.                                 ,tmpsub.sname);
  591.                             }
  592.                         else if(k==3) { /* AREAS.BBS SBBSECHO */
  593.                             p=str;
  594.                             while(*p && *p>SP) p++;
  595.                             *p=0;
  596.                             sprintf(tmpsub.code,"%.8s",str);
  597.                             p++;
  598.                             while(*p && *p<=SP) p++;
  599.                             sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,p);
  600.                             p=strchr(tmpsub.sname,SP);
  601.                             if(p) *p=0;
  602.                             strcpy(tmpsub.sname,utos(tmpsub.sname));
  603.                             sprintf(tmpsub.lname,"%.*s",LEN_SLNAME
  604.                                 ,tmpsub.sname);
  605.                             sprintf(tmpsub.qwkname,"%.*s",10
  606.                                 ,tmpsub.sname);
  607.                             }
  608.                         else if(k==4) { /* FIDONET.NA */
  609.                             p=str;
  610.                             while(*p && *p>SP) p++;
  611.                             *p=0;
  612.                             sprintf(tmpsub.code,"%.8s",str);
  613.                             sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,utos(str));
  614.                             sprintf(tmpsub.qwkname,"%.10s",tmpsub.sname);
  615.                             p++;
  616.                             while(*p && *p<=SP) p++;
  617.                             sprintf(tmpsub.lname,"%.*s",LEN_SLNAME,p);
  618.                             }
  619.                         ported++; }
  620.                     else {
  621.                         memset(&tmpsub,0,sizeof(sub_t));
  622.                         tmpsub.grp=i;
  623.                         sprintf(tmpsub.lname,"%.*s",LEN_SLNAME,str);
  624.                         if(!fgets(str,128,stream)) break;
  625.                         truncsp(str);
  626.                         sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,str);
  627.                         if(!fgets(str,128,stream)) break;
  628.                         truncsp(str);
  629.                         sprintf(tmpsub.qwkname,"%.*s",10,str);
  630.                         if(!fgets(str,128,stream)) break;
  631.                         truncsp(str);
  632.                         sprintf(tmpsub.code,"%.*s",8,str);
  633.                         if(!fgets(str,128,stream)) break;
  634.                         truncsp(str);
  635.                         sprintf(tmpsub.data_dir,"%.*s",LEN_DIR,str);
  636.                         if(!fgets(str,128,stream)) break;
  637.                         truncsp(str);
  638.                         sprintf(tmpsub.ar,"%.*s",LEN_ARSTR,str);
  639.                         if(!fgets(str,128,stream)) break;
  640.                         truncsp(str);
  641.                         sprintf(tmpsub.read_ar,"%.*s",LEN_ARSTR,str);
  642.                         if(!fgets(str,128,stream)) break;
  643.                         truncsp(str);
  644.                         sprintf(tmpsub.post_ar,"%.*s",LEN_ARSTR,str);
  645.                         if(!fgets(str,128,stream)) break;
  646.                         truncsp(str);
  647.                         sprintf(tmpsub.op_ar,"%.*s",LEN_ARSTR,str);
  648.                         if(!fgets(str,128,stream)) break;
  649.                         truncsp(str);
  650.                         tmpsub.misc=ahtoul(str);
  651.                         if(!fgets(str,128,stream)) break;
  652.                         truncsp(str);
  653.                         sprintf(tmpsub.tagline,"%.*s",80,str);
  654.                         if(!fgets(str,128,stream)) break;
  655.                         truncsp(str);
  656.                         sprintf(tmpsub.origline,"%.*s",50,str);
  657.                         if(!fgets(str,128,stream)) break;
  658.                         truncsp(str);
  659.                         sprintf(tmpsub.echomail_sem,"%.*s",LEN_DIR,str);
  660.                         if(!fgets(str,128,stream)) break;
  661.                         truncsp(str);
  662.                         sprintf(tmpsub.echopath,"%.*s",LEN_DIR,str);
  663.                         if(!fgets(str,128,stream)) break;
  664.                         truncsp(str);
  665.                         tmpsub.faddr=atofaddr(str);
  666.                         if(!fgets(str,128,stream)) break;
  667.                         truncsp(str);
  668.                         tmpsub.maxmsgs=atol(str);
  669.                         if(!fgets(str,128,stream)) break;
  670.                         truncsp(str);
  671.                         tmpsub.maxcrcs=atol(str);
  672.                         if(!fgets(str,128,stream)) break;
  673.                         truncsp(str);
  674.                         tmpsub.maxage=atoi(str);
  675.                         if(!fgets(str,128,stream)) break;
  676.                         truncsp(str);
  677.                         tmpsub.ptridx=atoi(str);
  678.                         if(!fgets(str,128,stream)) break;
  679.                         truncsp(str);
  680.                         sprintf(tmpsub.mod_ar,"%.*s",LEN_ARSTR,str);
  681.  
  682.                         ported++;
  683.                         while(!feof(stream)
  684.                             && strcmp(str,"***END-OF-SUB***")) {
  685.                             if(!fgets(str,128,stream)) break;
  686.                             truncsp(str); } }
  687.  
  688.                     truncsp(tmpsub.code);
  689.                     truncsp(tmpsub.sname);
  690.                     truncsp(tmpsub.lname);
  691.                     truncsp(tmpsub.qwkname);
  692.                     for(j=0;j<total_subs;j++) {
  693.                         if(sub[j]->grp!=i)
  694.                             continue;
  695.                         if(!stricmp(sub[j]->code,tmpsub.code))
  696.                             break; }
  697.                     if(j==total_subs) {
  698.  
  699.                         if((sub=(sub_t **)REALLOC(sub
  700.                             ,sizeof(sub_t *)*(total_subs+1)))==NULL) {
  701.                             errormsg(WHERE,ERR_ALLOC,nulstr,total_subs+1);
  702.                             total_subs=0;
  703.                             bail(1);
  704.                             break; }
  705.  
  706.                         for(ptridx=0;ptridx>-1;ptridx++) {
  707.                             for(n=0;n<total_subs;n++)
  708.                                 if(sub[n]->ptridx==ptridx)
  709.                                     break;
  710.                             if(n==total_subs)
  711.                                 break; }
  712.  
  713.                         if((sub[j]=(sub_t *)MALLOC(sizeof(sub_t)))
  714.                             ==NULL) {
  715.                             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t));
  716.                             break; }
  717.                         memset(sub[j],0,sizeof(sub_t)); }
  718.                     if(!k)
  719.                         memcpy(sub[j],&tmpsub,sizeof(sub_t));
  720.                     else {
  721.                         sub[j]->grp=i;
  722.                         if(total_faddrs)
  723.                             sub[j]->faddr=faddr[0];
  724.                         strcpy(sub[j]->code,tmpsub.code);
  725.                         strcpy(sub[j]->sname,tmpsub.sname);
  726.                         strcpy(sub[j]->lname,tmpsub.lname);
  727.                         strcpy(sub[j]->qwkname,tmpsub.qwkname);
  728.                         strcpy(sub[j]->echopath,tmpsub.echopath);
  729.                         strcpy(sub[j]->data_dir,tmpsub.data_dir);
  730.                         if(j==total_subs)
  731.                             sub[j]->maxmsgs=1000;
  732.                         }
  733.                     if(j==total_subs) {
  734.                         sub[j]->ptridx=ptridx;
  735.                         sub[j]->misc=tmpsub.misc;
  736.                         total_subs++; }
  737.                     changes=1; }
  738.                 fclose(stream);
  739.                 upop(0);
  740.                 sprintf(str,"%lu Message Areas Imported Successfully",ported);
  741.                 umsg(str);
  742.                 break;
  743.  
  744.             case 6:
  745.                 sub_cfg(i);
  746.                 break; } } }
  747.  
  748. }
  749.  
  750. void msg_opts()
  751. {
  752.     char str[128],*p;
  753.     static int msg_dflt;
  754.     int i,j;
  755.  
  756.     while(1) {
  757.         i=0;
  758.         sprintf(opt[i++],"%-33.33s%s"
  759.             ,"BBS ID for QWK Packets",sys_id);
  760.         sprintf(opt[i++],"%-33.33s%s"
  761.             ,"Local Time Zone",zonestr(sys_timezone));
  762.         sprintf(opt[i++],"%-33.33s%u seconds"
  763.             ,"Maximum Retry Time",smb_retry_time);
  764.         if(max_qwkmsgs)
  765.             sprintf(str,"%lu",max_qwkmsgs);
  766.         else
  767.             sprintf(str,"Unlimited");
  768.         sprintf(opt[i++],"%-33.33s%s"
  769.             ,"Maximum QWK Messages",str);
  770.         sprintf(opt[i++],"%-33.33s%s","Pre-pack QWK Requirements",preqwk_ar);
  771.         if(mail_maxage)
  772.             sprintf(str,"Enabled (%u days old)",mail_maxage);
  773.         else
  774.             strcpy(str,"Disabled");
  775.         sprintf(opt[i++],"%-33.33s%s","Purge E-mail by Age",str);
  776.         if(sys_misc&SM_DELEMAIL)
  777.             strcpy(str,"Immediately");
  778.         else
  779.             strcpy(str,"Daily");
  780.         sprintf(opt[i++],"%-33.33s%s","Purge Deleted E-mail",str);
  781.         if(mail_maxcrcs)
  782.             sprintf(str,"Enabled (%lu mail CRCs)",mail_maxcrcs);
  783.         else
  784.             strcpy(str,"Disabled");
  785.         sprintf(opt[i++],"%-33.33s%s","Duplicate E-mail Checking",str);
  786.         sprintf(opt[i++],"%-33.33s%s","Allow Anonymous E-mail"
  787.             ,sys_misc&SM_ANON_EM ? "Yes" : "No");
  788.         sprintf(opt[i++],"%-33.33s%s","Allow Quoting in E-mail"
  789.             ,sys_misc&SM_QUOTE_EM ? "Yes" : "No");
  790.         sprintf(opt[i++],"%-33.33s%s","Allow Uploads in E-mail"
  791.             ,sys_misc&SM_FILE_EM ? "Yes" : "No");
  792.         sprintf(opt[i++],"%-33.33s%s","Allow Forwarding to NetMail"
  793.             ,sys_misc&SM_FWDTONET ? "Yes" : "No");
  794.         sprintf(opt[i++],"%-33.33s%s","Kill Read E-mail"
  795.             ,sys_misc&SM_DELREADM ? "Yes" : "No");
  796.         sprintf(opt[i++],"%-33.33s%s","Users Can View Deleted Messages"
  797.             ,sys_misc&SM_USRVDELM ? "Yes" : sys_misc&SM_SYSVDELM
  798.                 ? "Sysops Only":"No");
  799.         strcpy(opt[i++],"Extra Attribute Codes...");
  800.         opt[i][0]=0;
  801.         savnum=0;
  802.         SETHELP(WHERE);
  803. /*
  804. Message Options:
  805.  
  806. This is a menu of system-wide message related options. Messages include
  807. E-mail and public posts (on sub-boards).
  808. */
  809.  
  810.         switch(ulist(WIN_ORG|WIN_ACT|WIN_MID|WIN_CHE,0,0,72,&msg_dflt,0
  811.             ,"Message Options",opt)) {
  812.             case -1:
  813.                 i=save_changes(WIN_MID);
  814.                 if(i==-1)
  815.                    continue;
  816.                 if(!i) {
  817.                     write_msgs_cfg();
  818.                     write_main_cfg(); }
  819.                 return;
  820.             case 0:
  821.                 strcpy(str,sys_id);
  822.                 SETHELP(WHERE);
  823. /*
  824. BBS ID for QWK Packets:
  825.  
  826. This is a short system ID for your BBS that is used for QWK packets.
  827. It should be an abbreviation of your BBS name or other related string.
  828. This ID will be used for your outgoing and incoming QWK packets. If
  829. you plan on networking via QWK packets with another Synchronet BBS,
  830. this ID should not begin with a number. The maximum length of the ID
  831. is eight characters and cannot contain spaces or other invalid DOS
  832. filename characters. In a QWK packet network, each system must have
  833. a unique QWK system ID.
  834. */
  835.  
  836.                 uinput(WIN_MID|WIN_SAV,0,0,"BBS ID for QWK Packets"
  837.                     ,str,8,K_EDIT|K_UPPER);
  838.                 if(code_ok(str))
  839.                     strcpy(sys_id,str);
  840.                 else
  841.                     umsg("Invalid ID");
  842.                 break;
  843.             case 1:
  844.                 strcpy(opt[0],"Yes");
  845.                 strcpy(opt[1],"No");
  846.                 opt[2][0]=0;
  847.                 i=0;
  848.                 SETHELP(WHERE);
  849. /*
  850. United States Time Zone:
  851.  
  852. If your local time zone is the United States, select Yes.
  853. */
  854.  
  855.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  856.                     ,"United States Time Zone",opt);
  857.                 if(i==-1)
  858.                     break;
  859.                 if(i==0) {
  860.                     strcpy(opt[i++],"Atlantic");
  861.                     strcpy(opt[i++],"Eastern");
  862.                     strcpy(opt[i++],"Central");
  863.                     strcpy(opt[i++],"Mountain");
  864.                     strcpy(opt[i++],"Pacific");
  865.                     strcpy(opt[i++],"Yukon");
  866.                     strcpy(opt[i++],"Hawaii/Alaska");
  867.                     strcpy(opt[i++],"Bering");
  868.                     opt[i][0]=0;
  869.                     i=0;
  870.                     i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  871.                         ,"Time Zone",opt);
  872.                     if(i==-1)
  873.                         break;
  874.                     changes=1;
  875.                     switch(i) {
  876.                         case 0:
  877.                             sys_timezone=AST;
  878.                             break;
  879.                         case 1:
  880.                             sys_timezone=EST;
  881.                             break;
  882.                         case 2:
  883.                             sys_timezone=CST;
  884.                             break;
  885.                         case 3:
  886.                             sys_timezone=MST;
  887.                             break;
  888.                         case 4:
  889.                             sys_timezone=PST;
  890.                             break;
  891.                         case 5:
  892.                             sys_timezone=YST;
  893.                             break;
  894.                         case 6:
  895.                             sys_timezone=HST;
  896.                             break;
  897.                         case 7:
  898.                             sys_timezone=BST;
  899.                             break; }
  900.                     strcpy(opt[0],"Yes");
  901.                     strcpy(opt[1],"No");
  902.                     opt[2][0]=0;
  903.                     i=1;
  904.                     i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  905.                         ,"Daylight Savings",opt);
  906.                     if(i==-1)
  907.                         break;
  908.                     if(!i)
  909.                         sys_timezone|=DAYLIGHT;
  910.                     break; }
  911.                 i=0;
  912.                 strcpy(opt[i++],"Midway");
  913.                 strcpy(opt[i++],"Vancouver");
  914.                 strcpy(opt[i++],"Edmonton");
  915.                 strcpy(opt[i++],"Winnipeg");
  916.                 strcpy(opt[i++],"Bogota");
  917.                 strcpy(opt[i++],"Caracas");
  918.                 strcpy(opt[i++],"Rio de Janeiro");
  919.                 strcpy(opt[i++],"Fernando de Noronha");
  920.                 strcpy(opt[i++],"Azores");
  921.                 strcpy(opt[i++],"London");
  922.                 strcpy(opt[i++],"Berlin");
  923.                 strcpy(opt[i++],"Athens");
  924.                 strcpy(opt[i++],"Moscow");
  925.                 strcpy(opt[i++],"Dubai");
  926.                 strcpy(opt[i++],"Kabul");
  927.                 strcpy(opt[i++],"Karachi");
  928.                 strcpy(opt[i++],"Bombay");
  929.                 strcpy(opt[i++],"Kathmandu");
  930.                 strcpy(opt[i++],"Dhaka");
  931.                 strcpy(opt[i++],"Bangkok");
  932.                 strcpy(opt[i++],"Hong Kong");
  933.                 strcpy(opt[i++],"Tokyo");
  934.                 strcpy(opt[i++],"Sydney");
  935.                 strcpy(opt[i++],"Noumea");
  936.                 strcpy(opt[i++],"Wellington");
  937.                 strcpy(opt[i++],"Other...");
  938.                 opt[i][0]=0;
  939.                 i=0;
  940.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  941.                     ,"Time Zone",opt);
  942.                 if(i==-1)
  943.                     break;
  944.                 changes=1;
  945.                 switch(i) {
  946.                     case 0:
  947.                         sys_timezone=MID;
  948.                         break;
  949.                     case 1:
  950.                         sys_timezone=VAN;
  951.                         break;
  952.                     case 2:
  953.                         sys_timezone=EDM;
  954.                         break;
  955.                     case 3:
  956.                         sys_timezone=WIN;
  957.                         break;
  958.                     case 4:
  959.                         sys_timezone=BOG;
  960.                         break;
  961.                     case 5:
  962.                         sys_timezone=CAR;
  963.                         break;
  964.                     case 6:
  965.                         sys_timezone=RIO;
  966.                         break;
  967.                     case 7:
  968.                         sys_timezone=FER;
  969.                         break;
  970.                     case 8:
  971.                         sys_timezone=AZO;
  972.                         break;
  973.                     case 9:
  974.                         sys_timezone=LON;
  975.                         break;
  976.                     case 10:
  977.                         sys_timezone=BER;
  978.                         break;
  979.                     case 11:
  980.                         sys_timezone=ATH;
  981.                         break;
  982.                     case 12:
  983.                         sys_timezone=MOS;
  984.                         break;
  985.                     case 13:
  986.                         sys_timezone=DUB;
  987.                         break;
  988.                     case 14:
  989.                         sys_timezone=KAB;
  990.                         break;
  991.                     case 15:
  992.                         sys_timezone=KAR;
  993.                         break;
  994.                     case 16:
  995.                         sys_timezone=BOM;
  996.                         break;
  997.                     case 17:
  998.                         sys_timezone=KAT;
  999.                         break;
  1000.                     case 18:
  1001.                         sys_timezone=DHA;
  1002.                         break;
  1003.                     case 19:
  1004.                         sys_timezone=BAN;
  1005.                         break;
  1006.                     case 20:
  1007.                         sys_timezone=HON;
  1008.                         break;
  1009.                     case 21:
  1010.                         sys_timezone=TOK;
  1011.                         break;
  1012.                     case 22:
  1013.                         sys_timezone=SYD;
  1014.                         break;
  1015.                     case 23:
  1016.                         sys_timezone=NOU;
  1017.                         break;
  1018.                     case 24:
  1019.                         sys_timezone=WEL;
  1020.                         break;
  1021.                     default:
  1022.                         if(sys_timezone>720 || sys_timezone<-720)
  1023.                             sys_timezone=0;
  1024.                         sprintf(str,"%02d:%02d"
  1025.                             ,sys_timezone/60,sys_timezone<0
  1026.                             ? (-sys_timezone)%60 : sys_timezone%60);
  1027.                         uinput(WIN_MID|WIN_SAV,0,0
  1028.                             ,"Time (HH:MM) East (+) or West (-) of Universal "
  1029.                                 "Time"
  1030.                             ,str,6,K_EDIT|K_UPPER);
  1031.                         sys_timezone=atoi(str)*60;
  1032.                         p=strchr(str,':');
  1033.                         if(p) {
  1034.                             if(sys_timezone<0)
  1035.                                 sys_timezone-=atoi(p+1);
  1036.                             else
  1037.                                 sys_timezone+=atoi(p+1); }
  1038.                         break;
  1039.                         }
  1040.                 break;
  1041.             case 2:
  1042.                 SETHELP(WHERE);
  1043. /*
  1044. Maximum Message Base Retry Time:
  1045.  
  1046. This is the maximum number of seconds to allow while attempting to open
  1047. or lock a message base (a value in the range of 10 to 45 seconds should
  1048. be fine).
  1049. */
  1050.                 itoa(smb_retry_time,str,10);
  1051.                 uinput(WIN_MID|WIN_SAV,0,0
  1052.                     ,"Maximum Message Base Retry Time (in seconds)"
  1053.                     ,str,2,K_NUMBER|K_EDIT);
  1054.                 smb_retry_time=atoi(str);
  1055.                 break;
  1056.             case 3:
  1057.                 SETHELP(WHERE);
  1058. /*
  1059. Maximum Messages Per QWK Packet:
  1060.  
  1061. This is the maximum number of messages (excluding E-mail), that a user
  1062. can have in one QWK packet for download. This limit does not effect
  1063. QWK network nodes (Q restriction). If set to 0, no limit is imposed.
  1064. */
  1065.  
  1066.                 ultoa(max_qwkmsgs,str,10);
  1067.                 uinput(WIN_MID|WIN_SAV,0,0
  1068.                     ,"Maximum Messages Per QWK Packet (0=No Limit)"
  1069.                     ,str,6,K_NUMBER|K_EDIT);
  1070.                 max_qwkmsgs=atoi(str);
  1071.                 break;
  1072.             case 4:
  1073.                 SETHELP(WHERE);
  1074. /*
  1075. Pre-pack QWK Requirements:
  1076.  
  1077. ALL user accounts on the BBS meeting this requirmenet will have a QWK
  1078. packet automatically created for them every day after midnight
  1079. (during the internal daily event).
  1080.  
  1081. This is mainly intended for QWK network nodes that wish to save connect
  1082. time by having their packets pre-packed. If a large number of users meet
  1083. this requirement, it can take up a large amount of disk space on your
  1084. system (in the DATA\FILE directory).
  1085. */
  1086.                 getar("Pre-pack QWK (Use with caution!)",preqwk_ar);
  1087.                 break;
  1088.             case 5:
  1089.                 sprintf(str,"%u",mail_maxage);
  1090.                 SETHELP(WHERE);
  1091. /*
  1092. Maximum Age of Mail:
  1093.  
  1094. This value is the maximum number of days that mail will be kept.
  1095. */
  1096.                 uinput(WIN_MID|WIN_SAV,0,17,"Maximum Age of Mail "
  1097.                     "(in days)",str,5,K_EDIT|K_NUMBER);
  1098.                 mail_maxage=atoi(str);
  1099.                 break;
  1100.             case 6:
  1101.                 strcpy(opt[0],"Daily");
  1102.                 strcpy(opt[1],"Immediately");
  1103.                 opt[2][0]=0;
  1104.                 i=0;
  1105.                 SETHELP(WHERE);
  1106. /*
  1107. Purge Deleted E-mail:
  1108.  
  1109. If you wish to have deleted e-mail physically (and permanently) removed
  1110. from your e-mail database immediately after a users exits the reading
  1111. e-mail prompt, set this option to Immediately.
  1112.  
  1113. For the best system performance and to avoid delays when deleting e-mail
  1114. from a large e-mail database, set this option to Daily (the default).
  1115. Your system maintenance will automatically purge deleted e-mail once a
  1116. day.
  1117. */
  1118.  
  1119.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1120.                     ,"Purge Deleted E-mail",opt);
  1121.                 if(!i && sys_misc&SM_DELEMAIL) {
  1122.                     sys_misc&=~SM_DELEMAIL;
  1123.                     changes=1; }
  1124.                 else if(i==1 && !(sys_misc&SM_DELEMAIL)) {
  1125.                     sys_misc|=SM_DELEMAIL;
  1126.                     changes=1; }
  1127.                 break;
  1128.             case 7:
  1129.                 sprintf(str,"%lu",mail_maxcrcs);
  1130.                 SETHELP(WHERE);
  1131. /*
  1132. Maximum Number of Mail CRCs:
  1133.  
  1134. This value is the maximum number of CRCs that will be kept for duplicate
  1135. mail checking. Once this maximum number of CRCs is reached, the oldest
  1136. CRCs will be automatically purged.
  1137. */
  1138.                 uinput(WIN_MID|WIN_SAV,0,17,"Maximum Number of Mail "
  1139.                     "CRCs",str,5,K_EDIT|K_NUMBER);
  1140.                 mail_maxcrcs=atol(str);
  1141.                 break;
  1142.             case 8:
  1143.                 strcpy(opt[0],"Yes");
  1144.                 strcpy(opt[1],"No");
  1145.                 opt[2][0]=0;
  1146.                 i=1;
  1147.                 SETHELP(WHERE);
  1148. /*
  1149. Allow Anonymous E-mail:
  1150.  
  1151. If you want users with the A exemption to be able to send E-mail
  1152. anonymously, set this option to Yes.
  1153. */
  1154.  
  1155.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1156.                     ,"Allow Anonymous E-mail",opt);
  1157.                 if(!i && !(sys_misc&SM_ANON_EM)) {
  1158.                     sys_misc|=SM_ANON_EM;
  1159.                     changes=1; }
  1160.                 else if(i==1 && sys_misc&SM_ANON_EM) {
  1161.                     sys_misc&=~SM_ANON_EM;
  1162.                     changes=1; }
  1163.                 break;
  1164.             case 9:
  1165.                 strcpy(opt[0],"Yes");
  1166.                 strcpy(opt[1],"No");
  1167.                 opt[2][0]=0;
  1168.                 i=0;
  1169.                 SETHELP(WHERE);
  1170. /*
  1171. Allow Quoting in E-mail:
  1172.  
  1173. If you want your users to be allowed to use message quoting when
  1174. responding in E-mail, set this option to Yes.
  1175. */
  1176.  
  1177.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1178.                     ,"Allow Quoting in E-mail",opt);
  1179.                 if(!i && !(sys_misc&SM_QUOTE_EM)) {
  1180.                     sys_misc|=SM_QUOTE_EM;
  1181.                     changes=1; }
  1182.                 else if(i==1 && sys_misc&SM_QUOTE_EM) {
  1183.                     sys_misc&=~SM_QUOTE_EM;
  1184.                     changes=1; }
  1185.                 break;
  1186.             case 10:
  1187.                 strcpy(opt[0],"Yes");
  1188.                 strcpy(opt[1],"No");
  1189.                 opt[2][0]=0;
  1190.                 i=0;
  1191.                 SETHELP(WHERE);
  1192. /*
  1193. Allow File Attachment Uploads in E-mail:
  1194.  
  1195. If you want your users to be allowed to attach an uploaded file to
  1196. an E-mail message, set this option to Yes.
  1197. */
  1198.  
  1199.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1200.                     ,"Allow File Attachment Uploads in E-mail",opt);
  1201.                 if(!i && !(sys_misc&SM_FILE_EM)) {
  1202.                     sys_misc|=SM_FILE_EM;
  1203.                     changes=1; }
  1204.                 else if(i==1 && sys_misc&SM_FILE_EM) {
  1205.                     sys_misc&=~SM_FILE_EM;
  1206.                     changes=1; }
  1207.                 break;
  1208.             case 11:
  1209.                 strcpy(opt[0],"Yes");
  1210.                 strcpy(opt[1],"No");
  1211.                 opt[2][0]=0;
  1212.                 i=0;
  1213.                 SETHELP(WHERE);
  1214. /*
  1215. Allow Users to Have Their E-mail Forwarded to NetMail:
  1216.  
  1217. If you want your users to be able to have any e-mail sent to them
  1218. optionally (at the sender's discretion) forwarded to a NetMail address,
  1219. set this option to Yes.
  1220. */
  1221.  
  1222.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1223.                     ,"Allow Forwarding of E-mail to NetMail",opt);
  1224.                 if(!i && !(sys_misc&SM_FWDTONET)) {
  1225.                     sys_misc|=SM_FWDTONET;
  1226.                     changes=1; }
  1227.                 else if(i==1 && sys_misc&SM_FWDTONET) {
  1228.                     sys_misc&=~SM_FWDTONET;
  1229.                     changes=1; }
  1230.                 break;
  1231.             case 12:
  1232.                 strcpy(opt[0],"Yes");
  1233.                 strcpy(opt[1],"No");
  1234.                 opt[2][0]=0;
  1235.                 i=1;
  1236.                 SETHELP(WHERE);
  1237. /*
  1238. Kill Read E-mail Automatically:
  1239.  
  1240. If this option is set to Yes, e-mail that has been read will be
  1241. automatically deleted when message base maintenance is run.
  1242. */
  1243.  
  1244.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1245.                     ,"Kill Read E-mail Automatically",opt);
  1246.                 if(!i && !(sys_misc&SM_DELREADM)) {
  1247.                     sys_misc|=SM_DELREADM;
  1248.                     changes=1; }
  1249.                 else if(i==1 && sys_misc&SM_DELREADM) {
  1250.                     sys_misc&=~SM_DELREADM;
  1251.                     changes=1; }
  1252.                 break;
  1253.             case 13:
  1254.                 strcpy(opt[0],"Yes");
  1255.                 strcpy(opt[1],"No");
  1256.                 strcpy(opt[2],"Sysops Only");
  1257.                 opt[3][0]=0;
  1258.                 i=1;
  1259.                 SETHELP(WHERE);
  1260. /*
  1261. Users Can View Deleted Messages:
  1262.  
  1263. If this option is set to Yes, then users will be able to view messages
  1264. they've sent and deleted or messages sent to them and they've deleted
  1265. with the option of un-deleting the message before the message is
  1266. physically purged from the e-mail database.
  1267.  
  1268. If this option is set to No, then when a message is deleted, it is no
  1269. longer viewable (with SBBS) by anyone.
  1270.  
  1271. If this option is set to Sysops Only, then only sysops and sub-ops (when
  1272. appropriate) can view deleted messages.
  1273. */
  1274.  
  1275.                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1276.                     ,"Users Can View Deleted Messages",opt);
  1277.                 if(!i && (sys_misc&(SM_USRVDELM|SM_SYSVDELM))
  1278.                     !=(SM_USRVDELM|SM_SYSVDELM)) {
  1279.                     sys_misc|=(SM_USRVDELM|SM_SYSVDELM);
  1280.                     changes=1; }
  1281.                 else if(i==1 && sys_misc&(SM_USRVDELM|SM_SYSVDELM)) {
  1282.                     sys_misc&=~(SM_USRVDELM|SM_SYSVDELM);
  1283.                     changes=1; }
  1284.                 else if(i==2 && (sys_misc&(SM_USRVDELM|SM_SYSVDELM))
  1285.                     !=SM_SYSVDELM) {
  1286.                     sys_misc|=SM_SYSVDELM;
  1287.                     sys_misc&=~SM_USRVDELM;
  1288.                     changes=1; }
  1289.                 break;
  1290.             case 14:
  1291.                 SETHELP(WHERE);
  1292. /*
  1293. Extra Attribute Codes...
  1294.  
  1295. Synchronet can suppport the native text attribute codes of other BBS
  1296. programs in messages (menus, posts, e-mail, etc.) To enable the extra
  1297. attribute codes for another BBS program, set the corresponding option
  1298. to Yes.
  1299. */
  1300.  
  1301.                 j=0;
  1302.                 while(1) {
  1303.                     i=0;
  1304.                     sprintf(opt[i++],"%-15.15s %-3.3s","WWIV"
  1305.                         ,sys_misc&SM_WWIV ? "Yes":"No");
  1306.                     sprintf(opt[i++],"%-15.15s %-3.3s","PCBoard"
  1307.                         ,sys_misc&SM_PCBOARD ? "Yes":"No");
  1308.                     sprintf(opt[i++],"%-15.15s %-3.3s","Wildcat"
  1309.                         ,sys_misc&SM_WILDCAT ? "Yes":"No");
  1310.                     sprintf(opt[i++],"%-15.15s %-3.3s","Celerity"
  1311.                         ,sys_misc&SM_CELERITY ? "Yes":"No");
  1312.                     sprintf(opt[i++],"%-15.15s %-3.3s","Renegade"
  1313.                         ,sys_misc&SM_RENEGADE ? "Yes":"No");
  1314.                     opt[i][0]=0;
  1315.                     j=ulist(WIN_BOT|WIN_RHT|WIN_SAV,2,2,0,&j,0
  1316.                         ,"Extra Attribute Codes",opt);
  1317.                     if(j==-1)
  1318.                         break;
  1319.  
  1320.                     changes=1;
  1321.                     switch(j) {
  1322.                         case 0:
  1323.                             sys_misc^=SM_WWIV;
  1324.                             break;
  1325.                         case 1:
  1326.                             sys_misc^=SM_PCBOARD;
  1327.                             break;
  1328.                         case 2:
  1329.                             sys_misc^=SM_WILDCAT;
  1330.                             break;
  1331.                         case 3:
  1332.                             sys_misc^=SM_CELERITY;
  1333.                             break;
  1334.                         case 4:
  1335.                             sys_misc^=SM_RENEGADE;
  1336.                             break; } } } }
  1337. }
  1338.