/* * LazyBBS - The Ultimate BBS for Lazy People * ------------------------------------------ * * LazyBBS is a very simple BBS program for a Pandora Fidonet * message base (used by Led, Qbbs, Bermuda, IOS, etc on the Atari * ST). And FILES.BBS-like download areas. It should be portable * on most operating systems supporting unix-like libraries, * ANSI C libraries and compilers. It is especially useful * with the Fidonet package "Bermuda". The code is ugly, but * that's LAZYbbs :-). * * Public domain: this program may be copied and sold freely. * Suggestion: read the fine manual & state on modified versions * that these are not the original version and change the version * string in bbs.h. * * Porting: * 1) edit sysdep.c bbs.h * 2) compile sysdep.c miscio.c login.c linedit.c match.c msg.c bbs.c * 3) link to bbs */ #include #include #include #include #include #include #include /* POSIX directory for download */ #include /* for download's stat() */ #include #ifdef UNIX #include /* for raw mode */ #include #endif #include "bbs.h" /* constants & config */ #include "match.h" /* regular expression library */ #include "linedit.h" /* line editor module */ #include "login.h" /* login module */ #include "msg.h" /* message module */ #include "sysdep.h" /* LEVEL 0: low level, in main and download */ #include "miscio.h" /* LEVEL 1: Misc and IO */ #define DEBUG /**/ #ifdef LATTICE /* for atari Lattice C 5 */ unsigned long _STACK=16000; #endif /* =================================================== PROTOTYPES */ int more(char *, int ); int upload(char *); void do_download(char *); int download(char *); void global_download(char *); int readmail(char *,char *,char *,int ); int writemail(char *,char *,char *,char *); void lazyprompt(char *); int domenu(char *,char *,char *); void chat(void); int main(int, char **); /* ============================================================= MORE */ int more(char *text, int domore) { char oneline[BBSSTR]; FILE *txt; int line=1,capture=0,key=1,neubauten=1; if(!text) return BBSFAIL; txt=fopen(text,"r"); if(!txt) return BBSFAIL; out_printf(CLS_STRING); while(fgets(oneline,BBSSTR,txt)) { if(strlen(oneline)>79) strcpy(oneline+78,"\n"); out_string(oneline); if(line%MORELINE==0 && domore) { /* prompt */ out_printf("\nMore? [Y]es [N]o [C]apture "); key=tolower(getkey()); if(key=='c') capture++; if((key!='y') && (key!='\r') && (key!=' ')) { neubauten=0; /* no enter return */ break; } if(key<0) break; out_printf("\n"); } line++; } fclose(txt); if(key<0) return BBSFAIL; else if(capture) more(text,0); if(domore && neubauten) { out_printf("\nEnter [Return].\n"); if(getkey()<0) return BBSFAIL; } return BBSOK; } /* ======================================================= DOWNLOAD */ int upload(char *path) { char temp[BBSSTR]; int ret; out_printf(CLS_STRING); if(is_uguest()) { out_printf("Guest user can't upload\n[Return]\n"); getkey(); return BBSOK; } out_printf( "\nEnter the name and description of the file who wanna upload or\n" "or enter to abort (example: \"unix.c PD source for a Unix system Vr5 clone\"\n>"); if(getstring(temp)==BBSFAIL) return BBSFAIL; if(strlen(temp)<5) return BBSFAIL; logline(2,"User trying to upload %s",temp); ret=z_upload(path); logline(2,"User %s uploaded a file (protocol return=%d)",get_uname(),ret); return BBSOK; } void do_download(char *file) { long zesize; int ret; struct stat mystat; if(stat(file,&mystat)) { out_printf("\nFile does not exist in this area! Hit [Return]\n"); getkey(); } else if(strchr(file,'*') || strchr(file,'?') || strchr(file,' ')) { out_printf("\nWildcards and multiple files not allowed. Hit [Return]\n"); getkey(); } else { zesize=mystat.st_size/1024; if(get_ucredit((int) zesize)==BBSFAIL) { out_printf("\nFile too large for today, try again later. Hit a key.\n\n"); getkey(); logline(3,"User tried to download over his/her credit limit! (size=%ld kb)", zesize); } else { ret=z_download(file); logline(3,"User downloaded file %s - %ld kb (protocol return=%d)", file, zesize, ret); } } } int download(char *area) { int line=1,key; struct stat mystat; char area2[BBSSTR]; char *temp; char file[BBSSTR]; char filebbs[BBSSTR]; FILE *fbbs; int flag=0,domore=0; /* clean copy of area */ strcpy(area2,area); addslash(area2); strcpy(filebbs,area2); strcat(filebbs,FILESBBS); fbbs=fopen(filebbs,"r"); if(!fbbs) { logline(1,"Can't find files.bbs in area %s",area); return BBSFAIL; } temp=malloc(BBSSTR*10); if(!temp) { logline(1,"Can't malloc temp buffer in download()"); return BBSFAIL; } out_printf(CLS_STRING); while(!flag) { if(fgets(temp,BBSSTR*5,fbbs)) { if(!isalnum(*temp)) /* thats a comment */ { if(strlen(temp)>75) strcpy(temp+72,"\n"); out_string(temp); } else { /* that's a file name */ char filen[BBSSTR]; char unknown[BBSSTR]; char date[BBSSTR]; char *desc; int lastspace,idx,lastcut; strcpy(unknown,"-none-"); strcpy(file,area2); /* file \ */ strspacecpy(filen,temp); strcat(file,filen); desc=nextstr(temp); /* desc: description */ if(!desc) desc=unknown; strcln(desc,-1); /* multiline */ idx=0; lastspace=0; lastcut=0; while(desc[idx]) { if(line%MORELINE==0) domore++; if(desc[idx]==' ') lastspace=idx; if((idx-lastcut)>FBBSCUTLEN) { int j; for(j=0;j"); if(getstring(temp)==BBSOK) { strcpy(file,area2); strcat(file,temp); if(strlen(temp)>1) /* a name */ { do_download(file); break; /* quit */ } } /* getstring */ } /* guest */ } /* download */ if(key!='y') break; if(key<0) break; out_printf("\n"); } /* more */ line++; } /* lines */ free(temp); fclose(fbbs); return BBSOK; } void global_download(char *config) { char temp[BBSSTR],user_pat[BBSSTR],file[BBSSTR]; FILE *pof; DIR *mydir; struct dirent *ent; int stop_search=0; int file_found=0; char *file_ptr; char file_temp[BBSSTR]; char file_dname[BBSSTR]; if(is_uguest()) { out_printf("Guest user can't download. Hit [Return].\n\n"); getkey(); return; } if(!config[0]) { logline(3,"No global download config file!"); return; } out_printf(CLS_STRING); out_printf("\nGlobal downloading: scan the hardisk for a file ( to exit).\n\n" "Please enter the name of the file you want to \ndownload (example: THING*.LZH)\n\n>"); if(getstring(user_pat)==BBSOK) { if(strlen(user_pat)<4) { if(strlen(user_pat)!=0) { out_printf("Name too short! Hit a key.\n"); getkey(); } } else { out_printf("\n\n"); pof=fopen(config,"r"); if(pof) { while(fgets(temp,BBSSTR,pof) && !stop_search) { strcln(temp,-1); if(temp[0]!=0 && temp[0]!='#' && temp[0]!=';' && temp[0]!='@') {/* pof line is a path */ addslash(temp); out_printf("Searching in %s\n",temp); mydir=opendir(temp); if(!mydir) logline(2,"Bad directory %s",temp); else { while( ((ent=readdir(mydir))!=NULL) && (!stop_search)) { file_found=0; /* reset file */ /* is it a file we search? */ file_ptr=user_pat; do { strspacecpy(file_temp,file_ptr); strcpy(file_dname,ent->d_name); #ifndef CASE_SENSITIVE strlwr(file_temp); strlwr(file_dname); #endif if(match(file_temp,file_dname)==TRUE) file_found++; } while((file_ptr=nextstr(file_ptr))!=NULL); if(file_found) {/* got it */ int key; out_printf("Found %s: [A]bort [C]ontinue [Z]modem download ?",ent->d_name); key=tolower(getkey()); out_printf("\n"); switch(key) { case 'c': case ' ': case '\r': break; case 'z': strcpy(file,temp); strcat(file,ent->d_name); do_download(file); break; default: case 'a': stop_search++; break; } } } closedir(mydir); } } } fclose(pof); } } } } /* ================================================================= MAIL */ int readmail(char *command, char *netmail, char *fromaddr, int okwrite) { ECHOLIST *entry; out_printf(CLS_STRING); if(stricmp(command,"_private")) { /* echomail */ do { out_printf(CLS_STRING); out_printf("Read an echomail area....\n\n"); entry=choose_area(command); if(entry) read_messages(entry->name, entry->file, get_uname(), fromaddr, 0, okwrite); } while(entry); } else { /* netmail */ if(is_uguest()) { out_printf("Guest user can't read netmail. Hit [Return]\n"); getkey(); } else { /* logline(5,"User reading netmail"); */ read_messages("* Netmail *",netmail,get_uname(),fromaddr,1,1); /* init mail prompt */ reset_new_mail(); } } return BBSOK; } /* * Write a mail message */ int writemail(char *command, char *netmail, char *fromaddr, char *uucpgate) { char toaddr[BBSSTR],name[BBSSTR],subject[BBSSTR]; int private=0; int errorfl=0; ECHOLIST *entry; out_printf(CLS_STRING); if(is_uguest()) { out_printf("Guest user can't write mail.\n\n[Return]\n"); getkey(); return BBSOK; } logline(5,"User trying to write mail (%s)",command); strcpy(toaddr,fromaddr); /* deflt */ if(!strcmp(command,"_sysop") || !strcmp(command,"_local") || !strcmp(command,"_fido") || !strcmp(command,"_uucp")) { private++; out_printf("\nLazyBBS Mail - Send a private mail\n\n\n"); if(!strcmp(command,"_sysop")) { out_printf("Mail to sysop.\n"); strcpy(name,"Sysop"); } else { /* get to name */ if(!strcmp(command,"_uucp")) out_printf("\nEnter INTERNET address of recipient (Example: \"cynthia@lazy.com\")\n>"); else out_printf("\nWrite the name of the recipient of the message (example: \"Amelie.Cecile Vloupf\")\n>"); if(getstring(name)==BBSFAIL) return BBSFAIL; out_printf("\n"); /* no name? */ if(strlen(name)<5) return BBSFAIL; if(strlen(name)>35) { out_printf("Name too long! Hit a key.\n"); getkey(); return BBSFAIL; } } if(strcmp(command,"_sysop") && strcmp(command,"_local") && strcmp(command,"_uucp")) { /* get to address */ out_printf("\n\nWrite the fidonet address of the recipient of\n" "the message (example: \"2:345/678.0\")\n>"); if(getstring(toaddr)==BBSFAIL) return BBSFAIL; if((strlen(toaddr)<5) || (strlen(toaddr)>30)) return BBSFAIL; /* fixme: check nodelist? */ } if(!strcmp(command,"_uucp")) strcpy(toaddr,uucpgate); } else { /* echomail */ out_printf("Write an echomail message to area....\n\n"); entry=choose_area(command); if(!entry) return BBSFAIL; strcpy(name,"All"); } out_printf("\n\nSubject of the message? (example: \"How are you?\")\n>"); if(getstring(subject)==BBSFAIL) return BBSFAIL; if(strlen(subject)<3) return BBSFAIL; if(strlen(subject)>69) { out_printf("Subject too long. Message canceled. Hit [Return].\n"); getkey(); return BBSFAIL; } out_printf(CLS_STRING); out_printf(" This will be a %s message to %s.\n",private ? "PRIVATE" : "*PUBLIC*", private ? name : entry->name); out_printf(" Subject: %s.\n",subject); if(!strcmp(command,"_uucp")) { FILE *truc; truc=fopen(tempfile(),"w"); if(!truc) return BBSFAIL; fprintf(truc,"To: %s",name); fclose(truc); strcpy(toaddr,uucpgate); strcpy(name,"Uucp"); } if(edit_file(tempfile())==BBSFAIL) errorfl++; else { out_printf("\n\nDo you want to send your mail to %s on %s? [Y/n]\n", name, private ? toaddr : entry->name); if(tolower(getkey())!='n') { if(private) logline(2,"User %s wrote private mail to %s @ %s",get_uname(),name,toaddr); else logline(2,"User wrote echomail in area %s",entry->name); postmsg(get_uname(),fromaddr,name,toaddr,subject, private ? netmail : entry->file, tempfile(), private); } } remove(tempfile()); if(errorfl) return BBSFAIL; return BBSOK; } /* =================================================== MENU PROCESSOR */ void lazyprompt(char *pr) { int i; if(!pr || !*pr) return; for(i=0;i'); for(i=0;i79) strcpy(oneline+78,"\n"); if(strncmp(oneline,"$/",2) && strncmp(oneline,"$#",2)) out_string(oneline); else { /* that's a key */ strcln(oneline,-1); #ifdef OLD_CODE if(curkey4); { keys[curkey].key=tolower(oneline[2]); strcpy(keys[curkey].command,oneline+4); curkey++; } } #else if(curkey"); uugateway[0]=0; pof_file[0]=0; /* init */ set_endsession(D_TIMEOUT); strcpy(topmenu,TOPMENU); /* parse command line */ for(i=1;i=get_ulastlogin()) more(HOTNEWS,1); } /* start menu processor */ { char comline[BBSSTR]; char command[BBSSTR]; char curmenu[BBSSTR]; char *parameter; int status=BBSOK; strcpy(curmenu,topmenu); while(1) { if(domenu(curmenu,comline,prompt)==BBSFAIL) break; /* else command valid */ parameter=nextstr(comline); /* parse! */ if(parameter) strspacecpy(command,comline); else strcpy(command,comline); if(!stricmp(command,"top")) strcpy(curmenu,topmenu); else if(!stricmp(command,"gdown")) global_download(pof_file); else if(!stricmp(command,"hangup")) break; else if(!stricmp(command,"chat")) chat(); else if(!stricmp(command,"info")) { out_printf(CLS_STRING); out_printf("LazyBBS - The Ultimate BBS for Lazy People\n\n" "Version : %s\nCompiled on: %s\nPlatform : %s\n\n", LAZYVERS,__DATE__,MACHINE); out_printf("Squeeze [Return]\n"); getkey(); } else if(!stricmp(command,"userinfo")) display_login(); else if(!stricmp(command,"password")) change_password(); else if(!parameter) /* only parametred command staying */ logline(1,"syntax error in %s",curmenu); else if(!stricmp(command,"more")) status=more(parameter,1); else if(!stricmp(command,"menu")) strcpy(curmenu,parameter); else if(!stricmp(command,"read")) status=readmail(parameter,netarea,from,0); else if(!stricmp(command,"readw")) status=readmail(parameter,netarea,from,1); else if(!stricmp(command,"download")) status=download(parameter); else if(!stricmp(command,"write")) status=writemail(parameter,netarea,from,uugateway); else if(!stricmp(command,"upload")) status=upload(parameter); else { logline(1,"Unknown command in %s (%s)",comline,curmenu); break; } } } if(more(BYE,0)!=BBSOK) logline(2,"Bye error"); the_end(); return 0; } /*eof*/