home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / CEREBRUM / WWFFL114.ZIP / FFL.CPP next >
C/C++ Source or Header  |  2000-01-02  |  27KB  |  1,151 lines

  1. /* v1.4                                                                     */
  2. /* - Y2K-compliant date patches and display issues.  Compatibility with all */
  3. /*   changes in WWIV v4.3 code.                                             */
  4. /*                                                                          */
  5. /* v1.3                                                                     */
  6. /* - Added check for existence on files residing on hard disk (to account   */
  7. /*   for all the missing files after my crash!)                             */
  8. /*                                                                          */
  9. /* v1.2                                                                     */
  10. /* - Treats description to strip trailing CR/LF pairs                       */
  11. /* - Honors FILEnet flag to identify directory type (UFRD or successor).    */
  12. /*                                                                          */
  13. /* v1.1 changes                                                             */
  14. /* - Changed fprintf(...) to fputs() in several places to avoid unlinked    */
  15. /*   floating point errors which occurred with a "%f" was in description.   */
  16. /* - Replaced atime() routine with strftime() (TC function) as suggested    */
  17. /*   by Dawg.                                                               */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <stdarg.h>
  22. #include <sys\stat.h>
  23. #include <fcntl.h>
  24. #include <string.h>
  25. #include <dos.h>
  26. #include <io.h>
  27. #include <alloc.h>
  28. #include <time.h>
  29. #include <dir.h>
  30. #include <errno.h>
  31. #include <process.h>
  32. #include <ctype.h>
  33. #include <conio.h>
  34. #include <mem.h>
  35. #include <share.h>
  36. #include <math.h>
  37. #include <direct.h>
  38. #include "vardec.h"
  39. #include "net.h"
  40.  
  41. #define VERSION "1.4"
  42.  
  43. #define WAIT_TIME 10
  44. #define TRIES 100
  45. #define MT_DESQVIEW 0x01
  46. #define MT_WINDOWS  0x02
  47. #define MT_OS2      0x04
  48. #define DELIMS_WHITE " \t\r\n"
  49.  
  50. #define SETREC(f,i)  sh_lseek(f,((long) (i)) * \
  51.     ((long)sizeof(uploadsrec)), SEEK_SET);
  52.  
  53. #define LAST(s) s[strlen(s)-1]
  54.  
  55. typedef struct {
  56.   char nam[13], desc[59], uplddate[9];
  57.   unsigned long bytes;
  58.   int num;
  59. } toprec;
  60.  
  61. typedef struct {
  62.   char filename[9];
  63.   int type;
  64. } whichdir;
  65.  
  66. whichdir *DIR;
  67.  
  68. directoryrec huge *directories;
  69. configrec syscfg;
  70. configoverrec syscfgovr;
  71. toprec *top;
  72. net_networks_rec netcfg;
  73. static unsigned char whichtype[3] = {254, 240, 237};
  74.  
  75. char dlfn[81], text1[161], text2[161], maindir[161], buffer[201];
  76. int instance, net_num, net_num_max, num_dirs;
  77. int numdirs, multitasker, file_date;
  78. unsigned int totaldirs;
  79. unsigned long totalfiles, numf;
  80. char wwiv_net_no[20], net_name[16], net_data[121];
  81. unsigned short net_sysnum;
  82.  
  83. void dv_pause(void)
  84. {
  85.   _AX = 0x101a;
  86.   geninterrupt(0x15);
  87.   _AX = 0x1000;
  88.   geninterrupt(0x15);
  89.   _AX = 0x1025;
  90.   geninterrupt(0x15);
  91. }
  92.  
  93.  
  94. void win_pause(void)
  95. {
  96.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  97. }
  98.  
  99.  
  100. void giveup_timeslice(void)
  101. {
  102.   if (multitasker) {
  103.     switch (multitasker) {
  104.  case 1: 
  105.         dv_pause();
  106.         break;
  107.       case 2:
  108.         win_pause();
  109.         break;
  110.       case 3:
  111.         dv_pause();
  112.         break;
  113.       case 4:
  114.         _AX = 0x1680;
  115.         geninterrupt(0x2f);
  116.         break;
  117.       case 5:
  118.       case 6:
  119.       case 7:
  120.         win_pause();
  121.         break;
  122.       default:
  123.         break;
  124.     }
  125.   }
  126. }
  127.  
  128. int get_dos_version(void)
  129. {
  130.   _AX = 0x3000;
  131.   geninterrupt(0x21);
  132.   if (_AX % 256 >= 10) {
  133.     multitasker |= MT_OS2;
  134.   }
  135.   return (_AX);
  136. }
  137.  
  138.  
  139. int get_dv_version(void)
  140. {
  141.   int v;
  142.  
  143.   _AX = 0x2b01;
  144.   _CX = 0x4445;
  145.   _DX = 0x5351;
  146.   geninterrupt(0x21);
  147.   if (_AL == 0xff) {
  148.     return 0;
  149.   } else {
  150.     v = _BX;
  151.     multitasker |= MT_DESQVIEW;
  152.     return v;
  153.   }
  154. }
  155.  
  156.  
  157. int get_win_version(void)
  158. {
  159.   int v = 0;
  160.  
  161.   __emit__(0x55, 0x06, 0x53);
  162.  
  163.   _AX = 0x352f;
  164.   geninterrupt(0x21);
  165.   _AX = _ES;
  166.  
  167.   if (_AX | _BX) {
  168.  
  169.     _AX = 0x1600;
  170.     geninterrupt(0x2f);
  171.  
  172.     v = _AX;
  173.     if (v % 256 <= 1)
  174.       v = 0;
  175.   }
  176.   __emit__(0x5b, 0x07, 0x5d);
  177.  
  178.   if (v != 0)
  179.     multitasker |= MT_WINDOWS;
  180.   return (v);
  181. }
  182.  
  183. void detect_multitask(void)
  184. {
  185.   get_dos_version();
  186.   get_win_version();
  187.   get_dv_version();
  188. }
  189.  
  190.  
  191. int sh_open(char *path, int file_access, unsigned mode)
  192. {
  193.   int handle, count, share;
  194.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  195.  
  196.   if ((file_access & O_RDWR) || (file_access & O_WRONLY) ||
  197.       (mode & S_IWRITE)) {
  198.     share = SH_DENYRW;
  199.   } else {
  200.     share = SH_DENYWR;
  201.   }
  202.   handle = open(path, file_access | share, mode);
  203.   if (handle < 0) {
  204.     count = 1;
  205.     fnsplit(path, drive, dir, file, ext);
  206.     if (access(path, 0) != -1) {
  207.       delay(WAIT_TIME);
  208.       handle = open(path, file_access | share, mode);
  209.       while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
  210.         if (count % 2)
  211.           delay(WAIT_TIME);
  212.         else
  213.           giveup_timeslice();
  214.         count++;
  215.         handle = open(path, file_access | share, mode);
  216.       }
  217.     }
  218.   }
  219.   return (handle);
  220. }
  221.  
  222.  
  223. int sh_open1(char *path, int access)
  224. {
  225.   unsigned mode;
  226.  
  227.   mode = 0;
  228.   if ((access & O_RDWR) || (access & O_WRONLY))
  229.     mode |= S_IWRITE;
  230.   if ((access & O_RDWR) || (access & O_RDONLY))
  231.     mode |= S_IREAD;
  232.   return (sh_open(path, access, mode));
  233. }
  234.  
  235. long sh_lseek(int handle, long offset, int fromwhere)
  236. {
  237.  
  238.   if (handle == -1) {
  239.     return (-1L);
  240.   }
  241.   return (lseek(handle, offset, fromwhere));
  242. }
  243.  
  244.  
  245.  
  246. FILE *fsh_open(char *path, char *mode)
  247. {
  248.   FILE *f;
  249.   int count, share, md, fd;
  250.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  251.  
  252.   share = SH_DENYWR;
  253.   md = 0;
  254.   if (_fstrchr(mode, 'w') != NULL) {
  255.     share = SH_DENYRD;
  256.     md = O_RDWR | O_CREAT | O_TRUNC;
  257.   } else
  258.     if (_fstrchr(mode, 'a') != NULL) {
  259.     share = SH_DENYRD;
  260.     md = O_RDWR | O_CREAT;
  261.   } else {
  262.     md = O_RDONLY;
  263.   }
  264.   if (_fstrchr(mode, 'b') != NULL) {
  265.     md |= O_BINARY;
  266.   }
  267.   if (_fstrchr(mode, '+') != NULL) {
  268.     md &= ~O_RDONLY;
  269.     md |= O_RDWR;
  270.     share = SH_DENYRD;
  271.   }
  272.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  273.   if (fd < 0) {
  274.     count = 1;
  275.     fnsplit(path, drive, dir, file, ext);
  276.     if (access(path, 0) != -1) {
  277.       delay(WAIT_TIME);
  278.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  279.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  280.         delay(WAIT_TIME);
  281.         count++;
  282.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  283.       }
  284.     }
  285.   }
  286.   if (fd > 0) {
  287.     if (_fstrchr(mode, 'a'))
  288.       sh_lseek(fd, 0L, SEEK_END);
  289.  
  290.     f = fdopen(fd, mode);
  291.     if (!f) {
  292.       close(fd);
  293.     }
  294.   } else
  295.     f = 0;
  296.   return (f);
  297. }
  298.  
  299.  
  300. int sh_close(int f)
  301. {
  302.   if (f != -1)
  303.     close(f);
  304.   return (-1);
  305. }
  306.  
  307.  
  308. void fsh_close(FILE * f)
  309. {
  310.   fclose(f);
  311. }
  312.  
  313.  
  314.  
  315.  
  316.  
  317. int sh_read(int handle, void *buf, unsigned len)
  318. {
  319.  
  320.   if (handle == -1) {
  321.     return (-1);
  322.   }
  323.   return (read(handle, buf, len));
  324. }
  325.  
  326.  
  327. int sh_write(int handle, void *buf, unsigned len)
  328. {
  329.  
  330.   if (handle == -1) {
  331.     return (-1);
  332.   }
  333.   return (write(handle, buf, len));
  334. }
  335.  
  336. static unsigned char *trimstr1(unsigned char *s)
  337. {
  338.   int i;
  339.   static char *whitespace = " \r\n\t";
  340.  
  341.   i = strlen(s);
  342.  
  343.   while ((i > 0) && (_fstrchr(whitespace, s[i - 1])))
  344.     --i;
  345.  
  346.   while ((i > 0) && (_fstrchr(whitespace, *s))) {
  347.     memmove(s, s + 1, --i);
  348.   }
  349.  
  350.   s[i] = 0;
  351.   return (s);
  352. }
  353.  
  354. void far *malloca(unsigned long nbytes)
  355. {
  356.   void *buf;
  357.  
  358.   buf = (void *) farmalloc(nbytes + 1);
  359.   if (buf == NULL) {
  360.     cprintf("Unable to allocate %ld bytes memory!", nbytes + 1);
  361.   }
  362.   return (buf);
  363. }
  364.  
  365.  
  366. void far *mallocx(unsigned long l, char *where)
  367. {
  368.   void *x;
  369.   char huge *xx;
  370.  
  371.   if (!l)
  372.     l = 1;
  373.   x = (long *) malloca(l);
  374.   if (!x) {
  375.     fprintf(stderr, "Insufficient memory (%ld bytes) for %s.\n", l, where);
  376.     exit(EXIT_FAILURE);
  377.   }
  378.   xx = (char huge *) x;
  379.   while (l > 0L) {
  380.     if (l > 32768L) {
  381.       memset((void *) xx, 0, (int) 32768L);
  382.       l -= 32768L;
  383.       xx += 32768L;
  384.     } else {
  385.       memset((void *) xx, 0, (int) l);
  386.       break;
  387.     }
  388.   }
  389.   return (x);
  390. }
  391.  
  392. #define MAX_XFER 61440L
  393.  
  394. long huge_xfer(int fd, void huge * buf, unsigned sz, unsigned nel, int wr)
  395. {
  396.   long nxfr = 0, len = ((long) sz) * ((long) nel);
  397.   char huge *xbuf = (char huge *) buf;
  398.   unsigned cur, cur1;
  399.  
  400.   while (len > 0) {
  401.  
  402.     if (len > MAX_XFER)
  403.       cur = (unsigned int) MAX_XFER;
  404.     else
  405.       cur = (unsigned int) len;
  406.  
  407.     if (wr)
  408.       cur1 = sh_write(fd, (char *) xbuf, cur);
  409.     else
  410.       cur1 = sh_read(fd, (char *) xbuf, cur);
  411.  
  412.     if (cur1 != 65535L) {
  413.       len -= cur1;
  414.       nxfr += cur1;
  415.       xbuf = ((char huge *) buf) + nxfr;
  416.     }
  417.     if (cur1 != cur)
  418.       break;
  419.   }
  420.  
  421.   return (nxfr);
  422. }
  423.  
  424. void cd_to(char *s)
  425. {
  426.   char s1[81];
  427.   int i, db;
  428.  
  429.   strcpy(s1, s);
  430.   i = strlen(s1) - 1;
  431.   db = (s1[i] == '\\');
  432.   if (i == 0)
  433.     db = 0;
  434.   if ((i == 2) && (s1[1] == ':'))
  435.     db = 0;
  436.   if (db)
  437.     s1[i] = 0;
  438.   chdir(s1);
  439.   if (s[1] == ':')
  440.     setdisk(s[0] - 'A');
  441. }
  442.  
  443. void get_dir(char *s, int be)
  444. {
  445.   strcpy(s, "X:\\");
  446.   s[0] = 'A' + getdisk();
  447.   getcurdir(0, s + 3);
  448.   if (be) {
  449.     if (s[strlen(s) - 1] != '\\')
  450.       strcat(s, "\\");
  451.   }
  452. }
  453.  
  454. int exist(char *s)
  455. {
  456.   int i;
  457.   struct ffblk ff;
  458.  
  459.   i = findfirst(s, &ff, FA_HIDDEN);
  460.   if (i)
  461.     return (0);
  462.   else
  463.     return (1);
  464. }
  465.  
  466.  
  467. char *center_text(char *s)
  468. {
  469.   static char s1[160];
  470.   int i, x, col, lenx;
  471.   div_t len;
  472.  
  473.   i = 0;
  474.   x = 0;
  475.   lenx = strlen(s);
  476.  
  477.   while (s[x]) {
  478.     if (s[x] == 3) {
  479.       lenx--;
  480.       lenx--;
  481.     }
  482.     x++;
  483.   }
  484.   col = 80 - lenx;
  485.   len = div(col, 2);
  486.   i = len.quot;
  487.   strcpy(s1, "");
  488.   while (i > 0) {
  489.     strcat(s1, " ");
  490.     i--;
  491.   }
  492.   strcat(s1, s);
  493.   return (s1);
  494. }
  495.  
  496.  
  497. char *filedate(char *fpath)
  498. {
  499.   struct ftime d;
  500.   static char s[21];
  501.   int i;
  502.  
  503.   if (!exist(fpath))
  504.     return ("");
  505.  
  506.   i = sh_open1(fpath, O_RDONLY);
  507.   if (i == -1)
  508.     sprintf(s, "");
  509.   else {
  510.     if (getftime(i, &d) == 0)
  511.       sprintf(s, "%02d/%02d/%02d", d.ft_month, d.ft_day,
  512.            d.ft_year < 20 ? (d.ft_year + 80) : (d.ft_year - 20));
  513.     else
  514.       return ("");
  515.   }
  516.   i = sh_close(i);
  517.   return (s);
  518. }
  519.  
  520. void strip_colors(char *text)
  521. {
  522.   int pos = 0;
  523.   int len = strlen(text);
  524.  
  525.   while (pos < len && text[pos] != 26) {
  526.     if (text[pos] == 3) {
  527.       memmove(text + pos, text + pos + 2, len - pos);
  528.       --len;
  529.       --len;
  530.     } else {
  531.       if ((text[pos] == 13) || (text[pos] == 26) || (text[pos] == 37)) {
  532.         memmove(text + pos, text + pos + 1, len - pos);
  533.         --len;
  534.       } else
  535.         ++pos;
  536.     }
  537.   }
  538. }
  539.  
  540.  
  541. void sortlist(void)
  542. {
  543.   int i8, i9;
  544.   toprec temp;
  545.  
  546.   if (memcpy(&temp, &top[9], sizeof(toprec)) == NULL) {
  547.     fprintf(stderr, "Could not allocate %u bytes for top downloads!",
  548.             (sizeof(toprec) * 10));
  549.     return;
  550.   }
  551.   i8 = 9;
  552.   temp.num = top[9].num;
  553.   strcpy(temp.nam, top[9].nam);
  554.   strcpy(temp.desc, top[9].desc);
  555.   strcpy(temp.uplddate, top[9].uplddate);
  556.   temp.bytes = top[9].bytes;
  557.   while ((top[9].num >= top[i8].num) && (i8 >= 0)) {
  558.     i8--;
  559.   }
  560.   for (i9 = 8; i9 > i8; i9--) {
  561.     top[i9 + 1].num = top[i9].num;
  562.     strcpy(top[i9 + 1].nam, top[i9].nam);
  563.     strcpy(top[i9 + 1].desc, top[i9].desc);
  564.     strcpy(top[i9 + 1].uplddate, top[i9].uplddate);
  565.     top[i9 + 1].bytes = top[i9].bytes;
  566.   }
  567.   top[i8 + 1].num = temp.num;
  568.   strcpy(top[i8 + 1].nam, temp.nam);
  569.   strcpy(top[i8 + 1].desc, temp.desc);
  570.   strcpy(top[i8 + 1].uplddate, temp.uplddate);
  571.   top[i8 + 1].bytes = temp.bytes;
  572.   return;
  573. }
  574.  
  575.  
  576. void toplist(void)
  577. {
  578.   int ok, f, i, i1, i2, count, bad1, bad2, bad3;
  579.   char s[81], s1[81];
  580.   uploadsrec u1;
  581.   directoryrec tdir;
  582.  
  583.   for (count = 0; count < 10; count++) {
  584.     strcpy(top[count].nam, "01234567.ZIP");
  585.     strcpy(top[count].desc, "The quick brown fox jumps over the lazy dog.");
  586.     strcpy(top[count].uplddate, "00-00-00");
  587.     top[count].bytes = 0;
  588.     top[count].num = 0;
  589.   }
  590.   for (i2 = 0; (i2 < num_dirs); i2++) {
  591.     if (kbhit()) {
  592.       if (getch() == 27) {
  593.         cd_to(maindir);
  594.         fprintf(stderr, "\nAborted!\n\n");
  595.         exit(EXIT_FAILURE);
  596.       }
  597.     }
  598.     ok = 0;
  599.     tdir = directories[i2];
  600.     for (i = 0; i < numdirs; i++) {
  601.       if (strcmpi(DIR[i].filename, tdir.filename) == 0) {
  602.         ok = 1;
  603.         break;
  604.       }
  605.     }
  606.  
  607.     if (ok) {
  608.       sprintf(dlfn, "%s%s.DIR", syscfg.datadir, tdir.filename);
  609.       f = sh_open1(dlfn, O_RDONLY | O_BINARY);
  610.       if (f > -1) {
  611.         sh_read(f, (void *) &u1, sizeof(uploadsrec));
  612.         numf = u1.numbytes;
  613.         sprintf(text2, "%s", tdir.name);
  614.         fprintf(stderr, "\rSearching for top downloads in %-30.30s", text2);
  615.         for (i1 = 1; i1 <= numf; i1++) {
  616.           if (multitasker)
  617.             giveup_timeslice();
  618.           SETREC(f, i1);
  619.           sh_read(f, (void *) &u1, sizeof(uploadsrec));
  620.           if (u1.numdloads > top[9].num) {
  621.             strcpy(top[9].nam, u1.filename);
  622.             strip_colors(u1.description);
  623.             strcpy(top[9].desc, u1.description);
  624.             if ((file_date) && (!(tdir.mask & mask_cdrom))) {
  625.               sprintf(s, "%s%s", tdir.path, u1.filename);
  626.               strcpy(s1, filedate(s));
  627.               if (s1[0] != 0)
  628.                 strcpy(top[9].uplddate, s1);
  629.               else {
  630.                 if ((u1.date[0] == 0) || (isalpha(u1.date[0])))
  631.                   strcpy(top[9].uplddate, "UNKNOWN ");
  632.                 else {
  633.                   strcpy(top[9].uplddate, u1.date);
  634.                   sscanf(top[9].uplddate, "%02d/%02d/%02d", &bad1,
  635.                          &bad2, &bad3);
  636.                   if (((bad1 <= 0) || (bad1 > 12)) || ((bad2 <= 0) ||
  637.                                                 (bad2 > 31)) || (bad3 <= 0))
  638.                     strcpy(top[9].uplddate, "UNKNOWN ");
  639.                   else
  640.                     sprintf(top[9].uplddate, "%02d-%02d-%02d", bad1,
  641.                             bad2, bad3);
  642.                 }
  643.               }
  644.             } else {
  645.               if ((u1.date[0] == 0) || (isalpha(u1.date[0])))
  646.                 strcpy(top[9].uplddate, "UNKNOWN ");
  647.               else {
  648.                 strcpy(top[9].uplddate, u1.date);
  649.                 sscanf(top[9].uplddate, "%02d/%02d/%02d", &bad1, &bad2, &bad3);
  650.                 if (((bad1 <= 0) || (bad1 > 12)) || ((bad2 <= 0) ||
  651.                                                 (bad2 > 31)) || (bad3 <= 0))
  652.                   strcpy(top[9].uplddate, "UNKNOWN ");
  653.                 else
  654.                   sprintf(top[9].uplddate, "%02d-%02d-%02d", bad1, bad2, bad3);
  655.               }
  656.             }
  657.             top[9].bytes = u1.numbytes;
  658.             top[9].num = u1.numdloads;
  659.             sortlist();
  660.           }
  661.         }
  662.         f = sh_close(f);
  663.       }
  664.     }
  665.   }
  666. }
  667.  
  668. char *stripfn(char *fn)
  669. {
  670.   static char ofn[15];
  671.   int i,i1;
  672.   char s[81];
  673.  
  674.   i1=-1;
  675.   for (i=0; i<strlen(fn); i++)
  676.     if ((fn[i]=='\\') || (fn[i]==':') || (fn[i]=='/'))
  677.       i1=i;
  678.   if (i1!=-1)
  679.     strcpy(s,&(fn[i1+1]));
  680.   else
  681.     strcpy(s,fn);
  682.   for (i=0; i<strlen(s); i++)
  683.     if ((s[i]>='A') && (s[i]<='Z'))
  684.       s[i]=s[i]-'A'+'a';
  685.   i=0;
  686.   while (s[i]!=0) {
  687.     if (s[i]==32)
  688.       strcpy(&s[i],&s[i+1]);
  689.     else
  690.       ++i;
  691.   }
  692.   strcpy(ofn,s);
  693.   return(ofn);
  694. }
  695.  
  696.  
  697. void align(char *s)
  698. {
  699.   char f[40], e[40], s1[20], *s2;
  700.   int i, i1, i2;
  701.  
  702.   i1 = 0;
  703.   if (s[0] == '.')
  704.     i1 = 1;
  705.   for (i = 0; i < strlen(s); i++)
  706.     if ((s[i] == '\\') || (s[i] == '/') || (s[i] == ':') || (s[i] == '<') ||
  707.         (s[i] == '>') || (s[i] == '|'))
  708.       i1 = 1;
  709.   if (i1) {
  710.     strcpy(s, "!");
  711.     return;
  712.   }
  713.   s2 = strchr(s, '.');
  714.   if (s2 == NULL) {
  715.     e[0] = 0;
  716.   } else {
  717.     strcpy(e, &(s2[1]));
  718.     e[3] = 0;
  719.     s2[0] = 0;
  720.   }
  721.   strcpy(f, s);
  722.  
  723.   for (i = strlen(f); i < 8; i++)
  724.     f[i] = 32;
  725.   f[8] = 0;
  726.   i1 = 0;
  727.   i2 = 0;
  728.   for (i = 0; i < 8; i++) {
  729.     if (f[i] == '*')
  730.       i1 = 1;
  731.     if (f[i] == ' ')
  732.       i2 = 1;
  733.     if (i2)
  734.       f[i] = ' ';
  735.     if (i1)
  736.       f[i] = '?';
  737.   }
  738.  
  739.   for (i = strlen(e); i < 3; i++)
  740.     e[i] = 32;
  741.   e[3] = 0;
  742.   i1 = 0;
  743.   for (i = 0; i < 3; i++) {
  744.     if (e[i] == '*')
  745.       i1 = 1;
  746.     if (i1)
  747.       e[i] = '?';
  748.   }
  749.  
  750.   for (i = 0; i < 12; i++)
  751.     s1[i] = 32;
  752.   strcpy(s1, f);
  753.   s1[8] = '.';
  754.   strcpy(&(s1[9]), e);
  755.   strcpy(s, s1);
  756.   strupr(s);
  757. }
  758.  
  759. char *unalign(char *filename)
  760. {
  761.   char *temp, *exttemp;
  762.  
  763.   temp = strstr(filename, " ");
  764.   if (temp) {
  765.     temp[0] = 0;
  766.     ++temp;
  767.     exttemp = strstr(temp, ".");
  768.     if (exttemp)
  769.       strcat(filename, exttemp);
  770.   }
  771.   return (filename);
  772. }
  773.  
  774.  
  775.  
  776. unsigned long file_lister(char *listname, char *which, char type)
  777. {
  778.   int i1, i2, f;
  779.   int ok, na, dir, newflag, bad1, bad2, bad3;
  780.   long l, nscandate;
  781.   static char s[101], s1[81], s2[81], s3[81], s4[81];
  782.   struct date d;
  783.   struct time t;
  784.   uploadsrec u;
  785.   directoryrec one_dir;
  786.   FILE *fp;
  787.  
  788.   gettime(&t);
  789.   getdate(&d);
  790.  
  791.   if (d.da_mon > 1) {
  792.     d.da_mon = d.da_mon - 1;
  793.   } else {
  794.     d.da_mon = 12;
  795.     d.da_year = d.da_year - 1;
  796.   }
  797.   t.ti_min = 0;
  798.   t.ti_hour = 0;
  799.   t.ti_hund = 0;
  800.   t.ti_sec = 0;
  801.   nscandate = dostounix(&d, &t);
  802.  
  803.   fp = fsh_open(listname, "a+t");
  804.  
  805.   for (dir = 0; dir < num_dirs; dir++) {
  806.     one_dir = directories[dir];
  807.     ok = 0;
  808.     if (strcmp(one_dir.filename, which) == 0)
  809.       ok = 1;
  810.     if (ok) {
  811.       ++totaldirs;
  812.       sprintf(text1, "%s", one_dir.name);
  813.       fprintf(stderr, "\rAdding files in %-45.45s", text1);
  814.       sprintf(dlfn, "%s%s.DIR", syscfg.datadir, one_dir.filename);
  815.       f = sh_open1(dlfn, O_RDONLY | O_BINARY);
  816.       numf = 0;
  817.       if (f > -1) {
  818.         sh_read(f, (void *) &u, sizeof(uploadsrec));
  819.         numf = u.numbytes;
  820.         sprintf(buffer, "\n%c %s (%ld files) %c\n", type, one_dir.name,
  821.                 numf, type);
  822.         fputs(buffer, fp);
  823.         for (i1 = 1; (i1 <= numf); i1++) {
  824.           if (kbhit()) {
  825.             if (getch() == 27) {
  826.               cd_to(maindir);
  827.               fprintf(stderr, "\nFile listing aborted!\n\n");
  828.               exit(EXIT_FAILURE);
  829.             }
  830.           }
  831.           SETREC(f, i1);
  832.           sh_read(f, (void *) &u, sizeof(uploadsrec));
  833.           newflag = 0;
  834.           if (u.daten == 0L) {
  835.             time(&l);
  836.             u.daten = l;
  837.           }
  838.           if (u.daten >= nscandate)
  839.             newflag = 1;
  840.           if ((u.date[0] == 0) || (isalpha(u.date[0])))
  841.             strcpy(s3, "UNKNOWN ");
  842.           else {
  843.             strcpy(s3, u.date);
  844.             sscanf(s3, "%02d/%02d/%02d", &bad1, &bad2, &bad3);
  845.             if (((bad1 <= 0) || (bad1 > 12)) || ((bad2 <= 0) ||
  846.                                 (bad2 > 31)) || (bad3 <= 0))
  847.               strcpy(s3, "UNKNOWN ");
  848.             else
  849.               sprintf(s3, "%02d-%02d-%02d", bad1, bad2, bad3);
  850.           }
  851.  
  852.           if (!(one_dir.mask & mask_cdrom)) {
  853.             strcpy(s1, one_dir.path);
  854.             strcat(s1, stripfn(u.filename));
  855.             na = (exist(s1));
  856.             align(u.filename);
  857.           }
  858.  
  859.           if ((na) || (one_dir.mask && mask_cdrom)) {
  860.             s1[0] = 0;
  861.             sprintf(s, "%s", ltoa((((u.numbytes) + 1023) / 1024), s1, 10));
  862.             sprintf(s1, "%sK", s);
  863.           } else
  864.             sprintf(s1, "N/A");
  865.  
  866.           strcpy(s2, u.filename);
  867.           unalign(s2);
  868.           strcpy(s4, u.description);
  869.           strip_colors(s4);
  870.           trimstr1(s4);
  871.           s4[48] = NULL;
  872.           sprintf(buffer, "%-12s %6s%s %s  %s\n", s2, s1,
  873.                   (newflag ? "*" : " "), s3, s4);
  874.           fputs(buffer, fp);
  875.         }
  876.       }
  877.       f = sh_close(f);
  878.       if (!numf) {
  879.         sprintf(buffer, "   No Files in Directory\n");
  880.         fputs(buffer, fp);
  881.       }
  882.     }
  883.   }
  884.   fsh_close(fp);
  885.   return numf;
  886. }
  887.  
  888. void set_net_num(int n)
  889. {
  890.   char s[121];
  891.   int f;
  892.  
  893.   sprintf(s, "%sNETWORKS.DAT", syscfg.datadir);
  894.   f = sh_open1(s, O_RDONLY | O_BINARY);
  895.   if (f < 0)
  896.     return;
  897.   lseek(f, ((long) (n)) * sizeof(net_networks_rec), SEEK_SET);
  898.   sh_read(f, &netcfg, sizeof(net_networks_rec));
  899.   close(f);
  900.   net_num = n;
  901.   net_sysnum = netcfg.sysnum;
  902.   strcpy(net_name, netcfg.name);
  903.   strcpy(net_data, netcfg.dir);
  904.   if (LAST(net_data) != '\\')
  905.     strcat(net_data, "\\");
  906.   sprintf(wwiv_net_no, "WWIV_NET=%d", net_num);
  907. }
  908.  
  909. int count_lines(char *s)
  910. {
  911.   FILE *fp;
  912.   char fn[121];
  913.   unsigned int nl = 0;
  914.   const int NEWLINE = '\n';
  915.   int c;
  916.  
  917.   strcpy(fn, s);
  918.   fp = fsh_open(fn, "rt");
  919.   if (fp == NULL) {
  920.     printf("\n ■ Cannot open %s", fn);
  921.     return 0;
  922.   }
  923.   while ((c = getc(fp)) != EOF) {
  924.     if (c == NEWLINE)
  925.       ++nl;
  926.   }
  927.   fclose(fp);
  928.   return nl;
  929. }
  930.  
  931. #pragma warn -par
  932. void main(int argc, char *argv[])
  933. {
  934.  
  935.   int i, i1, ok, dirtype;
  936.   char s[101], s1[21], fsize[11], fname[21], fdesc[81], flist[MAXPATH], *ss;
  937.   FILE *fp;
  938.   time_t now;
  939.   struct tm *ptr;
  940.  
  941.   time(&now);
  942.   ptr = localtime(&now);
  943.  
  944. #ifdef DEBUG
  945.   cprintf("\r\nSize of directoryrec = %d", sizeof(directoryrec));
  946.   cprintf("\r\nSize of toprec = %d", sizeof(toprec));
  947.   cprintf("\r\nSize of configrec = %d", sizeof(configrec));
  948.   cprintf("\r\nSize of configoverrec = %d", sizeof(configoverrec));
  949.   getch();
  950. #endif
  951.   fprintf(stderr, "\nFILEnet File Lister v%s\n", VERSION);
  952.   get_dir(maindir, 1);
  953.   detect_multitask();
  954.   ss = getenv("WWIV_INSTANCE");
  955.   if (ss) {
  956.     instance = atoi(ss);
  957.     if ((instance <= 0) || (instance > 999)) {
  958.       fprintf(stderr, "WWIV_INSTANCE can only be 1..999!");
  959.       instance = 1;
  960.     }
  961.   } else {
  962.     instance = 1;
  963.   }
  964.   i = -1;
  965.   s[0] = 0;
  966.   strcpy(s, "CONFIG.DAT");
  967.   i = sh_open1(s, O_RDONLY | O_BINARY);
  968.   if (i < 0) {
  969.     fprintf(stderr, "\n%s%s not found.  Run in BBS main directory!\n\n",
  970.             maindir, s);
  971.     cd_to(maindir);
  972.     exit(EXIT_FAILURE);
  973.   }
  974.   read(i, (void *) (&syscfg), sizeof(configrec));
  975.   i = sh_close(i);
  976.  
  977.   strcpy(s, "CONFIG.OVR");
  978.   i = sh_open1(s, O_RDONLY | O_BINARY);
  979.   if (i < 0) {
  980.     fprintf(stderr, "\n%s%s not found.\n\n", maindir, s);
  981.     cd_to(maindir);
  982.     exit(EXIT_FAILURE);
  983.   }
  984.   sh_lseek(i, (instance - 1) * sizeof(configoverrec), SEEK_SET);
  985.   read(i, &syscfgovr, sizeof(configoverrec));
  986.   i = sh_close(i);
  987.  
  988.   directories = (directoryrec *) mallocx(((long) syscfg.max_dirs) *
  989.                               ((long) sizeof(directoryrec)), "directories");
  990.   sprintf(s, "%sDIRS.DAT", syscfg.datadir);
  991.   i = sh_open1(s, O_RDWR | O_BINARY);
  992.   if (i < 0) {
  993.     fprintf(stderr, "\n%s not found!\n\n", s);
  994.     cd_to(maindir);
  995.     exit(EXIT_FAILURE);
  996.   } else {
  997.     num_dirs = (int) huge_xfer(i, directories, sizeof(directoryrec),
  998.                                syscfg.max_dirs, 0) / sizeof(directoryrec);
  999.   }
  1000.   i = sh_close(i);
  1001.  
  1002.   top = (toprec *) malloca((long) 10 * sizeof(toprec) + 1);
  1003.   if (top == NULL) {
  1004.     fprintf(stderr, "\nCould not allocate %u bytes for top downloads!\n\n",
  1005.             sizeof(toprec) * 10);
  1006.     exit(EXIT_FAILURE);
  1007.   }
  1008.   sprintf(s, "%sNETWORKS.DAT", syscfg.datadir);
  1009.   i = sh_open1(s, O_RDONLY | O_BINARY);
  1010.   net_num_max = 0;
  1011.   if (i > 0) {
  1012.     net_num_max = (int) (filelength(i) / sizeof(net_networks_rec));
  1013.     i = sh_close(i);
  1014.   }
  1015.   ok = 1;
  1016.   for (i = 0; i < net_num_max && ok; i++) {
  1017.     set_net_num(i);
  1018.     if (strnicmp(net_name, "filenet", 7) == 0) {
  1019.       ok = 0;
  1020.       net_num = i;
  1021.     }
  1022.   }
  1023.   if (ok) {
  1024.     fprintf(stderr, "\nFILEnet not defined in INIT... aborting.\n\n");
  1025.     cd_to(maindir);
  1026.     exit(EXIT_FAILURE);
  1027.   }
  1028. #ifdef DEBUG
  1029.   else
  1030.     fprintf(stderr, "\nFILEnet found in INIT!\n\n");
  1031. #endif
  1032.  
  1033.   sprintf(s, "%sDIRLIST.FTS", net_data);
  1034.   if (!exist(s)) {
  1035.     fprintf(stderr, "\n%s not found!\n\n", s);
  1036.     cd_to(maindir);
  1037.     exit(EXIT_FAILURE);
  1038.   }
  1039.   numdirs = count_lines(s);
  1040.   DIR = (whichdir *) malloc((numdirs + 2) * sizeof(whichdir));
  1041.   if (!DIR) {
  1042.     fprintf(stderr, "\nInsufficient memory for %s.\n\n", s);
  1043.     cd_to(maindir);
  1044.     exit(EXIT_FAILURE);
  1045.   } else {
  1046.     fprintf(stderr,
  1047.       "\nCreating file list of %d directories... [Esc] aborts!\n", numdirs);
  1048.   }
  1049.   fp = fsh_open(s, "rt");
  1050.   i = dirtype = 0;
  1051.   while (fgets(s, 9, fp) != NULL) {
  1052.     if ((s[0]) && ((s[0] != 10) && (s[0] != 13))) {
  1053.       ss = strtok(s, " \r\n");
  1054.       trimstr1(ss);
  1055.       if (ss[0] == '!') {
  1056.         strcpy(s1, &ss[1]);
  1057.         if (strnicmp(s1, "REGULAR", 7) == 0)
  1058.           dirtype = 0;
  1059.         else
  1060.           if (strnicmp(s1, "SYSOP", 5) == 0)
  1061.           dirtype = 1;
  1062.         else
  1063.           if (strnicmp(s1, "WWIVREG", 7) == 0)
  1064.           dirtype = 2;
  1065.       } else {
  1066.         strcpy(DIR[i].filename, ss);
  1067.         DIR[i].type = dirtype;
  1068.       }
  1069.       i++;
  1070.     }
  1071.   }
  1072. #ifdef DEBUG
  1073.   fprintf(stderr, "\nNow looking at %d dirs.\n", numdirs);
  1074.   for (i = 0; i < numdirs; i++)
  1075.     fprintf(stderr, "\n%s", DIR[i].filename);
  1076.   getch();
  1077. #endif
  1078.   toplist();
  1079.   sprintf(flist, "%sL%hu.FTS", net_data, net_sysnum);
  1080.   fp = fsh_open(flist, "wt+");
  1081.   if (!fp) {
  1082.     fprintf(stderr, "\nUnable to open %s for write operation.", flist);
  1083.     cd_to(maindir);
  1084.     exit(EXIT_FAILURE);
  1085.   }
  1086.   fprintf(fp, "╒");
  1087.   for (i = 0; i < 77; i++)
  1088.     fprintf(fp, "═");
  1089.   fprintf(fp, "╕\n│");
  1090.   for (i = 0; i < 77; i++)
  1091.     fprintf(fp, " ");
  1092.   fprintf(fp, "│\n│");
  1093.   sprintf(text1, "File Listing from %s (%hu.FILEnet)", syscfg.systemname,
  1094.           net_sysnum);
  1095.   sprintf(s, "%s", center_text(text1));
  1096.   fputs(s, fp);
  1097.   for (i = 77; i > strlen(s); i--)
  1098.     fprintf(fp, " ");
  1099.   fprintf(fp, "│\n│");
  1100.   strftime(text1, 80, "as of %A, %B %d, %Y", ptr);
  1101.   sprintf(s, "%s", center_text(text1));
  1102.   fputs(s, fp);
  1103.   for (i = 77; i > strlen(s); i--)
  1104.     fprintf(fp, " ");
  1105.   fprintf(fp, "│\n│");
  1106.   for (i = 0; i < 77; i++)
  1107.     fprintf(fp, " ");
  1108.   fprintf(fp, "│\n");
  1109.   fprintf(fp, "╘");
  1110.   for (i = 0; i < 77; i++)
  1111.     fprintf(fp, "═");
  1112.   fprintf(fp, "╛\n\n");
  1113.   sprintf(text1, "Files marked with \'*\' are less than 30 days old.\n");
  1114.   sprintf(buffer, "%s", center_text(text1));
  1115.   fputs(buffer, fp);
  1116.   fprintf(fp, "\n");
  1117.   fprintf(fp, "■ Top Ten Downloaded Files ■");
  1118.   for (i = 0; i < 10; i++) {
  1119.     ltoa((((top[i].bytes) + 1023) / 1024), fsize, 10);
  1120.     strcat(fsize, "K");
  1121.     strncpy(fname, top[i].nam, 8);
  1122.     i1 = 8;
  1123.     while (i1--)
  1124.       if (fname[i1] != ' ')
  1125.         break;
  1126.     fname[i1 + 1] = '\0';
  1127.     strncat(fname, &((top[i].nam)[8]), 4);
  1128.     trimstr1(top[i].desc);
  1129.     strcpy(fdesc, top[i].desc);
  1130.     if (strlen(fdesc) > 42)
  1131.       fdesc[42] = '\0';
  1132.     sprintf(buffer, "\n%-12s %6s %s [%03.03d] %s",
  1133.             fname, fsize, top[i].uplddate, top[i].num, fdesc);
  1134.     fputs(buffer, fp);
  1135.   }
  1136.   fprintf(fp, "\n");
  1137.   fclose(fp);
  1138.   totaldirs = 0;
  1139.   totalfiles = 0L;
  1140.   for (i = 0; i < numdirs; i++)
  1141.     totalfiles += file_lister(flist, DIR[i].filename, whichtype[DIR[i].type]);
  1142.   fp = fsh_open(flist, "a+t");
  1143.   if (fp) {
  1144.     sprintf(buffer, "\n%ld total files in %d directories.", totalfiles,
  1145.             totaldirs);
  1146.     fputs(buffer, fp);
  1147.   }
  1148.   fsh_close(fp);
  1149.   exit(EXIT_SUCCESS);
  1150. }
  1151.