home *** CD-ROM | disk | FTP | other *** search
- /*
- * MSGEDQ.C - Main program
- *
- * Msged/Q message editor for QuickBBS Copyright 1990 by P.J. Muller
- *
- */
-
- #include <process.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <dos.h>
- #if defined(__MSC__) || defined(__TURBOC__) || defined(__JPIC__)
- #include <fcntl.h>
- #endif
-
- #define MAIN
- #include "msged.h"
- #include "screen.h"
- #include "bmg.h"
- #include "maincmds.h"
- #include "qmsgbase.h"
- #include "shell.h"
-
- #if 0
- #ifdef __ZTC__
- unsigned _stack = 4096;
- #endif
- #endif
-
- #if defined(__TURBOC__)
- unsigned int _stklen = 4096; /* Turbo C min. stack size */
- #endif
-
- #ifdef __JPIC__
- int _ISDST = 0; /* hack */
- #endif
-
- #define ENDFREQ 550 /* Hz */
- #define ENDLEN 1 /* 1/18.2 s */
-
- #define S_HEAD 1
- #define S_TEXT 2
- #define S_BOTH (S_TEXT|S_HEAD)
-
- static void highest(void);
- static int command; /* keyboard command */
- static int direction = RIGHT;
- static int root = 0; /* root message of a thread */
- static int back = 0;
-
- static int start(int argc, char *argv[]);
- static void empty(void);
- static void gotomsg(int i);
- static void srch(int what); /* 1-header, 2-text, 3-both */
- static void toarea(int n);
- static void retry(void);
-
- void go_last()
- {
- setcur(CurBoard, lastreadmsg(CurBoard));
- root = curmsg(CurBoard);
- }
-
- void escquit()
- {
- if (confirm(confirmations))
- cleanup();
- }
-
- void deletemsg()
- {
- if (!confirm(confirmations))
- return;
-
- msgdelete(curmsg(CurBoard),arealist[area].echomail,arealist[area].netmail);
-
- if (direction == LEFT)
- left(); /* for Peter */
- }
-
- void link_from()
- {
- if (!msgat(CurBoard,message.header.reply))
- return;
-
- back = curmsg(CurBoard);
- setcur(CurBoard,message.header.reply);
- }
-
- void link_to()
- {
- if (!msgat(CurBoard,message.header.up))
- return;
-
- back = curmsg(CurBoard);
- setcur(CurBoard,message.header.up);
- }
-
- void marklast()
- {
- setlastread(CurBoard,curmsg(CurBoard));
- }
-
- void view()
- {
- shownotes = !shownotes;
- #ifdef SEENBY
- if (shownotes)
- seenbys = shownotes;
- #endif
- }
-
- void go_root()
- {
- if (!msgat(CurBoard,root))
- return;
-
- back = curmsg(CurBoard);
- setcur(CurBoard,root);
-
- highest();
- }
-
- void rotate()
- {
- rot13 = (rot13 + 1) % 4;
- }
-
- void togaddr()
- {
- techie = !techie;
- } /* togaddr */
-
- void go_dos()
- {
- #ifndef MINI
- os();
- #endif
- }
-
- void main(int argc, char *argv[])
- {
- arealist = NULL;
- msgbuf.first = NULL;
-
- #if defined(__MSC__) || defined(__TURBOC__) || defined(__JPIC__)
- _fmode = (unsigned int) O_BINARY; /* default open mode - binary */
- #endif
-
- command = start(argc,argv);
-
- while (1) { /* endless loop... exit is through cleanup */
- if (command & 0xff) {
- if (isdigit(command))
- gotomsg(command - 0x30);
- else if (mainckeys[command])
- mainckeys[command & 0xff]();
- }
- else if (mainakeys[command >> 8])
- mainakeys[command >> 8]();
-
- if (countmsg(CurBoard) < 1) {
- empty();
- command = getkey();
- }
- else {
- int last = lastmsg(CurBoard);
-
- if (!msgat(CurBoard,curmsg(CurBoard))) { /* e.g. after delete */
- setcur(CurBoard,msgnext(CurBoard,curmsg(CurBoard)));
- highest();
- } /* if */
-
- if (lastreadmsg(CurBoard) > last)
- setlastread(CurBoard,last);
- if (curmsg(CurBoard) > last)
- setcur(CurBoard,last);
-
- if (!readmsg(&message, curmsg(CurBoard))) {
- retry();
- command = direction;
- continue;
- }
- command = showmsg(message);
- } /* else */
- } /* while */
- } /* main */
-
- static void retry(void)
- {
- int ch;
-
- gotoxy(9,1);
- clreol();
- set_color(co_warn);
- bputs("Error reading message, (R)etry or (A)bort? ");
- video_update();
-
- do {
- ch = getkey() & 0x7f;
- ch = tolower(ch); /* tolower might be a macro */
- } while ((ch != 'r') && (ch != 'a'));
-
- bputc((char) ch);
- set_color(co_normal);
-
- if (ch == 'a')
- cleanup();
- } /* retry */
-
- void cleanup()
- {
- int echomail = 0, netmail = 0;
- int result;
-
- cls();
-
- for (area = 0; area < areas; area++) {
- if (arealist[area].echomail)
- echomail |= arealist[area].new;
-
- if (arealist[area].netmail)
- netmail |= arealist[area].new;
- } /* for */
-
- if (!closemsgbase()) {
- set_color(co_warn);
- bputs("Error closing message base.");
- set_color(co_normal);
- gotoxy(1,2);
- } /* if */
-
- if (useusersbbs) /* update USERS.BBS */
- updatehigh(usernum, highmsgread);
-
- set_color(co_hilite);
- if (echomail && netmail) {
- bputs("New Echomail and Netmail entered.");
- result = 3;
- } else if (echomail) {
- bputs("New Echomail entered.");
- result = 2;
- } else if (netmail) {
- bputs("New Netmail entered.");
- result = 1;
- } else {
- bputs("No new net- or echomail entered.");
- result = 0;
- } /* else */
- set_color(co_normal);
- gotoxy(1,3);
- bprintf("* Exiting from Msged/Q with errorlevel %d.", result);
- gotoxy(1,4);
- video_update();
- video_end();
-
- exit(result);
- } /* cleanup */
-
- void halt(int status)
- {
- if (status != 0)
- fprintf(stderr,"\nExiting with errorlevel %d\n",status);
- exit(status);
- } /* halt */
-
- void fatal(char *s)
- {
- fprintf(stderr, "\n%s\n", s);
- fprintf(stderr, "Press <Return> to exit.\n");
- while (getchar() != '\n') /* nothing */;
- cleanup();
- } /* fatal */
-
- void outamemory()
- {
- fatal("I've run out of memory!");
- } /* outamemory */
-
- static void empty()
- {
- cls();
- gotoxy(3, maxy / 2);
- set_color(co_hilite);
- bprintf("No messages in '%s'!", arealist[area].description);
- set_color(co_normal);
- } /* empty */
-
- static void search()
- {
- srch(S_BOTH);
- } /* srchall */
-
- static void srchhdr()
- {
- srch(S_HEAD);
- } /* srchhdr */
-
- static void srch(int what)
- {
- static bmgARG pattern;
- static char prompt[bmgMAXPAT];
- static char patstr[bmgMAXPAT];
- static int lastfound = 0;
- MSGHEADER hdr;
- int tmp2;
- char *s;
- int tmp;
- int curarea = area;
-
- gotoxy(9,1);
- clreol();
- set_color(co_info);
- bputs("Find: ");
- set_color(co_normal);
- if (bgets(prompt,sizeof(prompt)) == ABORT)
- return;
-
- if (strcmpl(prompt,patstr) != 0) { /* changed, so recompile */
- memset(patstr,0,sizeof(patstr));
- memset(&pattern,0,sizeof(bmgARG));
- strncpy(patstr,prompt,sizeof(prompt));
- bmgCompile(patstr,&pattern,TRUE);
- lastfound = 0;
- } /* if */
-
- gotoxy(9,1);
- clreol();
-
- set_color(co_info);
- for (;;) {
- do {
- s = NULL;
- tmp = curmsg(CurBoard);
- if (readheader(tmp, &hdr)) {
- if (what & S_TEXT)
- s = readtext(&hdr);
- if (what & S_HEAD) {
- if (s == NULL) {
- if ((s = malloc(36+36+73+1)) != NULL)
- *s = EOS;
- } else {
- s = realloc(s,strlen(s)+1 + 36+36+73+1);
- } /* else */
-
- if (s != NULL) {
- strcat(s, hdr.to);
- strcat(s, hdr.from);
- strcat(s, hdr.subj);
- } /* if */
-
- } /* if */
- } /* if */
-
- if (s != NULL) {
- gotoxy(9,1);
- bprintf("Looking at %s #%d for \"%s\"",
- arealist[area].description,tmp,prompt);
- video_update();
- clreol(); /* vvv is ignored and 's' is changed */
- tmp2 = bmgSearch(s,strlen(s),&pattern);
- ptrfree(s); s = NULL;
-
- if (tmp2 && (lastfound != tmp)) { /* found new one */
- lastfound = tmp;
- set_color(co_normal);
- return;
- } /* if */
- } /* if */
-
- if (keypressed()) {
- if (getkey() == ABORT) {
- set_color(co_normal);
- return;
- } /* if */
- } /* if */
-
- tmp = msgnext(CurBoard, tmp2 = tmp);
- if (tmp != 0)
- setcur(CurBoard,tmp);
- } while ((tmp != 0) && (tmp != tmp2));
-
- if (!globsrch) break; /* not global search, exit */
-
- if (++area >= areas)
- area = 0;
- if (area == curarea) break; /* searched through all */
- tmp = firstmsg(CurBoard); /* skip to first message of next board */
- setcur(CurBoard,tmp);
- } /* forever */
-
- beep(0,0);
-
- set_color(co_normal);
- } /* srch */
-
- BOOLEAN confirm(int confirmations)
- {
- int ch;
-
- if (!confirmations)
- return(TRUE);
-
- gotoxy(9,1);
- clreol();
- set_color(co_warn);
- bputs("*warning* ");
- bputs("Do you really want to do this? (y/n) ");
- video_update();
-
- do {
- ch = getkey() & 0x7f;
- ch = tolower(ch); /* tolower might be a macro */
- } while ((ch != 'y') && (ch != 'n'));
-
- bputc((char) ch);
- set_color(co_normal);
- return(ch == 'y');
- } /* confirm */
-
- /*
- * Set highest message read and set 'root' to current message
- * There may be problems here, with msgnum and filemsg ...
- * ... think about it sometime
- */
-
- void highest()
- {
- if (msgat(CurBoard,curmsg(CurBoard)))
- root = curmsg(CurBoard); /* global */
-
- if (root > lastreadmsg(CurBoard))
- setlastread(CurBoard, root);
-
- } /* highest */
-
- void left()
- {
- int temp;
-
- back = curmsg(CurBoard);
- direction = LEFT;
-
- if (back <= firstmsg(CurBoard))
- beep(0,0); /* must check here, msgprev doesn't give error */
-
- if ((temp = msgprev(CurBoard, back)) == 0)
- temp = firstmsg(CurBoard);
- setcur(CurBoard, temp);
-
- highest(); /* set root */
- } /* left */
-
- void right()
- {
- int temp;
-
- back = curmsg(CurBoard);
- direction = RIGHT;
-
- if (back >= lastmsg(CurBoard))
- beep(0,0); /* must check here, msgnext doesn't give error */
-
- if ((temp = msgnext(CurBoard, back)) == 0)
- temp = lastmsg(CurBoard);
- setcur(CurBoard, temp);
-
- highest();
- } /* right */
-
- void movetop()
- {
- back = curmsg(CurBoard);
- direction = LEFT;
-
- setcur(CurBoard,lastmsg(CurBoard));
-
- highest();
- } /* movetop */
-
- void movebot()
- {
- back = curmsg(CurBoard);
- direction = RIGHT;
-
- setcur(CurBoard,firstmsg(CurBoard));
-
- highest(); /* set root */
- } /* movebot */
-
- void enter()
- {
- if (direction == RIGHT)
- right();
- else
- left();
- } /* enter */
-
- void nextto()
- {
- int new;
- int look = area;
- int startarea = area;
-
- set_color(co_info);
- do {
- gotoxy(9,1);
- bprintf("Looking for new mail to you in '%s'",arealist[look].description);
- video_update();
- clreol();
-
- new = searchto(arealist[look].board, curmsg(arealist[look].board), username);
-
- if (keypressed()) {
- if (getkey() == ABORT) {
- set_color(co_normal);
- return;
- } /* if */
- } /* if */
- } while ((globsrch) && (new == -1) &&
- ((++look >= areas ? look = 0 : look) != startarea));
-
- set_color(co_normal);
-
- if (new == -1) {
- beep(0,0);
- return;
- } /* while */
-
- area = look;
- setcur(CurBoard,new);
- /* highest(); */ /* not here */
- } /* nextto */
-
- static void gotomsg(int i)
- {
- int f,l;
-
- f = /* firstmsg(CurBoard) */ 0; /* 8/2/90 */
- l = lastmsg(CurBoard);
-
- gotoxy(9, 1);
- clreol();
- set_color(co_info);
- bprintf("Goto Message #? (%d-%d) ", f, l);
- set_color(co_normal);
- back = curmsg(CurBoard);
- i = getnum(f, l, i);
- if (i == 0) /* ignore it */
- return;
-
- if (!msgat(CurBoard,i))
- i = msgnext(CurBoard,i);
- setcur(CurBoard, i);
-
- if (!msgat(CurBoard,i))
- setcur(CurBoard, back);
- else
- highest();
- } /* gotomsg */
-
- void newarea()
- {
- int newarea;
-
- if (!flushmsgbase())
- fatal("Error writing message base");
-
- if (areas < 2)
- return;
-
- newarea = selectarea(NULL);
- if (newarea != -1)
- toarea(newarea); /* show menu */
- } /* newarea */
-
- void nextarea()
- {
- int look = area;
-
- /* look for next board with mail */
- while ((++look >= areas ? look = 0 : look) != area)
- if (lastmsg(arealist[look].board) > lastreadmsg(arealist[look].board))
- break;
-
- if (look != area) {
- toarea(look);
- } else {
- toarea(0); /* go to first area */
- beep(0,0);
- }
- } /* nextarea */
-
- void prevarea()
- {
- int look = area;
-
- /* look for prev board with mail */
- while ((--look < 0 ? look = areas-1 : look) != area)
- if (lastmsg(arealist[look].board) > lastreadmsg(arealist[look].board))
- break;
-
- if (look != area)
- toarea(look);
- else
- beep(0,0);
- } /* prevarea */
-
- void uparea()
- {
- toarea(area+1 >= areas ? 0 : area+1);
- } /* uparea */
-
- void downarea()
- {
- toarea(area <= 0 ? areas-1 : area-1);
- } /* downarea */
-
- static void toarea(int n)
- {
- area = n;
- override = FALSE;
- direction = RIGHT;
- back = root = curmsg(CurBoard);
- clearbuffer(&msgbuf);
- } /* toarea */
-
- static void checkbase(void)
- {
- BYTE board;
- int result;
-
- gotoxy(1, maxy-3);
- bputs("Checking message base... ");
- video_update();
-
- result = checkmsgbase(&board);
-
- if (result == CHK_NOERR) {
- bputs("No errors found.");
- } else {
- char *msg = NULL;
-
- switch (result) {
- case CHK_NONINC:
- msg = "Non-increasing numbers found in board %d";
- break;
- case CHK_COUNTS:
- msg = "MSGINFO.BBS and MSGIDX.BBS differ in board %d";
- break;
- case CHK_HDR:
- msg = "Length of MSGHDR.BBS differs from MSGIDX.BBS";
- break;
- case CHK_TO:
- msg = "Length of MSGTOIDX.BBS differs from MSGIDX.BBS";
- break;
- } /* switch */
-
- gotoxy(1, maxy-3);
- set_color(co_warn);
- bputs("Error: ");
- bprintf(msg, board);
- clreol();
- gotoxy(1, maxy-2);
- bputs("You should exit and run MSGPACK -I to rebuild your index files.");
- set_color(co_normal);
- } /* else */
-
- } /* checkbase */
-
- static void usage_exit(void)
- {
- printf("\nUsage: MsgedQ [switches] [configfile [areasfile]]\n\n");
- printf(" -q Read QuickBBS config files\n");
- printf(" -r Read RemoteAccess config files\n");
- #ifdef DBRIDGE
- printf(" -b Read D'Bridge config files\n");
- #endif
- printf(" -d Config trace mode for debugging\n");
- printf(" -nPath Write new config file and define Path as netmail directory\n");
- printf(" -uName Override username from config file (use \"_\" for space)\n");
- printf(" -p Protect netmail\n");
- exit(255);
- } /* usage_exit */
-
- static int start(int argc, char *argv[])
- {
- char *uname = NULL;
- char *cfg = NULL, *afn = NULL;
-
- printf("Msged/Q " VERSION " Copyright 1991 Pieter J. Muller\n");
-
- configdebug = quicksysop = rastruct = protectnet = FALSE;
- #ifdef DBRIDGE
- dbridgestruct = FALSE;
- #endif
- useusersbbs = TRUE; /* could be configurable */
-
- while (--argc) {
- if (**(++argv) == '-') {
- switch (tolower(argv[0][1])) {
- case 'n':
- newnetpath = &argv[0][2];
- createconfig = (*newnetpath != EOS);
- if (createconfig) configdebug = TRUE;
- if (createconfig && (newnetpath[strlen(newnetpath)-1] != '\\')) {
- newnetpath = malloc(strlen(newnetpath)+2);
- strcpy(newnetpath,&argv[0][2]);
- strcat(newnetpath,"\\");
- } /* if */
- break;
-
- case 'u': { char *c;
- uname = &argv[0][2];
- for (c = uname; *c != EOS; ++c)
- if (*c == '_') *c = ' ';
- break;
- }
-
- case 'p':
- protectnet = TRUE;
- break;
-
- case 'd':
- configdebug = TRUE;
- break;
-
- case 'q':
- quicksysop = TRUE;
- break;
-
- case 'r':
- rastruct = TRUE;
- break;
-
- #ifdef DBRIDGE
- case 'b':
- dbridgestruct = TRUE;
- break;
- #endif
-
- case 'h':
- case '?':
- usage_exit();
-
- default:
- printf("Unknown switch '-%c'\n", argv[0][1]);
- break;
- } /* switch */
- } else {
- if (cfg == NULL)
- cfg = *argv;
- else
- if (afn == NULL)
- afn = *argv;
- } /* else */
- } /* while */
-
- /* (void)putenv("PROMPT=Msged/Q $P$G"); */
-
- printf("Initialising...\n");
- memset(&message, 0, sizeof(message));
- opening(cfg,afn,uname);
-
- message.to = thisnode[CurAKA];
- if (message.to.domain != NULL)
- message.to.domain = strdup(message.to.domain);
-
- if (!openmsgbase())
- fatal("Cannot open message base.");
-
- checkbase();
-
- gotoxy(1, maxy);
- bputs("Scanning for new mail....");
- video_update();
-
- area = areas-1; /* search forward from last area */
- nextarea(); /* next area with new mail */
-
- gotoxy(1, maxy);
- bputs("Press any key to continue....");
- clreol();
- video_update();
- getkey();
-
- return(KAREA);
-
- } /* start */
-
- #ifdef ZAPTHISOUT
- /*
- * Execute a Dos command
- * If path==NULL, execute COMSPEC
- * command may be NULL
- * Return TRUE iff ok
- */
-
- BOOLEAN shell(char *path, char *command)
- {
- if (path == NULL)
- if ((path = getenv("COMSPEC")) == NULL)
- return FALSE;
-
- if (spawnlp(P_WAIT, path, path, command, NULL) == -1)
- return FALSE;
-
- return TRUE;
- } /* shell */
- #endif
-
- #ifndef MINI
- static void far shell_msg(char swapmode, long amount)
- {
- if (swapmode != SWAP_NONE) {
- bprintf("Swapping %ld bytes to %s\n", amount,
- swapmode==SWAP_EMS ? "EMS" : "disk");
- gotoxy(1, wherey()+1);
- video_update();
- }
- } /* shell_msg */
-
- void os()
- {
- void *temp = shell_message;
- shell_message = shell_msg;
-
- cls();
- if (!flushmsgbase())
- fatal("Error writing message base");
-
- bputs("Type EXIT to return to Msged/Q.");
- gotoxy(1,3); video_update();
- if (!shell(NULL,NULL)) {
- gotoxy(9,1);
- set_color(co_warn);
- bputs("Could not shell, press any key");
- clreol();
- set_color(co_normal);
- video_update();
- (void)getkey();
- } /* if */
-
- shell_message = temp;
- video_init();
- } /* os */
- #endif
-
- void beep(int freq, int len)
- {
- #if defined(__TURBOC__) || defined(__JPIC__)
- static char state = 0;
-
- #define timer() (*(long far *)MK_FP(0, 0x046c))
- #define waitedge() { long v = timer(); while (v == timer()) /* */; }
-
- if (!beepson) return;
-
- if (state == 0) {
- long value = timer();
- sleep(1);
- if (value == timer())
- state = 1; /* disable all further beep calls */
- else
- state = 2; /* enable normal working */
- } /* if */
- if (state == 1) return; /* beeps disabled */
-
- if (freq == 0) freq = ENDFREQ;
- if (len == 0) len = ENDLEN;
-
- waitedge();
- sound(freq);
- while (len--)
- waitedge();
- nosound();
- #endif
- } /* beep */
-
- #ifndef SETTINGS
- void settings() {}
- #endif