home *** CD-ROM | disk | FTP | other *** search
Wrap
/********************************************************************** * DLMASTER version 2.60 - Make Downloadable List of RBBS files * * compiled with Borland C/C++ v 2.0 using Large memory model * * Copyright (c) 1990-93 by Bob Hampton * * S3-Tech BBS (703) 451-9509 * * all rights reserved * **********************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <alloc.h> #include <dir.h> #include <dos.h> #include <conio.h> #include <process.h> #include <io.h> #include <mem.h> #include <stdarg.h> #include "doswdw.h" #define FALSE 0 #define TRUE !FALSE #define OFF 0 #define ON !OFF #define MAXLINE 161 /* - maximum length of FMS file line */ #define MAXCATS 10 /* - maximum number of codes/category */ #define MAXFMS 50 /* - maximum number of FMS directories */ #define SINGLE 1 /* - used in windows to specify single */ #define DOUBLE 2 /* or double-line borders */ #define COLOR 1 /* - used for color display mode */ #define BW 0 /* - " " b&w " " */ typedef struct ltag /* structure for linked-list created */ { /* in initial read of FMS file(s): */ char lname[13]; /* - name of file */ long lsize, /* - size of file (in bytes) */ ldate, /* - date of file */ lpos; /* - position of description in FMS */ int lseclvl, /* - security level needed */ lfms; /* - FMS array index */ char lcode[4]; /* - category code of file */ struct ltag *lnext; /* - pointer to next node */ } LDATA; typedef struct /* structure for temporary files. Same as */ { /* LDATA but without category code or next */ char tname[13]; /* node pointer. */ long tsize, tdate, tpos; int tseclvl, tfms; } TDATA; typedef struct ptag /* structure for print buffer */ { /* linked-list. Includes: */ char prtline[MAXLINE]; /* - line buffer */ struct ptag *pnext; /* - pointer to next node */ } PDATA; typedef struct /* structure for config record: */ { char fmsname[MAXPATH], /* - FMS filename */ dcatname[MAXPATH], /* - DIR.CAT filename */ outname[MAXPATH], /* - output file path/name */ bbsname[65], /* - name of BBS */ sorttype, /* - A)lpha or D)ate sort */ revsort, /* - flag for reverse sort */ hdrname[MAXPATH], /* - name of header file */ ftrname[MAXPATH], /* - name of footer file */ zippath[MAXPATH]; /* - path to compression util */ int minseclvl, /* - minimum security level to process */ maxseclvl; /* - maximum " " " " */ } CNFGREC; typedef struct dtag /* structure of linked-list for */ { /* info from DIR.CAT file: */ char dname[9], /* - name of directory */ dcode[MAXCATS][4], /* - category code */ ddesc[65]; /* - directory description */ struct dtag *dnext; /* - pointer to next node */ } DCATINFO; typedef struct ctag /* structure of linked-list for valid */ { /* category codes, includes: */ char code[4]; /* - code */ struct ctag *cnext; /* - pointer to next node */ } CATCODE; typedef struct /* structure for array of info */ { /* about FMS file(s): */ char name[MAXPATH]; /* - FMS filename */ int top; /* - if \FMS TOP used in this file */ } FMSFILE; typedef struct /* structure containing info about */ { /* current window: */ int left, /* - left coordinate */ top, /* - top coordinate */ right, /* - right coordinate */ bottom, /* - bottom coordinate */ fore, /* - normal foreground color */ back, /* - normal background color */ hifore, /* - hilight foreground color */ hiback, /* - hilight background color */ bstyle, /* - border style */ bcolor, /* - border color */ shadow; /* - flag for 3-D shadow */ } WININFO; void make_wallpaper (unsigned char c, int fore, int back); void make_window (WININFO *win); void read_cnfgfile (char *cnfgname, CNFGREC *crec, WININFO *win); void read_dircatfile (char *dcatname, DCATINFO **dfirst, WININFO *win); int create_cats (DCATINFO *dnode, CATCODE **cfirst); void make_temps (CATCODE *cnode, WININFO *win); void searchfms (char *fmsname, FMSFILE *fmsdata, int *linelength); void readfms (FMSFILE *fmsdata, int num_cats, WININFO *win, CATCODE *cfirst, int *totalfiles, long *totalbytes, int *zip_fms_index, long *zip_fms_pos, char *zipname, int minseclvl, int maxseclvl); void make_sortfiles (LDATA *lnode[], WININFO *win, CATCODE *cnode); void process_list (DCATINFO *dnode, CATCODE *cnode, CNFGREC *crec, int linelength, int totalfiles, long totalbytes, FMSFILE *fmsdata, WININFO *win); void print_buffer (FILE *outfile, PDATA *pnode); void print_listheader (CNFGREC *crec, FILE *outfile); void print_dirheader (DCATINFO *dnode, int tempfiles, long tempbytes, FILE *outfile); void print_listfooter (int totalfiles, long totalbytes, FILE *outfile); void printfile (char *filename, char *message, FILE *outfile); void make_zip (char *zippath, char *textname, WININFO *win); int afcompare (TDATA huge **elem1, TDATA huge **elem2); int arcompare (TDATA huge **elem1, TDATA huge **elem2); int dfcompare (TDATA huge **elem1, TDATA huge **elem2); int drcompare (TDATA huge **elem1, TDATA huge **elem2); void cursor (int cmnd); int check_catcode (char *code, CATCODE *cnode); void fail (char *message, char *filename); int set_colors (WININFO *header, WININFO *center, WININFO *bottom); void clear_status (WININFO *win); extern unsigned _stklen = 49152; /* set stack size to 48K */ void main (int argc, char **argv) { CNFGREC crec; /* DLMASTER config file info */ DCATINFO *dfirst = NULL; /* head pointer for directory list */ CATCODE *cfirst = NULL; /* " " " catcodes " */ FMSFILE fmsdata[MAXFMS]; /* array of FMS file info */ char cnfgname[MAXPATH]; /* DLMASTER config file path/name */ int linelength = 0, /* FMS line length */ totalfiles, /* total number of files */ num_cats, /* number of categories */ dispmode, /* current display mode */ zip_fms_index, /* index to FMS file containing description of Zip file */ i; /* work variable */ long totalbytes, /* total number of bytes */ zip_fms_pos; /* byte position of Zipfile descr. in FMS file containing descr. */ WININFO header, /* info for top window */ center, /* " " center " */ bottom; /* " " bottom " */ switch (argc) { case 1: /* no config file specified in command line */ strcpy (cnfgname, "DLMASTER.CFG"); break; case 2: /* config file specified in command line */ strcpy (cnfgname, *(argv + 1)); break; default: fprintf (stderr, "\nInvalid command line\n\n"); fprintf (stderr, "Usage: DLMASTER <config file>\n"); exit(1); } /*************************************************** * determine the display mode (color or b&w), and * * set the colors for the windows accordingly. * ***************************************************/ dispmode = set_colors (&header, ¢er, &bottom); /************************************************************ * set text to white-on-black, clear the screen, paint the * * wallpaper, create the top window, and display the title * ************************************************************/ cursor (OFF); textattr (7); clrscr(); if (dispmode == COLOR) make_wallpaper('.', LIGHTGRAY, BLUE); make_window (&header); cputs (" DLMASTER version 2.60 (c) 1990-93 by Bob Hampton"); /********************************** * create the bottom window, and * * read the DLMASTER config file * **********************************/ make_window (&bottom); read_cnfgfile (cnfgname, &crec, &bottom); /********************************** * create the middle window, and * * read the DIR.CAT file. Create * * list of categories, and create * * the temp files. * **********************************/ make_window (¢er); read_dircatfile (crec.dcatname, &dfirst, ¢er); num_cats = create_cats (dfirst, &cfirst); make_temps (cfirst, ¢er); /**************************************** * create array of info on FMS file(s) * ****************************************/ searchfms (crec.fmsname, fmsdata, &linelength); /*************************************************** * read the FMS file(s) and create the temp files * ***************************************************/ readfms (fmsdata, num_cats, ¢er, cfirst, &totalfiles, &totalbytes, &zip_fms_index, &zip_fms_pos, crec.outname, crec.minseclvl, crec.maxseclvl); /************************************* * create the output text file from * * the temp and FMS files * *************************************/ process_list (dfirst, cfirst, &crec, linelength, totalfiles, totalbytes, fmsdata, ¢er); /*************************************** * create the ZIP file, if requested, * * deleting the text file afterwards * ***************************************/ if (strcmp (crec.zippath, "")) make_zip (crec.zippath, crec.outname, ¢er); /**************************************** * set screen to white-on-black, clear * * the screen, and restore the cursor * ****************************************/ textattr (7); window (1,1,80,25); clrscr(); cursor (ON); } void read_cnfgfile (char *cnfgname, CNFGREC *crec, WININFO *win) { /******************************************************************* * This function will read the config file specified in *cnfgname * * and modify the config file record *crec to contain information * * from the configuration file. * *******************************************************************/ FILE *cnfgfile; /* pointer to config file */ char buffer[MAXLINE]; /* buffer for file read */ /********************* * open config file * *********************/ if ((cnfgfile = fopen (cnfgname, "r")) == NULL) fail ("Error opening config file", cnfgname); /******************************** * read name of first FMS file * ********************************/ fgets (buffer, MAXLINE, cnfgfile); strcpy (crec->fmsname, strtok (buffer, "\n")); /****************************** * read name of DIR.CAT file * ******************************/ fgets (buffer, MAXLINE, cnfgfile); strcpy (crec->dcatname, strtok (buffer, "\n")); /***************************** * read name of output file * *****************************/ fgets (buffer, MAXLINE, cnfgfile); strcpy (crec->outname, strtok (buffer, "\n")); /********************* * read name of BBS * *********************/ fgets (buffer, MAXLINE, cnfgfile); strcpy (crec->bbsname, strtok (buffer, "\n")); /**************************** * read sort type (A or D) * ****************************/ crec->sorttype = fgetc (cnfgfile); fgetc (cnfgfile); /*************************** * read reverse sort flag * ***************************/ crec->revsort = fgetc (cnfgfile); fgetc (cnfgfile); /***************************************** * optionally, read name of header file * *****************************************/ if (fgets (buffer, MAXLINE, cnfgfile) != NULL && *buffer != '\n') strcpy (crec->hdrname, strtok (buffer, "\n")); else strcpy (crec->hdrname, ""); /***************************************** * optionally, read name of footer file * *****************************************/ if (fgets (buffer, MAXLINE, cnfgfile) != NULL && *buffer != '\n') strcpy (crec->ftrname, strtok (buffer, "\n")); else strcpy (crec->ftrname, ""); /******************************** * optionally, read PKZIP path * ********************************/ if (fgets (buffer, MAXLINE, cnfgfile) != NULL && *buffer != '\n') strcpy (crec->zippath, strtok (buffer, "\n")); else strcpy (crec->zippath, ""); /********************************************** * optionally, read security screening level * **********************************************/ if (fgets (buffer, MAXLINE, cnfgfile) != NULL && *buffer != '\n') { crec->minseclvl = atoi (strtok (buffer, ",")); crec->maxseclvl = atoi (strtok (NULL, "")); } else { crec->minseclvl = 0; crec->maxseclvl = 32767; } /*********************************** * close config file, and display * * runtime parameters in window * ***********************************/ fclose (cnfgfile); gotoxy (3,1); cputs ("sort type - "); textcolor (win->hifore); if (toupper (crec->sorttype) == 'A') cputs ("Alpha"); else cputs ("Date"); textcolor (win->fore); gotoxy (30,1); cputs ("reverse sort - "); textcolor (win->hifore); if (toupper (crec->revsort) == 'Y') cputs ("Yes"); else cputs ("No"); textcolor (win->fore); gotoxy (59,1); cputs ("auto ZIP - "); textcolor (win->hifore); if (strcmp (crec->zippath, "")) cputs ("Yes"); else cputs ("No"); textcolor (win->fore); } void read_dircatfile (char *dcatname, DCATINFO **dfirst, WININFO *win) { /********************************************************************* * This function will read the DIR.CAT file specified in *dcatname * * and will modify the pointer *dfirst to point to the first node * * in the linked-list of info about the file categories. It will * * also create the temp files for the categories using the category * * name, and will save 0 at the beginning of each file as the count * * for the number of files in that category. * *********************************************************************/ FILE *dirfile; /* pointer to DIR.CAT file */ DCATINFO *dnode, /* pointer to current node */ *dprev; /* " " previous " */ char buffer[MAXLINE], /* buffer for file read */ tempcat[65], /* work buffer for cat desc */ *temp; /* work pointer */ int i; /* work variable */ /******************************** * display directory file name * ********************************/ gotoxy (16,3); cputs ("Reading directory file: "); textattr (win->hifore + (win->hiback << 4)); cprintf ("%s", dcatname); textattr (win->fore + (win->back << 4)); clreol(); /******************************************** * open DIR.CAT file, allocate first node, * * and set head of linked-list * ********************************************/ if ((dirfile = fopen (dcatname, "r")) == NULL) fail ("Error opening category file", dcatname); dnode = (DCATINFO far *) farmalloc ( (unsigned long) sizeof (DCATINFO)); if (dnode == NULL) fail ("Unable to create","dnode"); *dfirst = dnode; /*************************************** * for each line in the DIR.CAT file, * ***************************************/ while (fgets (buffer, MAXLINE, dirfile) != NULL) { /****************************************** * get directory name from buffer, strip * * next seperating comma. * ******************************************/ strcpy (dnode->dname, strtok (buffer, "\"")); temp = strtok (NULL, "\""); /************************************** * get category code(s) from buffer, * * and strip next separating comma. * **************************************/ strcpy (tempcat, strtok (NULL, "\"")); temp = strtok (NULL, "\""); /****************************************** * get directory description from buffer * ******************************************/ strcpy (dnode->ddesc, strtok (NULL, "\"")); /********************************************* * separate category code(s) from tempcat[] * *********************************************/ i = 0; strcpy (dnode->dcode[i++], strtok (tempcat, ", ")); while (i < MAXCATS && (temp = strtok (NULL, ", ")) != NULL) strcpy (dnode->dcode[i++], temp); if (i != MAXCATS) strcpy (dnode->dcode[i], "###"); /***************************************************** * create the next node, set previous node pointer * * to the current node, and set the current pointer * * to new node * *****************************************************/ dnode->dnext = (DCATINFO far *) farmalloc ( (unsigned long) sizeof (DCATINFO)); if (dnode->dnext == NULL) fail ("Unable to create","dnode->dnext"); dprev = dnode; dnode = dnode->dnext; } /******************************************************* * set previous node's pointer-to-next to NULL, free * * the unneeded node from memory, close DIR.CAT file, * * and return the number of categories * *******************************************************/ dprev->dnext = NULL; farfree (dnode); fclose (dirfile); } int create_cats (DCATINFO *dnode, CATCODE **cfirst) { /*********************************************************************** * This function will create a linked-list of valid category codes by * * scanning through the dcodes in the linked-list of dnode info. It * * will eliminate any duplicate codes, making a list we can use for * * tempfile maintenance. * ***********************************************************************/ CATCODE *cnode = NULL, *cprev = NULL; int catfound = FALSE, num_cats = 0, i; /********************************* * for each node in linked-list * * of DIR.CAT entries * *********************************/ while (dnode) { /**************************** * scan each category code * ****************************/ for (i = 0; i < MAXCATS && strcmp (dnode->dcode[i], "###"); i++) { cnode = *cfirst; while (cnode && catfound == FALSE) { if (strcmp (dnode->dcode[i], cnode->code) == 0) catfound = TRUE; cprev = cnode; cnode = cnode->cnext; } /*********************************** * if code not already in list of * * codes, add to list * ***********************************/ if (catfound == FALSE) { num_cats++; cnode = (CATCODE far *) farmalloc ( (unsigned long) sizeof (CATCODE)); if (cnode == NULL) fail ("Unable to create","cnode->cnext"); if (cprev) cprev->cnext = cnode; cnode->cnext = NULL; strcpy (cnode->code, dnode->dcode[i]); if (*cfirst == NULL) *cfirst = cnode; } catfound = FALSE; } dnode = dnode->dnext; } /******************************* * return the number of codes * *******************************/ return (num_cats); } void make_temps (CATCODE *cnode, WININFO *win) { /********************************************************** * This function creates the temp files from info in the * * cnode linked-list of category names. * **********************************************************/ FILE *tempfile; char tempname[MAXPATH]; int tempfiles = 0, i; /****************************** * for every category code.. * ******************************/ while (cnode) { /************************************************** * make tempfilename and display it. Open file, * * write 0 to beginning of file (for number of * * tempfiles), and close tempfile * **************************************************/ strcpy (tempname, "$DLTEMP."); strcat (tempname, cnode->code); gotoxy (16,3); cputs ("Creating temporary file: "); textattr (win->hifore + (win->hiback << 4)); cprintf ("%s", tempname); textattr (win->fore + (win->back << 4)); clreol(); if ( (tempfile = fopen (tempname, "wb")) == NULL) fail ("Unable to open tempfile - ", tempname); fwrite (&tempfiles, 2, 1, tempfile); fclose (tempfile); cnode = cnode->cnext; } } void searchfms (char *fmsname, FMSFILE *fmsdata, int *linelength) { /****************************************************************** * This function will read file information from the FMS file(s), * * starting with the filename passed in *fmsname. It will * * modify the *fmsdata array to hold info about each of the * * FMS files, and will set *linelength to the length of the * * FMS line. * ******************************************************************/ int i = 0, /* work variable for indexing */ chain = TRUE; /* flag for chained FMS */ char buffer[MAXLINE], /* buffer for file read */ *work, /* work pointer */ *fmsarg; /* pointer to FMS header arg */ FILE *fp; /* pointer to FMS file */ /*********************** * for each FMS file, * ***********************/ while (chain && i < MAXFMS) { /*********************** * set flags to FALSE * ***********************/ chain = FALSE; (fmsdata + i)->top = FALSE; /***************************************** * copy FMS filename to array, open FMS * * file, and read first line * *****************************************/ strcpy ((fmsdata + i)->name, fmsname); if ((fp = fopen ((fmsdata + i)->name, "r")) == NULL) fail ("Unable to open FMS file", fmsname); fgets (buffer, MAXLINE, fp); /********************************* * if linelength is not already * * set, then set it * *********************************/ if (*linelength == 0) *linelength = strlen (buffer) + 1; /*************************** * if line is FMS header, * ***************************/ if (strncmp (buffer, "\\FMS", 4) == 0) { /************************************** * set work pointer to next argument * * and get next argument * **************************************/ work = strtok (buffer, "\n"); work += 4; fmsarg = strtok (work, " "); /********************************* * for each remaining argument, * *********************************/ while (fmsarg) { /*************************************** * if "CH()" command, get the name of * * the file to chain to, and set the * * chain flag to TRUE * ***************************************/ if (strncmp (fmsarg, "CH(", 3) == 0) { fmsarg += 3; strcpy (fmsname, fmsarg); fmsname[strlen(fmsarg)-1] = '\0'; chain = TRUE; } /******************************************* * otherwise, if argument is TOP command, * * set the TOP flag to TRUE * *******************************************/ else if (strcmp (fmsarg, "TOP") == 0) (fmsdata + i)->top = TRUE; /************************** * get the next argument * **************************/ fmsarg = strtok (NULL, " "); } } /*************************** * close the FMS file and * * increment the index * ***************************/ fclose (fp); i++; } /********************************** * if the FMS array is not full, * * set the next filename to NULL * ***********************************/ if (i < MAXFMS) strcpy ( (fmsdata + i)->name, ""); } void readfms (FMSFILE *fmsdata, int num_cats, WININFO *win, CATCODE *cfirst, int *totalfiles, long *totalbytes, int *zip_fms_index, long *zip_fms_pos, char *outname, int minseclvl, int maxseclvl) { /*************************************************************************** * This function will read the FMS file(s) listed in the *fmsdata * * array and builds an array of linked-lists of file info using the LDATA * * structure. This array will be filled to memory, then purged and * * refilled as necessary to finish reading the FMS file(s). At each * * purge, the temp files will be written to using the make_sortfiles() * * function. * ***************************************************************************/ LDATA **lnode, /* array of pointers to current node */ **lfirst; /* " " " " beg. of arrays */ char *buffer, /* buffer for file read */ tempbuf[MAXLINE], /* temp. workspace for buffer manipulation */ namebuff[14], /* buffer for name/ext parsing */ zipname[MAXPATH], /* ZIP name to look for in FMS */ lext[9], /* extension for file name */ testcode[4], /* test buffer for category code */ tempdate[9], /* work variable for file date */ tempsize[9]; /* work variable for file size */ FILE *fp; /* pointer to FMS file */ int i, /* work variable for indexing */ filesec, /* security level of file */ process_file, /* flag for whether to process file */ lndx, /* index to lnode array */ fndx = 0; /* index to FMS array */ long fpos; /* file position */ buffer = (char *) malloc (MAXLINE); /**************************************************** * strip path and extension from output text file * * name to yield name to search for in FMS file(s) * * to locate current file/position of description * * for the ZIPfile * ****************************************************/ strcpy (zipname, outname); strrev (zipname); strtok (zipname, "\\"); strrev (zipname); strtok (strupr (zipname), "."); /****************************************************** * allocate first nodes for arrays, set variable and * * array values, and display template in window * ******************************************************/ lnode = (LDATA far **) farmalloc ( (unsigned long) sizeof (LDATA *) * num_cats); lfirst = (LDATA far **) farmalloc ( (unsigned long) sizeof (LDATA *) * num_cats); *totalfiles = 0; *totalbytes = 0L; for (i = 0; i < num_cats; i++) { lnode[i] = NULL; lfirst[i] = NULL; } gotoxy (50,5); cputs ("Total files:"); gotoxy (50,6); cputs ("Total bytes:"); /******************************** * for each file in FMS array, * ********************************/ while ( strcmp( (fmsdata + fndx)->name, "") && fndx < MAXFMS) { /****************************************** * set file position, display filename, * * and seek to beginning of file * ******************************************/ fpos = 0L; gotoxy (16,3); cputs ("Reading FMS file: "); textattr (win->hifore + (win->hiback << 4)); cprintf ("%s", (fmsdata + fndx)->name); textattr (win->fore + (win->back << 4)); clreol(); if ((fp = fopen ((fmsdata + fndx)->name, "r")) == NULL) fail ("Unable to open FMS file", (fmsdata+fndx)->name); fseek (fp, 0L, SEEK_SET); /******************************* * for each line of FMS file, * *******************************/ while (fgets (buffer, MAXLINE, fp) != NULL) { process_file = FALSE; textcolor (win->hifore); /********************************* * if filename present in line, * *********************************/ if (strchr (" \\*", (int) *buffer) == NULL) { /************************************ * test for security level of file * ************************************/ /* (remember - want to add */ /* true security process- */ /* ing later...) */ if ( (int) *buffer == '=') { strcpy (tempbuf, buffer+33); filesec = atoi (strtok (tempbuf, " ")); if (filesec >= minseclvl && filesec <= maxseclvl) { process_file = TRUE; strcpy (buffer, buffer+1); } } else /********************************************** * if this line contains the current Zipfile * * description, set the FMS array index and * * file position into the holding variables * * so we can use them later to update the * * description. Otherwise, process as a * * normal file. * **********************************************/ /* future development */ if (strncmp (zipname, buffer, strlen (zipname)) == 0) { *zip_fms_index = fndx; *zip_fms_pos = fpos; } else if (minseclvl == 0) process_file = TRUE; if (process_file) { /************************************* * put category code in work buffer * * and strip from end of buffer * *************************************/ strncpy (testcode, buffer+strlen(buffer)-4, 3); testcode[3] = '\0'; buffer[strlen(buffer)-4] = '\0'; /**************************** * if valid category code, * ****************************/ if ( (i = check_catcode (testcode, cfirst)) != -1) { /****************************** * set index for lnode array * ******************************/ lndx = i; /********************************* * if less than 1K memory left, * *********************************/ if (coreleft() < 1000L) { /********************************** * append info to tempfiles, * * freeing memory in the process, * * and redisplay the template * **********************************/ make_sortfiles (lfirst, win, cfirst); for (i = 0; i < num_cats; i++) { lnode[i] = NULL; lfirst[i] = NULL; } gotoxy (16,3); cputs ("Reading FMS file: "); textattr (win->hifore + (win->hiback << 4)); cprintf ("%s", (fmsdata + fndx)->name); textattr (win->fore + (win->back << 4)); clreol(); } /************************************* * if first node of this cat empty, * * allocate the first node * *************************************/ if (lnode[lndx] == NULL) { lnode[lndx] = (LDATA far *) farmalloc ( (unsigned long) sizeof (LDATA)); if (lnode[lndx] == NULL) fail ("Unable to create", "lnode"); lfirst[lndx] = lnode[lndx]; } /****************************************** * otherwise, allocate the next node and * * set current node pointer to next node * ******************************************/ else { lnode[lndx]->lnext = (LDATA far *) farmalloc ( (unsigned long) sizeof (LDATA)); if (lnode[lndx]->lnext == NULL) fail ("Unable to create", "lnode"); lnode[lndx] = lnode[lndx]->lnext; } /********************************************* * set file position and next node pointer, * * and copy category code from work buffer * *********************************************/ lnode[lndx]->lpos = fpos; lnode[lndx]->lnext = NULL; strcpy (lnode[lndx]->lcode, testcode); /****************************************** * get file name/ext in work buffer, and * * strip from beginning of line buffer * ******************************************/ strncpy (namebuff, buffer, 13); namebuff[13] = '\0'; strrev (buffer); buffer[strlen(buffer)-13] = '\0'; strrev (buffer); /********************************************* * get filename, and extension (if there is * * one) from work buffer, and reformat it * *********************************************/ strcpy (lnode[lndx]->lname, strtok (namebuff, " .")); strcpy (lext, strtok (NULL, " .")); if (strcmp (lext, "")) { strcat (lnode[lndx]->lname, "."); strcat (lnode[lndx]->lname, lext); } /************************************** * get filesize, add to total bytes * **************************************/ strcpy (tempsize, strtok (buffer, " ")); lnode[lndx]->lsize = atol (tempsize); *totalbytes += lnode[lndx]->lsize; /************************************************ * get file date and convert to numeric YYMMDD * ************************************************/ strcpy (tempdate, strtok (NULL, " -")); strcat (tempdate, strtok (NULL, "-")); strcat (tempdate, strtok (NULL, " ")); lnode[lndx]->ldate = atol (tempdate); strncpy (tempdate, "0000", 4); lnode[lndx]->ldate = (atol (tempdate) * 10000) + (lnode[lndx]->ldate / 100); /**************************** * set index for FMS array * ****************************/ lnode[lndx]->lfms = fndx; /************************************** * increment and display total files * * and total bytes every * **************************************/ (*totalfiles)++; gotoxy (63,5); cprintf ("%d", *totalfiles); gotoxy (63,6); cprintf ("%ld", *totalbytes); } } } /********************** * get file position * **********************/ fpos = ftell (fp); } /****************************** * close current FMS file and * * increment FMS array index * ******************************/ fclose (fp); fndx++; textcolor (win->fore); } /********************************************* * append info to tempfiles, freeing memory * *********************************************/ make_sortfiles (lfirst, win, cfirst); } void make_sortfiles (LDATA *lnode[], WININFO *win, CATCODE *cnode) { /******************************************************************************** * This function will append file entries to the temporary files created for * * each category. It will access the array of LDATA structures for the file * * info, but will use a TDATA structure for writing to the files. It will * * access the DCATINFO structure to get the category names, in order to access * * the temporary files. It will also free the memory used by the ldata[] * * array, so that more files than can fit in memory may be processed. * ********************************************************************************/ FILE *tempfile; /* pointer to current temp file */ int i = 0, /* work variable for indexing */ tempfiles; /* number of files in temp file */ char tempname[MAXPATH]; /* name of temp file */ LDATA *lprev; /* pointer to previous lnode */ /******************************* * display template in window * *******************************/ textattr (win->fore + (win->back << 4)); gotoxy (16, 3); cprintf ("Appending to tempfile: "); /**************************** * for each category code, * ****************************/ while (cnode) { /*************************************** * set tempfile name, and display it * ***************************************/ strcpy (tempname, "$DLTEMP."); strcat (tempname, cnode->code); textattr (win->hifore + (win->hiback << 4)); gotoxy (39, 3); cprintf ("%s", tempname); textattr (win->fore + (win->back << 4)); clreol(); /************************************************* * open tempfile, read current number of files, * * and seek to end for appending * *************************************************/ if ((tempfile = fopen (tempname, "r+b")) == NULL) fail ("Unable to open tempfile", tempname); fread (&tempfiles, 2, 1, tempfile); fseek (tempfile, 0L, SEEK_END); /************************************************** * for each node in this category's linked-list, * * increment the file count, write the node info, * * go to the next node, and free the previous * * node from memory * **************************************************/ while (lnode[i] && strcmp (lnode[i]->lname, "")) { tempfiles++; fwrite (lnode[i], sizeof (TDATA), 1, tempfile); lprev = lnode[i]; lnode[i] = lnode[i]->lnext; farfree (lprev); } /***************************************** * seek to beginning of file, write new * * filecount, and close the file * *****************************************/ fseek (tempfile, 0L, SEEK_SET); fwrite (&tempfiles, 2, 1, tempfile); fclose (tempfile); /************************************** * increment the category index, and * * go to next category * **************************************/ i++; cnode = cnode->cnext; } } void process_list (DCATINFO *dnode, CATCODE *cnode, CNFGREC *crec, int linelength, int totalfiles, long totalbytes, FMSFILE *fmsdata, WININFO *win) { /**************************************************************************** * The heart of the beast! This function creates the downloadable file * * listing from the temp files created previously, along with the FMS * * files listed in the FMSFILE array (*fmsdata). Once all records for a * * category are loaded into memory, they can be sorted either by filename * * or by date, in ascending or descending order. * ****************************************************************************/ DCATINFO *dfirst, /* pointer to head of linked-list */ *dprev; /* " " previous dnode */ CATCODE *cprev; /* " " previous cnode */ TDATA huge *tdata; /* " " array of tempfile records */ TDATA huge *tfirst; /* " " first element of above */ TDATA huge *twork; /* " used when enlarging array */ TDATA **t_array; /* array of pointers to be sorted */ TDATA **t_first; /* pointer to first element of above */ FILE *sortfile, /* pointer to current tempfile */ *outfile, /* pointer to output file */ *fp; /* pointer to FMS file */ int count, /* loop control counter */ loop, /* flag for extended descr. */ tempfiles, /* number of files in tempfile */ tworkfiles, /* number used to enlarge array */ i, /* work variable for indexing */ x; /* work variable for counting */ long rcnt, /* number of bytes to backup */ /* in file (reverse count) */ prev = 1, /* position to seek to in file */ /* when backing up */ tempbytes; /* number of bytes in category */ char sfilename[MAXPATH], /* temp filename */ buffer[MAXLINE], /* buffer for read/write */ graph[51], /* graph to display */ *buffptr; /* buffer pointer */ PDATA *pnode = NULL, /* linked-list pointers */ *pfirst = NULL; /************************************************* * open output file, print the list header and, * * optionally, the user's header * *************************************************/ if ((outfile = fopen (crec->outname, "w")) == NULL) fail ("Unable to open output file", crec->outname); print_listheader (crec, outfile); if (strcmp (crec->hdrname, "") != 0) printfile (crec->hdrname, "header", outfile); /****************************************************** * set head pointer to list of categories, calculate * * rcnt from linelength, and display template * ******************************************************/ dfirst = dnode; rcnt = (long) linelength * 2; gotoxy (12,1); cputs ("0 . . . . 50 . . . . 100"); gotoxy (1,3); clreol(); gotoxy (5, 4); cputs ("Processing output for directory:"); gotoxy (5, 5); cputs ("files this directory:"); gotoxy (5, 6); cputs ("bytes this directory:"); /*********************** * for each category, * ***********************/ while (dnode) { tdata = tfirst = NULL; t_array = t_first = NULL; /********************************* * initialize and display graph * *********************************/ textattr (win->fore + (win->back << 4)); gotoxy (12,2); strcpy (graph, "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░"); cputs (graph); /************************************************** * set byte count to 0 and display category name * **************************************************/ tempbytes = 0L; textattr (win->hifore + (win->hiback << 4)); gotoxy (38,4); cprintf ("%s", dnode->dname); textattr (win->hifore + (win->back << 4)); clreol(); /********************************** * for each code in category.... * **********************************/ i = tempfiles = 0; while (i < MAXCATS && strcmp (dnode->dcode[i], "###")) { /****************************************** * set tempfile name, open tempfile, read * * number of files, and add to total. * ******************************************/ strcpy (sfilename, "$DLTEMP."); strcat (sfilename, dnode->dcode[i]); if ((sortfile = fopen (sfilename, "rb")) != NULL) fread (&tworkfiles, 2, 1, sortfile); tempfiles += tworkfiles; fclose (sortfile); i++; } /******************************** * if this category has files, * ********************************/ if (tempfiles != 0) { /*********************** * allocate the array * ***********************/ tdata = (TDATA huge *) farmalloc ((unsigned long) sizeof (TDATA) * tempfiles); if (tdata == NULL) fail ("Unable to allocate","tdata"); /*********************************** * read tempfile(s) to fill array * ***********************************/ i = tempfiles = 0; while (i < MAXCATS && strcmp (dnode->dcode[i], "###")) { /****************************************** * set tempfile name, open tempfile, and * * read number of files * ******************************************/ strcpy (sfilename, "$DLTEMP."); strcat (sfilename, dnode->dcode[i]); if ((sortfile = fopen (sfilename, "rb")) != NULL) fread (&tworkfiles, 2, 1, sortfile); tempfiles += tworkfiles; twork = tdata; for (x=0; x < (tempfiles - tworkfiles); x++, twork++); fread ((TDATA *) twork, sizeof (TDATA), tworkfiles, sortfile); fclose (sortfile); i++; } } /******************************* * display number of files in * * this category * *******************************/ gotoxy (27,5); cprintf ("%d ", tempfiles); /************************************************ * If there are files for this category, copy * * address of array elements into pointer array * * in order to sort pointers * ************************************************/ if (tempfiles != 0) { tfirst = tdata; t_array = (TDATA far **) farmalloc ( (unsigned long) sizeof (TDATA *) * tempfiles); if (t_array == NULL) fail ("Unable to create array","t_array"); t_first = t_array; count = 0; while (count < tempfiles) { *t_array = (TDATA *) tdata; tempbytes += tdata->tsize; tdata++; count++; t_array++; } /******************************************** * set array pointers back to beginning of * * array, and sort the array * ********************************************/ tdata = tfirst; t_array = t_first; if (toupper (crec->sorttype) == 'A') { if (toupper (crec->revsort) == 'N') qsort ((void *) t_array, tempfiles, sizeof (TDATA *), (int (*) (const void *, const void *)) afcompare); else qsort ((void *) t_array, tempfiles, sizeof (TDATA *), (int (*) (const void *, const void *)) arcompare); } else { if (toupper (crec->revsort) == 'N') qsort ((void *) t_array, tempfiles, sizeof (TDATA *), (int (*) (const void *, const void *)) dfcompare); else qsort ((void *) t_array, tempfiles, sizeof (TDATA *), (int (*) (const void *, const void *)) drcompare); } } /************************************************** * display the number of bytes in this category, * * and print the directory header to output file * **************************************************/ gotoxy (27,6); cprintf ("%ld ", tempbytes); print_dirheader (dnode, tempfiles, tempbytes, outfile); /* print directory header */ /******************************* * for each element of array, * *******************************/ count = 0; while (count < tempfiles) { /************************* * update graph display * *************************/ textattr (win->fore + (win->back << 4)); if (count > 0) { x = ( (long) count*100/tempfiles); for (i=0; i <= x/2; graph[i++]='█'); gotoxy (12, 2); cputs (graph); } /****************** * set loop flag * ******************/ loop = TRUE; /**************************************** * open appropriate FMS file and * * seek to proper position in FMS file * * and read first line of description * ****************************************/ if ((fp = fopen ((fmsdata + (*t_array)->tfms)->name, "r")) == NULL) fail ("Unable to open FMS file", (fmsdata + (*t_array)->tfms)->name); fseek (fp, (*t_array)->tpos, SEEK_SET); fgets (buffer, MAXLINE, fp); /******************************************* * copy buffer to print buffer, stripping * * category code and extra spaces at end * *******************************************/ strrev (buffer); buffptr = buffer; buffptr += 4; while (*buffptr == ' ') buffptr++; strrev (buffptr); strcat (buffptr, "\n"); if (pfirst) { pnode->pnext = (PDATA *) calloc (1, sizeof (PDATA)); pnode = pnode->pnext; } else { pnode = (PDATA *) calloc (1, sizeof (PDATA)); pfirst = pnode; } strcpy (pnode->prtline, buffptr); /*********************************** * if < 1K memory left, print the * * buffer to the file, freeing * * memory in the process * ***********************************/ if (coreleft() < 1000L) { clear_status (win); print_buffer (outfile, pfirst); pfirst = pnode = NULL; clear_status (win); } /************************************** * keep reading lines to see if part * * of extended description * **************************************/ while (loop) { /****************************************** * if FMS TOP is FALSE, seek to previous * * line and check if not before file * * beginning, otherwise turn loop off * ******************************************/ if (fmsdata[(*t_array)->tfms].top == FALSE) { prev = ftell (fp) - rcnt; if (prev >= 0) fseek (fp, prev, SEEK_SET); else loop = FALSE; } /*************************** * if loop is still TRUE, * ***************************/ if (loop) { /*************************** * if not at end of file, * ***************************/ if (fgets (buffer, MAXLINE, fp) != NULL) { /**************************** * if next line is part of * * extended description, * ****************************/ if (*buffer == ' ') { /************************************ * if not line from RBBSWHO merge, * ************************************/ if (strncmp (buffer, " Uploaded", 10)) { /******************************************* * copy buffer to print buffer, stripping * * final period and extra spaces at end * *******************************************/ strrev (buffer); buffptr = buffer; buffptr += 4; while (*buffptr == ' ') buffptr++; strrev (buffptr); strcat (buffptr, "\n"); if (pfirst) { pnode->pnext = (PDATA *) calloc (1, sizeof (PDATA)); pnode = pnode->pnext; } else { pnode = (PDATA *) calloc (1, sizeof (PDATA)); pfirst = pnode; } strcpy (pnode->prtline, buffptr); /*********************************** * if < 1K memory left, print the * * buffer to the file, freeing * * memory in the process * ***********************************/ if (coreleft() < 1000L) { print_buffer (outfile, pfirst); pfirst = pnode = NULL; } } } /**************************************** * if not part of extended description, * * break the loop * ****************************************/ else loop = FALSE; } /****************************** * if at EOF, break the loop * ******************************/ else loop = FALSE; } } /**************************************** * close current FMS file and * * increment array pointer and counter * ****************************************/ fclose (fp); t_array++; count++; } /******************************** * if not 0 files in category, * * free arrays from memory * ********************************/ if (tempfiles != 0) { farfree (t_first); /* clear pointer array */ farfree ((TDATA *)tfirst); /* clear array from memory */ } /************************ * flush buffer and * * go to next category * ************************/ print_buffer (outfile, pfirst); pfirst = pnode = NULL; dnode = dnode->dnext; textcolor (win->fore); } /********************************* * flush remaining print buffer * *********************************/ clear_status (win); print_buffer (outfile, pfirst); pfirst = pnode = NULL; clear_status (win); textattr (win->hifore + (win->back << 4)); /****************************************** * print user's footer (optional), print * * list footer, and close output file * ******************************************/ if (strcmp (crec->ftrname, "") != 0) printfile (crec->ftrname, "footer", outfile); print_listfooter (totalfiles, totalbytes, outfile); fclose (outfile); /************************************** * clear screen, and display message * * while deleting temp files and * * clearing cnode list from memory * **************************************/ clrscr(); gotoxy (20,3); cputs ("Erasing Temp Files....."); while (cnode) { strcpy (sfilename, "$DLTEMP."); strcat (sfilename, cnode->code); unlink (sfilename); cprev = cnode; cnode = cnode->cnext; farfree (cprev); } /********************************* * clear dnode list from memory * *********************************/ dnode = dfirst; while (dnode) { dprev = dnode; dnode = dnode->dnext; farfree (dprev); } } void print_buffer (FILE *outfile, PDATA *pnode) { PDATA *pprev; while (pnode) { fputs (pnode->prtline, outfile); pprev = pnode; pnode = pnode->pnext; farfree (pprev); } } void print_listheader (CNFGREC *crec, FILE *outfile) { int i, lead; char *ampm = "am", prtdate[40]; struct date pdate; struct time ptime; getdate (&pdate); gettime (&ptime); if (ptime.ti_hour > 12) { ptime.ti_hour -= 12; strcpy (ampm, "pm"); } sprintf (prtdate, "Last Updated %d/%d/%d at %d:%02d%s", pdate.da_mon, pdate.da_day, pdate.da_year, ptime.ti_hour, ptime.ti_min, ampm); fprintf (outfile, "┌─────────────────────────────────────────────────────────────────────────────┐\n"); fprintf (outfile, "│"); lead = (78 - strlen(crec->bbsname)) / 2; for (i = 0; i < lead; i++) fprintf (outfile, " "); fprintf (outfile, "%s", crec->bbsname); for (i = 1; i < (78 - lead- strlen(crec->bbsname)); i++) fprintf (outfile, " "); fprintf (outfile, "│\n"); fprintf (outfile, "│ Master List of Download Files │\n"); fprintf (outfile, "│ │\n"); fprintf (outfile, "│"); lead = (78 - strlen(prtdate)) / 2; for (i = 1; i < lead; i++) fprintf (outfile, " "); fprintf (outfile, "%s", prtdate); for (i = 0; i < (78 - lead - strlen(prtdate)); i++) fprintf (outfile, " "); fprintf (outfile, "│\n"); fprintf (outfile, "└─────────────────────────────────────────────────────────────────────────────┘\n"); } void print_dirheader (DCATINFO *dnode, int tempfiles, long tempbytes, FILE *outfile) { fprintf (outfile, "\n┌───────────────┬─────────────────────────────────────────────────────────────┐\n"); fprintf (outfile, "│ %-13s │ %-59s │\n", dnode->dname, dnode->ddesc); fprintf (outfile, "├───────────────┴─────────────────────────────────────────────────────────────┤\n"); fprintf (outfile, "│ Number of files: %-4d Number of bytes: %-9ld │\n", tempfiles, tempbytes); fprintf (outfile, "├────────────┬────────┬────────┬──────────────────────────────────────────────┤\n"); fprintf (outfile, "│ Filename │ Size │ Date │ Description │\n"); fprintf (outfile, "└────────────┴────────┴────────┴──────────────────────────────────────────────┘\n"); } void print_listfooter (int totalfiles, long totalbytes, FILE *outfile) { fprintf (outfile, "\n┌─────────────────────────────────────────────────────────────────────────────┐\n"); fprintf (outfile, "│ Total number of files in all directories: %-5d │\n", totalfiles); fprintf (outfile, "│ Total number of bytes in all directories: %-10ld │\n", totalbytes); fprintf (outfile, "└─────────────────────────────────────────────────────────────────────────────┘\n"); } void printfile (char *filename, char *message, FILE *outfile) { FILE *infile; char buffer[MAXLINE]; gotoxy (16,2); cprintf ("Adding %s file to output....", message); clreol(); if ((infile = fopen (filename, "r")) == NULL) fail ("Unable to open file", filename); while (fgets (buffer, MAXLINE, infile) != NULL) /* read file to end */ fputs (buffer, outfile); fclose (infile); } int afcompare (TDATA huge **elem1, TDATA huge **elem2) { return (strcmp ((*elem1)->tname, (*elem2)->tname)); } int arcompare (TDATA huge **elem1, TDATA huge **elem2) { return (strcmp ((*elem2)->tname, (*elem1)->tname)); } int dfcompare (TDATA huge **elem1, TDATA huge **elem2) { int retval; if ((*elem1)->tdate == (*elem2)->tdate) retval = strcmp ((*elem1)->tname, (*elem2)->tname); else retval = ((*elem1)->tdate < (*elem2)->tdate) ? -1 : 1; return (retval); } int drcompare (TDATA huge **elem1, TDATA huge **elem2) { int retval; if ((*elem1)->tdate == (*elem2)->tdate) retval = strcmp ((*elem2)->tname, (*elem1)->tname); else retval = ((*elem2)->tdate < (*elem1)->tdate) ? -1 : 1; return (retval); } void make_wallpaper (unsigned char c, int fore, int back) { int far *video, row, col, attr, i; struct text_info tinfo; gettextinfo (&tinfo); if (tinfo.currmode == MONO) video = (int far *) 0xB0000000; else video = (int far *) 0xB8000000; attr = fore + (back << 4); textattr (attr); clrscr(); for (row = 0; row < 25; row += 2) if (row % 4 == 0) for (col = 0; col < 80; col += 10) *(video + (row * 80) + col + 2) = c | (attr << 8); else for (col = 5; col < 80; col += 10) *(video + (row * 80) + col + 2) = c | (attr << 8); } void make_window (WININFO *win) { int row, col, attr, pos, far *video; char *savetext; struct text_info tinfo; struct { int upleft, upright, dnleft, dnright, vert, horiz; } border[3] = {{ 32, 32, 32, 32, 32, 32}, {218, 191, 192, 217, 179, 196}, {201, 187, 200, 188, 186, 205}}; gettextinfo (&tinfo); if (tinfo.currmode == MONO) video = (int far *) 0xB0000000; else video = (int far *) 0xB8000000; attr = (win->bcolor + (win->back << 4)) << 8; *(video + (win->top - 1) * 80 + win->left - 1) = border[win->bstyle].upleft | attr; *(video + (win->top - 1) * 80 + win->right - 1) = border[win->bstyle].upright | attr; *(video + (win->bottom - 1) * 80 + win->left - 1) = border[win->bstyle].dnleft | attr; *(video + (win->bottom - 1) * 80 + win->right - 1) = border[win->bstyle].dnright | attr; for (col = win->left; col < win->right-1; col++) { *(video + ((win->top-1)*80) + col) = border[win->bstyle].horiz | attr; *(video + ((win->bottom-1)*80) + col) = border[win->bstyle].horiz | attr; } for (row = win->top; row < win->bottom-1; row++) { *(video + (row * 80) + win->left-1) = border[win->bstyle].vert | attr; *(video + (row * 80) + win->right-1) = border[win->bstyle].vert | attr; } window (win->left+1, win->top+1, win->right-1, win->bottom-1); textattr (win->fore + (win->back << 4)); clrscr(); if (win->shadow) { for (row = win->top; row <= win->bottom; row++) { *(video + (row * 80) + win->right) &= 0x00FF; *(video + (row * 80) + win->right) |= (DARKGRAY + (BLACK << 4)) << 8; *(video + (row * 80) + win->right + 1) &= 0x00FF; *(video + (row * 80) + win->right + 1) |= (DARKGRAY + (BLACK << 4)) << 8; } for (col = win->left+1; col <= win->right; col++) { *(video + (win->bottom * 80) + col) &= 0x00FF; *(video + (win->bottom * 80) + col) |= (DARKGRAY + (BLACK << 4)) << 8; } } } void make_zip (char *zippath, char *textname, WININFO *win) { char command[MAXLINE], zipname[MAXPATH], *ziputil; int x, y, i; /****************************************************** * copy the path\filename of the compression utility * * into the ziputil variable and extract the name * * of the compression utility. * ******************************************************/ ziputil = (char *) malloc (MAXPATH); strcpy (ziputil, zippath); strrev (ziputil); strtok (ziputil, "\\"); strrev (ziputil); strtok (ziputil, "."); strcpy (zipname, textname); strtok (zipname, "."); strcpy (command, zippath); if (strcmp (strupr (ziputil), "PKZIP") == 0) strcat (command, " -a "); else strcat (command, " a "); strcat (command, zipname); strcat (command, " "); strcat (command, textname); strcat (command, " > NUL"); DoDosWdw (win->left+1, win->top+1,win->right-1,win->bottom-1, (win->fore + (win->back << 4)),command); if (strcmp (strupr (ziputil), "PKZIP") == 0) strcat (zipname, ".ZIP"); else if (strcmp (strupr (ziputil), "LHA") == 0) strcat (zipname, ".LZH"); else if (strcmp (strupr (ziputil), "ARJ") == 0) strcat (zipname, ".ARJ"); if (access (zipname, 0)) fail ("Unable to create ZIP file: ", zipname); else unlink (textname); } void cursor (int cmnd) { union REGS regs; int attribute; regs.h.ah = 0x01; if (cmnd == OFF) attribute = 0x01; else attribute = 0x00; regs.h.ch = attribute << 5 | 6; regs.h.cl = 7; int86 (0x10, ®s, ®s); } int check_catcode (char *code, CATCODE *cnode) { int i, cndx = 0; if (strcmp (code, "***") == 0) cndx = -1; else while (cnode && strcmp (cnode->code, code)) { cndx++; cnode = cnode->cnext; } if (cnode == NULL) cndx = -1; return (cndx); } void fail (char *message, char *filename) { clrscr(); gotoxy (16,2); cprintf ("%s %s ", message, filename); gotoxy (16,3); perror (""); textattr (7); cursor (ON); exit (1); } int set_colors (WININFO *header, WININFO *center, WININFO *bottom) { int dispmode; struct text_info t_info; header->left = 2; header->top = 2; header->right = 77; header->bottom = 4; center->left = 2; center->top = 9; center->right = 77; center->bottom = 16; bottom->left = 2; bottom->top = 20; bottom->right = 77; bottom->bottom = 22; gettextinfo (&t_info); if (t_info.currmode == C40 || t_info.currmode == C80) { dispmode = COLOR; header->fore = YELLOW; header->back = MAGENTA; header->hifore = YELLOW; header->hiback = RED; header->bstyle = DOUBLE; header->bcolor = LIGHTGRAY; header->shadow = ON; center->fore = WHITE; center->back = CYAN; center->hifore = YELLOW; center->hiback = RED; center->bstyle = DOUBLE; center->bcolor = DARKGRAY; center->shadow = ON; bottom->fore = BLACK; bottom->back = GREEN; bottom->hifore = WHITE; bottom->hiback = RED; bottom->bstyle = DOUBLE; bottom->bcolor = DARKGRAY; bottom->shadow = ON; } else { dispmode = BW; header->fore = LIGHTGRAY; header->back = BLACK; header->hifore = LIGHTGRAY; header->hiback = BLACK; header->bstyle = DOUBLE; header->bcolor = LIGHTGRAY; header->shadow = OFF; center->fore = LIGHTGRAY; center->back = BLACK; center->hifore = LIGHTGRAY; center->hiback = BLACK; center->bstyle = DOUBLE; center->bcolor = LIGHTGRAY; center->shadow = OFF; bottom->fore = LIGHTGRAY; bottom->back = BLACK; bottom->hifore = LIGHTGRAY; bottom->hiback = BLACK; bottom->bstyle = DOUBLE; bottom->bcolor = LIGHTGRAY; bottom->shadow = OFF; } return (dispmode); } void clear_status (WININFO *win) { textattr (win->fore + (win->back << 4)); gotoxy (1,1); clreol(); } /********************************************************************** * the following code comes from DOSWDW by Edward V. Dong, a Turbo C * * implementation of EXECWINDOW by Kim Kokkonen, TurboPower Software, * * which was released to the public domain. * **********************************************************************/ void far DoDosWdw(int xleft,int ytop,int xrite,int ybottom,int attrib,char *cmd) { textattr(attrib); /* set text attribute */ window(xleft, ytop, xrite, ybottom); /* make the window */ clrscr(); /* clear the window */ wdwpos = ((ytop - 1) * 256) + (xleft - 1); wdwupr = wdwpos; wdwlwr = ((ybottom - 1) * 256) + (xrite - 1); wdwattr = (attrib); oldint21 = getvect(0x21); /* save old interrupt 21h */ setup21(0); /* move vector into CS (use 0 to scroll screen) */ setvect(0x21, newint21); /* point to dos window */ system(cmd); /* run the command */ setvect(0x21, oldint21); /* restore interrupt 21h */ }