home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / lbbs07 / bbs.c next >
C/C++ Source or Header  |  1993-07-25  |  22KB  |  990 lines

  1. /*
  2.  *    LazyBBS - The Ultimate BBS for Lazy People
  3.  *    ------------------------------------------
  4.  *
  5.  *    LazyBBS is a very simple BBS program for a Pandora Fidonet 
  6.  *    message base (used by Led, Qbbs, Bermuda, IOS, etc on the Atari
  7.  *    ST). And FILES.BBS-like download areas. It should be portable 
  8.  *    on most operating systems supporting unix-like libraries,
  9.  *    ANSI C libraries and compilers. It is especially useful 
  10.  *    with the Fidonet package "Bermuda". The code is ugly, but 
  11.  *    that's LAZYbbs :-).
  12.  *
  13.  *    Public domain: this program may be copied and sold freely.
  14.  *    Suggestion: read the fine manual & state on modified versions 
  15.  *    that these are not the original version and change the version 
  16.  *    string in bbs.h.
  17.  *
  18.  *    Porting: 
  19.  *    1) edit sysdep.c bbs.h
  20.  *    2) compile sysdep.c miscio.c login.c linedit.c match.c msg.c bbs.c
  21.  *    3) link to bbs
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <time.h>
  27. #include <stdarg.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30.  
  31. #include <dirent.h>     /* POSIX directory for download */
  32. #include <sys/types.h>    /* for download's stat() */
  33. #include <sys/stat.h>
  34.  
  35. #ifdef UNIX
  36. #include <sys/ioctl.h>        /* for raw mode */
  37. #include <termios.h>
  38. #endif
  39.  
  40. #include "bbs.h"        /* constants & config */
  41.  
  42. #include "match.h"        /* regular expression library */
  43. #include "linedit.h"     /* line editor module */
  44. #include "login.h"        /* login module */
  45. #include "msg.h"        /* message module */
  46. #include "sysdep.h"        /* LEVEL 0: low level, in main and download */
  47. #include "miscio.h"        /* LEVEL 1: Misc and IO */
  48.  
  49. #define DEBUG /**/
  50.  
  51. #ifdef LATTICE /* for atari Lattice C 5 */
  52. unsigned long _STACK=16000;
  53. #endif
  54.  
  55. /* =================================================== PROTOTYPES */
  56.  
  57. int more(char *, int );
  58. int upload(char *);
  59. void do_download(char *);
  60. int download(char *);
  61. void global_download(char *);
  62. int readmail(char *,char *,char *,int );
  63. int writemail(char *,char *,char *,char *);
  64. void lazyprompt(char *);
  65. int domenu(char *,char *,char *);
  66. void chat(void);
  67. int main(int, char **);
  68.  
  69.  
  70.  
  71. /* ============================================================= MORE */
  72.  
  73. int more(char *text, int domore)
  74. {
  75.     char oneline[BBSSTR];
  76.     FILE *txt;
  77.     int line=1,capture=0,key=1,neubauten=1;
  78.     
  79.     if(!text)
  80.         return BBSFAIL;
  81.         
  82.     txt=fopen(text,"r");
  83.     if(!txt)
  84.         return BBSFAIL;
  85.     
  86.     out_printf(CLS_STRING);
  87.     
  88.     while(fgets(oneline,BBSSTR,txt))
  89.     {
  90.         if(strlen(oneline)>79)
  91.             strcpy(oneline+78,"\n");
  92.         out_string(oneline);
  93.         if(line%MORELINE==0 && domore)
  94.         { /* prompt */
  95.             out_printf("\nMore? [Y]es [N]o [C]apture ");
  96.             key=tolower(getkey());
  97.             if(key=='c')
  98.                 capture++;
  99.             if((key!='y') && (key!='\r') && (key!=' '))
  100.             {
  101.                 neubauten=0; /* no enter return */
  102.                 break;
  103.             }
  104.             if(key<0)
  105.                 break;
  106.             out_printf("\n");
  107.         }
  108.         line++;
  109.     }
  110.     fclose(txt);
  111.  
  112.     if(key<0)
  113.         return BBSFAIL;
  114.     else if(capture)
  115.         more(text,0);
  116.     
  117.     if(domore && neubauten)
  118.     {
  119.         out_printf("\nEnter [Return].\n");
  120.         if(getkey()<0)
  121.             return BBSFAIL;
  122.     }
  123.     
  124.     return BBSOK;
  125. }
  126.  
  127. /* ======================================================= DOWNLOAD */
  128.  
  129. int upload(char *path)
  130. {
  131.     char temp[BBSSTR];
  132.     int ret;
  133.     
  134.     out_printf(CLS_STRING);
  135.     
  136.     if(is_uguest())
  137.     {
  138.         out_printf("Guest user can't upload\n[Return]\n");
  139.         getkey();
  140.         return BBSOK;
  141.     }
  142.     
  143.     out_printf( "\nEnter the name and description of the file who wanna upload or\n"
  144.             "or enter to abort (example: \"unix.c PD source for a Unix system Vr5 clone\"\n>");
  145.     if(getstring(temp)==BBSFAIL)
  146.         return BBSFAIL;
  147.     if(strlen(temp)<5)
  148.         return BBSFAIL;
  149.     
  150.     logline(2,"User trying to upload %s",temp);
  151.     ret=z_upload(path);
  152.     logline(2,"User %s uploaded a file (protocol return=%d)",get_uname(),ret);
  153.     
  154.     return BBSOK;    
  155. }
  156.  
  157. void do_download(char *file)
  158. {
  159.     long zesize;
  160.     int ret;
  161.     struct stat mystat;
  162.         
  163.     if(stat(file,&mystat))
  164.     {
  165.         out_printf("\nFile does not exist in this area! Hit [Return]\n");
  166.         getkey();
  167.     }
  168.     else if(strchr(file,'*') || strchr(file,'?') || strchr(file,' '))
  169.     {
  170.         out_printf("\nWildcards and multiple files not allowed. Hit [Return]\n");
  171.         getkey();
  172.     }
  173.     else
  174.     {    
  175.         zesize=mystat.st_size/1024;
  176.         if(get_ucredit((int) zesize)==BBSFAIL)
  177.         {
  178.             out_printf("\nFile too large for today, try again later. Hit a key.\n\n");
  179.             getkey();
  180.             logline(3,"User tried to download over his/her credit limit! (size=%ld kb)",
  181.                     zesize);
  182.         }
  183.         else
  184.         {
  185.             ret=z_download(file);
  186.             logline(3,"User downloaded file %s - %ld kb (protocol return=%d)",
  187.                     file, zesize, ret); 
  188.         }
  189.     }
  190. }
  191.  
  192. int download(char *area)
  193. {
  194.     int line=1,key;
  195.     struct stat mystat;
  196.     char area2[BBSSTR];
  197.     char *temp;
  198.     char file[BBSSTR];
  199.     char filebbs[BBSSTR];
  200.     FILE *fbbs;
  201.     int flag=0,domore=0;
  202.     
  203.     /* clean copy of area */
  204.     strcpy(area2,area);
  205.     addslash(area2);
  206.     
  207.     strcpy(filebbs,area2);
  208.     strcat(filebbs,FILESBBS);
  209.     
  210.     fbbs=fopen(filebbs,"r");
  211.     if(!fbbs)
  212.     {
  213.         logline(1,"Can't find files.bbs in area %s",area);
  214.         return BBSFAIL;
  215.     }
  216.     
  217.     temp=malloc(BBSSTR*10);
  218.     if(!temp)
  219.     {
  220.         logline(1,"Can't malloc temp buffer in download()");
  221.         return BBSFAIL;
  222.     }
  223.     
  224.     out_printf(CLS_STRING);
  225.     
  226.     while(!flag)
  227.     {
  228.         if(fgets(temp,BBSSTR*5,fbbs))
  229.         {
  230.             if(!isalnum(*temp)) /* thats a comment */
  231.             {
  232.                 if(strlen(temp)>75)
  233.                     strcpy(temp+72,"\n");
  234.                 out_string(temp);
  235.             }
  236.             else
  237.             { /* that's a file name */
  238.                 char filen[BBSSTR];
  239.                 char unknown[BBSSTR];
  240.                 char date[BBSSTR];
  241.                 char *desc;
  242.                 int lastspace,idx,lastcut;
  243.             
  244.                 strcpy(unknown,"-none-");
  245.                 
  246.                 strcpy(file,area2); /* file <area>\<file> */
  247.                 strspacecpy(filen,temp);
  248.                 strcat(file,filen);
  249.             
  250.                 desc=nextstr(temp); /* desc: description */
  251.                 if(!desc) desc=unknown;
  252.                 strcln(desc,-1);
  253.             
  254.                 /* multiline */
  255.                 idx=0;
  256.                 lastspace=0;
  257.                 lastcut=0;
  258.                 while(desc[idx])
  259.                 {
  260.                     if(line%MORELINE==0)
  261.                         domore++;
  262.                     if(desc[idx]==' ')
  263.                         lastspace=idx;
  264.                 
  265.                     if((idx-lastcut)>FBBSCUTLEN)
  266.                     {
  267.                         int j;
  268.  
  269.                         for(j=0;j<FBBSSTART;j++)
  270.                             strspins(desc+lastspace+1+j);
  271.                         desc[lastspace+1]='\n';
  272.                         lastcut=idx=lastspace+FBBSSTART;
  273.                         
  274.                         line++;
  275.                     }
  276.                     idx++;
  277.                 }
  278.                 
  279.                 if(stat(file,&mystat))
  280.                     out_printf("%-12.12s *** MISSING *** %s\n",filen,desc);
  281.                 else
  282.                 {
  283.                     strftime(date,BBSSTR,"%d %b %y",localtime(&mystat.st_ctime));
  284.                     out_printf("%-12.12s %6ld %s %s\n",filen,(long) mystat.st_size,date,desc);
  285.                 }
  286.             }
  287.         }
  288.         else
  289.             flag++;
  290.             
  291.         /* MORE PROMPT */
  292.         if(line%MORELINE==0 || flag || domore)
  293.         {
  294.             domore=0;
  295.             out_printf("\nMore? [Y]es [N]o [Z]modem download ");
  296.             key=tolower(getkey());
  297.             
  298.             if(key=='z')
  299.             { /* download */
  300.                 if(is_uguest())
  301.                 {
  302.                     out_printf("\nGuest user can't download!\n[Return]\n");
  303.                     getkey();
  304.                 }
  305.                 else
  306.                 {
  307.                     out_printf("\n\nEnter the name of the file you want to download with Zmodem:\n>");
  308.                     if(getstring(temp)==BBSOK)
  309.                     {
  310.                         strcpy(file,area2);
  311.                         strcat(file,temp);
  312.                         if(strlen(temp)>1) /* a name */
  313.                         {    
  314.                             do_download(file);
  315.                             break; /* quit */
  316.                         }
  317.                     } /* getstring */
  318.                 } /* guest */
  319.             } /* download */
  320.             
  321.             if(key!='y')
  322.                 break;
  323.             if(key<0)
  324.                 break;
  325.             out_printf("\n");
  326.         } /* more */
  327.         line++;
  328.     } /* lines */
  329.  
  330.     free(temp);
  331.     fclose(fbbs);
  332.     
  333.     return BBSOK;
  334. }
  335.  
  336. void global_download(char *config)
  337. {
  338.     char temp[BBSSTR],user_pat[BBSSTR],file[BBSSTR];
  339.     FILE *pof;
  340.     DIR *mydir;
  341.     struct dirent *ent;
  342.     int stop_search=0;
  343.     
  344.     int file_found=0;
  345.     char *file_ptr;
  346.     char file_temp[BBSSTR];    
  347.     char file_dname[BBSSTR];
  348.     
  349.     if(is_uguest())
  350.     {
  351.         out_printf("Guest user can't download. Hit [Return].\n\n");
  352.         getkey();
  353.         return;
  354.     }
  355.     if(!config[0])
  356.     {
  357.         logline(3,"No global download config file!");
  358.         return;
  359.     }
  360.     
  361.     out_printf(CLS_STRING);
  362.     out_printf("\nGlobal downloading: scan the hardisk for a file (<return> to exit).\n\n"
  363.             "Please enter the name of the file you want to \ndownload (example: THING*.LZH)\n\n>");
  364.     if(getstring(user_pat)==BBSOK)
  365.     {
  366.         if(strlen(user_pat)<4)
  367.         {
  368.             if(strlen(user_pat)!=0)
  369.             {
  370.                 out_printf("Name too short! Hit a key.\n");
  371.                 getkey();
  372.             }
  373.         }
  374.         else
  375.         {
  376.             out_printf("\n\n");
  377.             
  378.             pof=fopen(config,"r");
  379.             if(pof)
  380.             {
  381.                 while(fgets(temp,BBSSTR,pof) && !stop_search)
  382.                 {
  383.                     strcln(temp,-1);
  384.                     if(temp[0]!=0 && temp[0]!='#' 
  385.                         && temp[0]!=';' && temp[0]!='@')
  386.                     {/* pof line is a path */
  387.                         addslash(temp);
  388.                         out_printf("Searching in %s\n",temp);
  389.                         
  390.                         mydir=opendir(temp);
  391.                         if(!mydir)
  392.                             logline(2,"Bad directory %s",temp);
  393.                         else
  394.                         {
  395.                             while( ((ent=readdir(mydir))!=NULL) 
  396.                                     && (!stop_search))
  397.                             {
  398.                                 file_found=0; /* reset file */
  399.                                 
  400.                                 /* is it a file we search? */
  401.                                 file_ptr=user_pat;
  402.                                 do {
  403.                                     strspacecpy(file_temp,file_ptr);
  404.                                     strcpy(file_dname,ent->d_name);
  405. #ifndef CASE_SENSITIVE
  406.                                     strlwr(file_temp);
  407.                                     strlwr(file_dname);
  408. #endif                                    
  409.                                     if(match(file_temp,file_dname)==TRUE)
  410.                                         file_found++;
  411.                                 } while((file_ptr=nextstr(file_ptr))!=NULL);
  412.                                 
  413.                                 
  414.                                 if(file_found)
  415.                                 {/* got it */
  416.                                     int key;
  417.                                                                     
  418.                                     out_printf("Found %s: [A]bort [C]ontinue [Z]modem download ?",ent->d_name);
  419.                                     key=tolower(getkey());
  420.                                     out_printf("\n");
  421.                                     switch(key)
  422.                                     {
  423.                                         case 'c':
  424.                                         case ' ':
  425.                                         case '\r':
  426.                                         break;
  427.                                         case 'z':
  428.                                         strcpy(file,temp);
  429.                                         strcat(file,ent->d_name);
  430.                                         do_download(file);
  431.                                         break;
  432.                                         default:
  433.                                         case 'a':
  434.                                         stop_search++;
  435.                                         break;
  436.                                     }
  437.                                 }
  438.                             }
  439.                             closedir(mydir);
  440.                         }
  441.                     }
  442.                 }
  443.                 fclose(pof);
  444.             }
  445.         }
  446.     }
  447. }
  448.  
  449. /* ================================================================= MAIL */
  450.  
  451. int readmail(char *command, char *netmail, char *fromaddr, int okwrite)
  452. {
  453.     ECHOLIST *entry;
  454.     
  455.     out_printf(CLS_STRING);
  456.     
  457.     if(stricmp(command,"_private"))
  458.     { /* echomail */
  459.         do {
  460.             out_printf(CLS_STRING);
  461.             out_printf("Read an echomail area....\n\n");
  462.             entry=choose_area(command);
  463.             if(entry)
  464.                 read_messages(entry->name, entry->file, get_uname(), fromaddr, 0, okwrite);
  465.         } while(entry);
  466.     }
  467.     else
  468.     { /* netmail */
  469.         if(is_uguest())
  470.         {
  471.             out_printf("Guest user can't read netmail. Hit [Return]\n");
  472.             getkey();
  473.         }
  474.         else
  475.         {
  476.             /* logline(5,"User reading netmail"); */
  477.             read_messages("* Netmail *",netmail,get_uname(),fromaddr,1,1);
  478.             /* init mail prompt */
  479.             reset_new_mail();
  480.         }
  481.     }
  482.     return BBSOK;
  483. }
  484.  
  485. /*
  486.  *    Write a mail message
  487.  */
  488.  
  489. int writemail(char *command, char *netmail, char *fromaddr, char *uucpgate)
  490. {
  491.     char toaddr[BBSSTR],name[BBSSTR],subject[BBSSTR];
  492.     int private=0;
  493.     int errorfl=0;
  494.     ECHOLIST *entry;
  495.     
  496.     out_printf(CLS_STRING);
  497.     if(is_uguest())
  498.     {
  499.         out_printf("Guest user can't write mail.\n\n[Return]\n");
  500.         getkey();
  501.         return BBSOK;
  502.     }
  503.     
  504.     logline(5,"User trying to write mail (%s)",command);
  505.     
  506.     strcpy(toaddr,fromaddr); /* deflt */
  507.     
  508.     if(!strcmp(command,"_sysop") || !strcmp(command,"_local") || !strcmp(command,"_fido") || !strcmp(command,"_uucp"))
  509.     {    
  510.         private++;
  511.         out_printf("\nLazyBBS Mail - Send a private mail\n\n\n");
  512.     
  513.         if(!strcmp(command,"_sysop"))
  514.         {
  515.             out_printf("Mail to sysop.\n");
  516.             strcpy(name,"Sysop");
  517.         }
  518.         else
  519.         { 
  520.             /* get to name */
  521.             if(!strcmp(command,"_uucp"))
  522.                 out_printf("\nEnter INTERNET address of recipient (Example: \"cynthia@lazy.com\")\n>");
  523.             else
  524.                 out_printf("\nWrite the name of the recipient of the message (example: \"Amelie.Cecile Vloupf\")\n>");
  525.                 
  526.             if(getstring(name)==BBSFAIL)
  527.                 return BBSFAIL;
  528.             out_printf("\n");
  529.             
  530.             /* no name? */
  531.             if(strlen(name)<5)
  532.                 return BBSFAIL;
  533.             
  534.             if(strlen(name)>35)
  535.             {
  536.                 out_printf("Name too long! Hit a key.\n");
  537.                 getkey();
  538.                 return BBSFAIL;
  539.             }
  540.         }
  541.     
  542.         if(strcmp(command,"_sysop") && strcmp(command,"_local") && strcmp(command,"_uucp"))
  543.         { /* get to address */
  544.             out_printf("\n\nWrite the fidonet address of the recipient of\n"
  545.                     "the message (example: \"2:345/678.0\")\n>");
  546.             if(getstring(toaddr)==BBSFAIL)
  547.                 return BBSFAIL;
  548.                 
  549.             if((strlen(toaddr)<5) || (strlen(toaddr)>30))
  550.                 return BBSFAIL;
  551. /* fixme: check nodelist? */
  552.         }
  553.         
  554.         if(!strcmp(command,"_uucp"))
  555.             strcpy(toaddr,uucpgate);
  556.     }
  557.     else
  558.     { /* echomail */
  559.         out_printf("Write an echomail message to area....\n\n");
  560.         entry=choose_area(command);
  561.         if(!entry)
  562.             return BBSFAIL;
  563.         strcpy(name,"All");
  564.     }
  565.     
  566.     out_printf("\n\nSubject of the message? (example: \"How are you?\")\n>");
  567.     if(getstring(subject)==BBSFAIL)
  568.         return BBSFAIL;
  569.         
  570.     if(strlen(subject)<3)
  571.         return BBSFAIL;
  572.         
  573.     if(strlen(subject)>69)
  574.     {
  575.         out_printf("Subject too long. Message canceled. Hit [Return].\n");
  576.         getkey();
  577.         return BBSFAIL;
  578.     }
  579.     
  580.     out_printf(CLS_STRING);
  581.     
  582.     out_printf("    This will be a %s message to %s.\n",private ? "PRIVATE" : "*PUBLIC*",
  583.                 private ? name : entry->name);
  584.     out_printf("    Subject: %s.\n",subject);
  585.  
  586.     if(!strcmp(command,"_uucp"))
  587.     {
  588.         FILE *truc;
  589.         truc=fopen(tempfile(),"w");
  590.         if(!truc)
  591.             return BBSFAIL;
  592.         fprintf(truc,"To: %s",name);
  593.         fclose(truc);
  594.         strcpy(toaddr,uucpgate);
  595.         strcpy(name,"Uucp");
  596.     }    
  597.     
  598.     if(edit_file(tempfile())==BBSFAIL)
  599.         errorfl++;
  600.     else
  601.     {
  602.         out_printf("\n\nDo you want to send your mail to %s on %s? [Y/n]\n",
  603.             name, private ? toaddr : entry->name);
  604.         
  605.         if(tolower(getkey())!='n')
  606.         {    
  607.             if(private)
  608.                 logline(2,"User %s wrote private mail to %s @ %s",get_uname(),name,toaddr);
  609.             else
  610.                 logline(2,"User wrote echomail in area %s",entry->name);
  611.  
  612.             postmsg(get_uname(),fromaddr,name,toaddr,subject,
  613.                 private ? netmail : entry->file, tempfile(), private);
  614.         }
  615.     }    
  616.     
  617.     remove(tempfile());
  618.     if(errorfl)
  619.         return BBSFAIL;
  620.     return BBSOK;
  621. }
  622.  
  623. /* =================================================== MENU PROCESSOR */
  624.  
  625. void lazyprompt(char *pr)
  626. {
  627.     int i;
  628.     if(!pr || !*pr)
  629.         return;
  630.         
  631.     for(i=0;i<strlen(pr)-1;i++)
  632.         out_char('=');
  633.     out_char('>');
  634.     for(i=0;i<strlen(pr);i++)
  635.         out_char('\b');
  636.     out_string(pr);
  637.     out_char(' ');
  638. }
  639.  
  640. int domenu(char *menu, char *command, char *prompt)
  641. {
  642.     FILE *txt;
  643.     int curkey=0,found=0,i,userkey;
  644.     struct domenuKey {
  645.         int key;
  646.         char command[BBSSTR];
  647.     } *keys;
  648.     char oneline[BBSSTR];
  649.     
  650.     *command=0;
  651.         
  652.     if(!menu)
  653.         return BBSFAIL;
  654.  
  655.     keys=malloc(MAXKEYS*sizeof(struct domenuKey));
  656.     if(!keys)
  657.         return BBSFAIL;
  658.     
  659.     txt=fopen(menu,"r");
  660.     if(!txt)
  661.     {
  662.         free(keys);
  663.         return BBSFAIL;
  664.     }
  665.     
  666.     out_printf(CLS_STRING);
  667.     /* display remaining time at the top menu */
  668.     out_printf("%d mn ",(get_endsession()-clock())/(CLK_TCK*60));
  669.     /* display mail reminder */
  670.     if(has_new_mail())
  671.         out_printf("Mail! ");        
  672.     
  673.     while(fgets(oneline,BBSSTR,txt))
  674.     {
  675.         if(strlen(oneline)>79)
  676.             strcpy(oneline+78,"\n");
  677.         
  678.         if(strncmp(oneline,"$/",2) && strncmp(oneline,"$#",2))
  679.             out_string(oneline);
  680.         else 
  681.         { /* that's a key */
  682.             strcln(oneline,-1);
  683.  
  684. #ifdef OLD_CODE
  685.             if(curkey<MAXKEYS)
  686.             {
  687.                 if(strlen(oneline)>4);
  688.                 {
  689.                     keys[curkey].key=tolower(oneline[2]);
  690.                     strcpy(keys[curkey].command,oneline+4);
  691.                     curkey++;
  692.                 }
  693.             }
  694. #else
  695.             if(curkey<MAXKEYS)
  696.             {
  697.                 int i=1;
  698.                 int userhasfl=0;
  699.                 int thereisfl=0;
  700.                 
  701.                 while(oneline[i])
  702.                 {
  703.                     if(oneline[i]=='/') /* end of flags */
  704.                     {
  705.                         if(oneline[i+1] && (oneline[i+2]=='=') && oneline[i+3])
  706.                         {
  707.                             keys[curkey].key=tolower(oneline[i+1]);
  708.                             if(!thereisfl || userhasfl!=0)
  709.                                 strcpy(keys[curkey].command,oneline+i+3);
  710.                             else
  711.                                 strcpy(keys[curkey].command,"_forbidden");
  712.                             curkey++;
  713.                         }
  714.                     }
  715.                     
  716.                     if(isalpha(oneline[i])) /* this is a flag */
  717.                     {
  718.                         thereisfl++;
  719.                         if(get_uflag(oneline[i])==BBSOK)
  720.                             userhasfl++;
  721.                     }
  722.                     
  723.                     i++;
  724.                 }
  725.             } /* END space in table */
  726. #endif
  727.         }
  728.     }
  729.     fclose(txt);
  730.     
  731.     lazyprompt(prompt);
  732.     
  733.     while(!found)
  734.     {
  735.         userkey=getkey();
  736.         if(userkey<0)
  737.             break;
  738. #ifdef CHAT_HOTKEY
  739.         if(user_key==CHAT_HOTKEY)
  740.             chat();
  741. #endif    
  742.         out_char(8); /* backspace to delete the key */
  743.     
  744.         for(i=0;i<curkey;i++)
  745.         {    
  746.             if(tolower(userkey)==keys[i].key)
  747.             {
  748.                 if(!strcmp(keys[i].command,"_forbidden"))
  749.                 {
  750.                     out_printf("\nYou must be granted access to this menu item.\n");
  751.                     lazyprompt(prompt);
  752.                 }
  753.                 else
  754.                 {
  755.                     strcpy(command,keys[i].command);
  756.                     found++;
  757.                 }
  758.             }
  759.         }
  760.     }
  761.     
  762.     free(keys);
  763.     
  764.     if(userkey<0)
  765.         return BBSFAIL;
  766.     return BBSOK;
  767. }
  768.  
  769. /* ============================================================ CHAT  */
  770.  
  771. int enablechat=0;
  772.  
  773. void chat(void )
  774. {
  775.     unsigned char truc;
  776.     
  777.     if(!enablechat)
  778.         return;
  779.         
  780.     logline(4,"Entering chat mode");
  781.     out_printf("\7"); /* call sysop */
  782.     
  783.     out_printf(CLS_STRING);
  784.     out_printf("Entered chat mode. Type '%' to exit.\n\n");
  785.     do {
  786.         truc=getkey();
  787.     } while(truc!='%' && truc!=3 && truc!=4);
  788. }
  789.  
  790. /* ================================================================== */
  791.  
  792. int main(int argc, char **argv)
  793. {
  794.     FILE *cf;
  795.     int i;
  796.     struct stat statbuf;
  797.     char llog[BBSSTR];
  798.     char aareas[BBSSTR];
  799.     char topmenu[BBSSTR];
  800.     char netarea[BBSSTR];
  801.     char prompt[BBSSTR];
  802.     char uugateway[BBSSTR];
  803.     char pof_file[BBSSTR];
  804.     char from[BBSSTR];
  805.     char temp[BBSSTR];
  806.     char *next;
  807.  
  808. #ifdef UNIX
  809.      /* set stdin in raw mode */
  810. #if 0
  811.       struct sgttyb buf;
  812.       ioctl (0, TIOCGETP, &buf);
  813.      buf.sg_flags |= RAW;
  814.       ioctl (0, TIOCSETP, &buf);
  815. #else
  816.      struct termios tios;
  817.      tcgetattr (0, &tios);
  818.      tios.c_lflag&= ~(ICANON+ECHOCTL);
  819.      tcsetattr (0, TCSANOW, &tios);
  820. #endif
  821. #endif
  822.     
  823.     /* default values */    
  824.     strcpy(llog,DEFLOGFILE);
  825.     strcpy(aareas,AREASFILE);
  826.     strcpy(netarea,"netmail");
  827.     strcpy(from,"2:345/678.9");
  828.     strcpy(prompt,"LazyBBS>");
  829.     uugateway[0]=0;
  830.     pof_file[0]=0;
  831.  
  832.     /* init */
  833.     set_endsession(D_TIMEOUT);
  834.     strcpy(topmenu,TOPMENU);
  835.     
  836.     /* parse command line */
  837.     for(i=1;i<argc;i++)
  838.     {    
  839.         if(!stricmp(argv[i],"-c"))
  840.             enable_watch();
  841.         if(!strnicmp(argv[i],"-d",2))
  842.         {
  843.             if(sysdep_dupeio(argv[i]+2)==BBSFAIL)
  844.                 printf("Can't dupe I/O\n");
  845.             enablechat++;
  846.         }
  847.         if(!stricmp(argv[i],"-g"))
  848.             setgod();
  849.     }
  850.         
  851.     /* read config file */
  852.     cf=fopen(CONFIGFILE,"r");
  853.     if(!cf)
  854.         printf("Can't read config file! Using default values\n");
  855.     else
  856.     {
  857.         while(fgets(temp,BBSSTR,cf))
  858.         {
  859.             strcln(temp,-1);
  860.             next=nextstr(temp);
  861.             if(next && !iscomment(*temp))
  862.             {
  863.                 if(!strnicmp(temp,"address",strlen("address")))
  864.                     strspacecpy(from,next);
  865.                 else if(!strnicmp(temp,"prompt",strlen("prompt")))
  866.                     strspacecpy(prompt,next);
  867.                 else if(!strnicmp(temp,"logfile",strlen("logfile")))
  868.                     strspacecpy(llog,next);
  869.                 else if(!strnicmp(temp,"areascfg",strlen("areascfg")))
  870.                     strspacecpy(aareas,next);
  871.                 else if(!strnicmp(temp,"netmail",strlen("netmail")))
  872.                     strspacecpy(netarea,next);
  873.                 else if(!strnicmp(temp,"uucpgate",strlen("netmail")))
  874.                     strspacecpy(uugateway,next);
  875.                 else if(!strnicmp(temp,"global",strlen("global")))
  876.                     strspacecpy(pof_file,next);
  877.                 else if(!strnicmp(temp,"maxdown",strlen("maxdown")))
  878.                     set_maxdown(atoi(next));
  879.                 else if(!strnicmp(temp,"maxtime",strlen("maxtime")))
  880.                     set_endsession(atoi(next));
  881.             }
  882.         }
  883.         fclose(cf);
  884.     }
  885.     
  886.     /* set net area ptr for other modules */
  887.     set_netarea(netarea);
  888.     
  889.     /* init */
  890.     open_the_log(llog,0);
  891.     logline(4,"LazyBBS version %s started.",LAZYVERS);
  892.  
  893.     more(INTRO,0); /* optional welcome page */
  894.     
  895.     if(open_login()==BBSFAIL)
  896.     {
  897.         logline(1,"Login failed");
  898.         close_the_log();
  899.         return 10;
  900.     }
  901.     
  902.     if(get_areas(aareas)==BBSFAIL)
  903.         logline(1,"Can't read areas.bbs");
  904.     
  905.     /* print 1st page */
  906.     if(more(WELCOME,1)!=BBSOK)
  907.         logline(2,"Can't display welcome page");
  908.     
  909.     /* hotnews */
  910.     if(!stat(HOTNEWS,&statbuf))
  911.     {    /* there's hotnews */
  912.         if((timet2nix(statbuf.st_mtime)/86400)>=get_ulastlogin())
  913.             more(HOTNEWS,1);
  914.     }
  915.     
  916.     /* start menu processor */
  917.     {
  918.         char comline[BBSSTR];
  919.         char command[BBSSTR];
  920.         char curmenu[BBSSTR];
  921.         char *parameter;
  922.         int status=BBSOK;
  923.         
  924.         strcpy(curmenu,topmenu);
  925.         
  926.         while(1)
  927.         {
  928.             if(domenu(curmenu,comline,prompt)==BBSFAIL)
  929.                 break;
  930.  
  931.             /* else command valid */
  932.             parameter=nextstr(comline); /* parse! */
  933.             if(parameter)
  934.                 strspacecpy(command,comline);
  935.             else
  936.                 strcpy(command,comline);
  937.                 
  938.             if(!stricmp(command,"top"))
  939.                 strcpy(curmenu,topmenu);
  940.             else if(!stricmp(command,"gdown"))
  941.                 global_download(pof_file);
  942.             else if(!stricmp(command,"hangup"))
  943.                 break;
  944.             else if(!stricmp(command,"chat"))
  945.                 chat();
  946.             else if(!stricmp(command,"info"))
  947.             {
  948.                 out_printf(CLS_STRING);
  949.                 out_printf("LazyBBS - The Ultimate BBS for Lazy People\n\n"
  950.                         "Version    : %s\nCompiled on: %s\nPlatform   : %s\n\n",
  951.                         LAZYVERS,__DATE__,MACHINE);
  952.                 out_printf("Squeeze [Return]\n");
  953.                 getkey();
  954.             }
  955.             else if(!stricmp(command,"userinfo"))
  956.                 display_login();
  957.             else if(!stricmp(command,"password"))
  958.                 change_password();
  959.             else if(!parameter) /* only parametred command staying */
  960.                 logline(1,"syntax error in %s",curmenu);
  961.             else if(!stricmp(command,"more"))
  962.                 status=more(parameter,1); 
  963.             else if(!stricmp(command,"menu"))
  964.                 strcpy(curmenu,parameter);
  965.             else if(!stricmp(command,"read"))
  966.                 status=readmail(parameter,netarea,from,0);
  967.             else if(!stricmp(command,"readw"))
  968.                 status=readmail(parameter,netarea,from,1);
  969.             else if(!stricmp(command,"download"))
  970.                 status=download(parameter);
  971.             else if(!stricmp(command,"write"))
  972.                 status=writemail(parameter,netarea,from,uugateway);
  973.             else if(!stricmp(command,"upload"))
  974.                 status=upload(parameter);
  975.             else
  976.             {
  977.                 logline(1,"Unknown command in %s (%s)",comline,curmenu);
  978.                 break;
  979.             }
  980.         }
  981.     }
  982.     
  983.     if(more(BYE,0)!=BBSOK)
  984.         logline(2,"Bye error");
  985.             
  986.     the_end();
  987.     return 0;
  988. }
  989.  
  990. /*eof*/