/***************************************************************************** * * File ..................: bbs/menu.c * Purpose ...............: Display and handle the menus. * Last modification date : 10-Jul-2001 * ***************************************************************************** * Copyright (C) 1997-2001 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * MBSE BBS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ #include "../lib/libs.h" #include "../lib/mbse.h" #include "../lib/structs.h" #include "../lib/records.h" #include "../lib/common.h" #include "../lib/clcomm.h" #include "oneline.h" #include "mail.h" #include "bbslist.h" #include "change.h" #include "bank.h" #include "chat.h" #include "file.h" #include "funcs.h" #include "funcs4.h" #include "misc.h" #include "nextuser.h" #include "safe.h" #include "timeout.h" #include "menu.h" #include "page.h" #include "pinfo.h" #include "bye.h" #include "timecheck.h" #include "exitinfo.h" #include "language.h" #include "offline.h" #include "email.h" /* * Menu stack, 50 levels deep. */ char Menus[50][15]; int MenuLevel; int MenuError; void InitMenu() { int i; for (i = 0; i < 50; i++) memset(Menus[i], 0, 51); MenuLevel = 0; MenuError = 0; sprintf(Menus[0], "%s", CFG.default_menu); } void menu() { FILE *pMenuFile; int iFoundKey = FALSE, Key; char *Input, *Semfile; char *sMenuPathFileName; Input = calloc(81, sizeof(char)); sMenuPathFileName = calloc(PATH_MAX, sizeof(char)); /* * Loop forever, this is what a BBS should do until a user logs out. */ while (TRUE) { WhosDoingWhat(BROWSING); /* * Open menufile, first users language menu, if it fails * try to open the default menu. */ sprintf(sMenuPathFileName,"%s/%s", lang.MenuPath, Menus[MenuLevel]); if ((pMenuFile = fopen(sMenuPathFileName, "r")) == NULL) { sprintf(sMenuPathFileName,"%s/%s", CFG.bbs_menus, Menus[MenuLevel]); pMenuFile = fopen(sMenuPathFileName,"r"); if (pMenuFile != NULL) Syslog('+', "Menu %s (Default)", Menus[MenuLevel]); } else { Syslog('+', "Menu %s (%s)", Menus[MenuLevel], lang.Name); } if (pMenuFile == NULL) { clear(); WriteError("Can't open menu file: %s", sMenuPathFileName); MenuError++; /* * Is this the last attempt to open the default menu? */ if (MenuError == 10) { WriteError("FATAL ERROR: Too many menu errors"); printf("Too many menu errors, notifying Sysop\n\n"); sleep(3); die(SIGILL); } /* * Switch back to the default menu */ MenuLevel = 0; strcpy(Menus[0], CFG.default_menu); } else { /* * Do all autoexec menus first */ while (fread(&menus, sizeof(menus), 1, pMenuFile) == 1) { if (menus.AutoExec && Access(exitinfo.Security, menus.MenuSecurity) && (UserAge >= menus.Age)) DoMenu(menus.MenuType); } /* * Check if the BBS closed down for Zone Mail Hour or * system shutdown. If so, we run the Goodbye show. */ if (CheckStatus() == FALSE) { fclose(pMenuFile); Syslog('+', "Kicking user out, the BBS is closed."); sleep(3); Good_Bye(0); } /* * Check the upsdown semafore */ Semfile = calloc(PATH_MAX, sizeof(char)); sprintf(Semfile, "%s/sema/upsdown", getenv("MBSE_ROOT")); if (file_exist(Semfile, R_OK) == 0) { fclose(pMenuFile); Syslog('+', "Kicking user out, upsdown semafore detected"); printf("System power failure, closing the bbs\n\n"); free(Semfile); sleep(3); Good_Bye(0); } free(Semfile); /* * Check if SysOp wants to chat to user everytime user * gets prompt. Make sure /tmp/chatdev exists before * before calling chat(). Make sure if a second user * logs in, that .BusyChatting does exist. */ if(CFG.iChatPromptChk && (access("/tmp/chatdev", R_OK) == 0) && (access("/tmp/.BusyChatting", F_OK) != 0)) Chat(); /* * Check users timeleft */ TimeCheck(); alarm_on(); if (exitinfo.HotKeys) { fflush(stdout); Key = Getone(); sprintf(Input, "%c", Key); printf("\n"); } else { colour(CFG.InputColourF, CFG.InputColourB); GetstrC(Input, 80); } if((strcmp(Input, "")) != 0) { fseek(pMenuFile, 0, SEEK_SET); while (fread(&menus, sizeof(menus), 1, pMenuFile) == 1) { if ((strcmp(tu(Input), menus.MenuKey)) == 0) { if ((Access(exitinfo.Security, menus.MenuSecurity)) && (UserAge >= menus.Age)) { Syslog('b', "Menu[%d] %d=(%s), Opt: '%s'", MenuLevel, menus.MenuType, menus.TypeDesc, menus.OptionalData); if (menus.MenuType == 13) { /* * Terminate call, cleanup here */ free(Input); free(sMenuPathFileName); fclose(pMenuFile); } DoMenu(menus.MenuType); iFoundKey = TRUE; break; } } } } fclose(pMenuFile); } /* If menu open */ } /* while true */ } void DoMenu(int Type) { int Strlen, i, x; char *DisplayF; char *sPrompt; char *sPromptBak; char *temp; DisplayF = calloc(81, sizeof(char)); sPrompt = calloc(81, sizeof(char)); sPromptBak = calloc(81, sizeof(char)); temp = calloc(81, sizeof(char)); TimeCheck(); switch(Type) { case 1: /* Goto another menu */ strncpy(Menus[MenuLevel], menus.OptionalData, 14); break; case 2: /* Gosub another menu */ if (MenuLevel < 49) { MenuLevel++; strncpy(Menus[MenuLevel], menus.OptionalData, 14); } else Syslog('?', "More than 50 menu levels"); break; case 3: /* Return from gosub */ if (MenuLevel > 0) MenuLevel--; break; case 4: /* Return to top menu */ MenuLevel = 0; break; case 5: /* Display .a?? file with controlcodes */ DisplayFile(menus.OptionalData); break; case 6: /* Show menu prompt */ Strlen = strlen(menus.OptionalData); for(x = 0; x < Strlen; x++) { if( menus.OptionalData[x] == '~') { strcat(sPrompt, sUserTimeleft); } else { sprintf(temp, "%c", menus.OptionalData[x]); strcat(sPrompt, temp); } } strcpy(sPromptBak, sPrompt); strcpy(sPrompt, ""); Strlen = strlen(sPromptBak); for(x = 0; x < Strlen; x++) { if( *(sPromptBak + x) == '@') strcat(sPrompt, sAreaDesc); else if ( *(sPromptBak + x) == '^') strcat(sPrompt, sMsgAreaDesc); else if ( *(sPromptBak + x) == '#') sprintf(sPrompt, "%s%s", sPrompt, (char *) GetLocalHM()); else { sprintf(temp, "%c", *(sPromptBak + x)); strcat(sPrompt, temp); } } pout(15, 0, sPrompt); break; case 7: /* Run external program */ ExtDoor(menus.OptionalData, menus.NoDoorsys, menus.Y2Kdoorsys, menus.Comport); break; case 8: /* Show product information */ cr(); break; case 9: /* display todays callers */ LastCallers(menus.OptionalData); break; case 10: /* display userlist */ UserList(menus.OptionalData); break; case 11: /* display time statistics */ TimeStats(); break; case 12: /* page sysop for chat */ Page_Sysop(menus.OptionalData); break; case 13: /* terminate call */ free(DisplayF); free(sPrompt); free(sPromptBak); free(temp); Good_Bye(0); break; case 14: /* make a log entry */ LogEntry(menus.OptionalData); break; case 15: /* print text to screen */ if (exitinfo.Security.level >= menus.MenuSecurity.level) { for(i = 0; i < strlen(menus.OptionalData); i++) if(*(menus.OptionalData + i) == '@') *(menus.OptionalData + i) = '\n'; printf("%s\n", menus.OptionalData); } break; case 16: /* who's currently online */ WhosOn(menus.OptionalData); Pause(); break; case 17: /* comment to sysop */ SysopComment((char *)"Comment to Sysop"); break; case 18: /* send on-line message */ SendOnlineMsg(menus.OptionalData); break; case 19: /* display Textfile with more */ MoreFile(menus.OptionalData); break; case 20: /* display a?? file with controlcode and wait for enter */ DisplayFileEnter(menus.OptionalData); break; case 22: /* nextuser door */ nextuser(); break; case 23: /* timebank door */ Bank(); break; case 24: /* voting door Not anymore */ break; case 25: /* safe cracker door */ Safe(); break; case 101: FileArea_List(menus.OptionalData); break; case 102: File_List(); break; case 103: ViewFile(); break; case 104: Download(); break; case 105: File_RawDir(menus.OptionalData); break; case 106: KeywordScan(); break; case 107: FilenameScan(); break; case 108: NewfileScan(TRUE); break; case 109: Upload(); break; case 110: EditTaglist(); break; case 111: /* View file in homedir */ break; case 112: DownloadDirect(menus.OptionalData, TRUE); break; case 113: Copy_Home(); break; case 114: List_Home(); break; case 115: Delete_Home(); break; /* 116 Unpack file in homedir */ /* 117 Pack files in homedir */ case 118: Download_Home(); break; case 119: Upload_Home(); break; case 201: MsgArea_List(menus.OptionalData); break; case 202: Post_Msg(); break; case 203: Read_Msgs(); break; case 204: CheckMail(); break; case 205: QuickScan_Msgs(); break; case 206: Delete_Msg(); break; case 207: MailStatus(); break; case 208: OLR_TagArea(); break; case 209: OLR_UntagArea(); break; case 210: OLR_ViewTags(); break; case 211: OLR_RestrictDate(); break; case 212: OLR_Upload(); break; case 213: OLR_DownBW(); break; case 214: OLR_DownQWK(); break; case 215: OLR_DownASCII(); break; case 216: Read_Email(); break; case 217: Write_Email(); break; case 218: Trash_Email(); break; case 219: Choose_Mailbox(menus.OptionalData); break; case 220: QuickScan_Email(); break; case 301: Chg_Protocol(); break; case 302: Chg_Password(); break; case 303: Chg_Location(); break; case 304: Chg_Graphics(); break; case 305: Chg_VoicePhone(); break; case 306: Chg_DataPhone(); break; case 307: Chg_News(); break; case 308: Chg_ScreenLen(); break; case 309: Chg_DOB(); break; case 310: Chg_Language(FALSE); break; case 311: Chg_Hotkeys(); break; case 312: Chg_Handle(); break; case 313: Chg_MailCheck(); break; case 314: Chg_Disturb(); break; case 315: Chg_FileCheck(); break; case 316: Chg_FsMsged(); break; case 401: Oneliner_Add(); break; case 402: Oneliner_List(); break; case 403: Oneliner_Show(); break; case 404: Oneliner_Delete(); break; case 405: Oneliner_Print(); break; case 501: BBS_Add(); break; case 502: BBS_List(); break; case 503: BBS_Show(); break; case 504: BBS_Delete(); break; case 506: BBS_Search(); break; default: Enter(1); pout(15, 0, (char *) Language(339)); Enter(2); Syslog('?', "Option: %s -> Unknown Menu Type: %d on %s", menus.MenuKey, Type, Menus[MenuLevel]); Pause(); } free(DisplayF); free(sPrompt); free(sPromptBak); free(temp); }