home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / FTSER10.ZIP / FTSER.C < prev    next >
C/C++ Source or Header  |  2000-02-13  |  15KB  |  501 lines

  1. /*************************************************************************
  2. * FTS list updater and maintainer.  At least it's commented this time.
  3. ************************************************************************/
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <dos.h>
  9. #include <fcntl.h>
  10. #include <sys/stat.h>
  11. #include <ctype.h>
  12. #include <conio.h>
  13. #include <io.h>
  14. #include <share.h>
  15. #include <errno.h>
  16. #include <dir.h>
  17. #include <time.h>
  18. #include <process.h>
  19. #include <spawno.h>
  20. #include <datelib.h>
  21.  
  22. /* datelib.h is freeware code by Brady Tippit, and seems to be invulnerable
  23. *  to both Y2K and the "binary millenium".  The full archive is included
  24. *  with this distribution as a convenience if you wish to recompile this
  25. *  source.  I owe him a great debt;  I doubt I could have coded his stuff.
  26. *  Basically all non-ANSI C time coding is his.*/
  27.  
  28. /************************************************************************
  29. * Share and Multitasking stolen wholesale from the PPP project around
  30. * Beta-85 or so.
  31. ************************************************************************/
  32.  
  33. #define WAIT_TIME 10
  34. #define TRIES 100
  35. #define SHARE_LEVEL 10
  36. #define MT_DESQVIEW 0x01
  37. #define MT_WINDOWS  0x02
  38. #define MT_OS2      0x04
  39. #define MT_NB       0x40
  40.  
  41. /* my global structures, variables, etc.  I hate passing lots of stuff
  42. *  when all my functions use the same things */
  43. #define YES 0
  44. #define NO 1
  45.  
  46.  int multitasker=0;
  47.  int nodeindex,listindex,aged=30;
  48.  int removedlists=0,missinglists=0,oldlists=0;
  49.  int maxnode,maxlist; /* maximum record to look at */
  50.  char filedir[256],listdir[256];
  51.  
  52. struct {
  53.   int number; /* node number, silly */
  54.   int list; /* does it exist? */
  55.   long int age;  /* of file list */
  56.   } node[300];  /* Storing node information here */
  57.  
  58. struct {        /* This is to store bbslist.* from bbslist.0 */
  59.   int number;   /* as I found from GFLINK, is not save to assume that */
  60.   } bbslist[30]; /* all existing files are used in bbslist.0 */
  61.  
  62. FILE *fsh_open(char *path, char *fmode);
  63. long sh_lseek(int handle, long offset, int fromwhere);
  64. void giveup_timeslice(void);
  65. void detect_multitask(void);
  66. int get_nb_version(void);
  67. int get_dos_version(void);
  68. int get_win_version(void);
  69. int get_dv_version(void);
  70. void extra_lists(void);
  71. void request_missing(void);
  72. void request_old(void);
  73.  
  74. /*************************************************************************
  75. * Finds extra lists and nukes 'em.
  76. ************************************************************************/
  77. void extra_lists(void)
  78.  {
  79.  struct ffblk ffblk;
  80.  char scrap[256],scrap2[256];
  81.  short qwerty,match=NO;
  82.  
  83.  sprintf(scrap,"%sL*.FTS",listdir);
  84.  qwerty=findfirst(scrap,&ffblk,0);
  85.  while (!qwerty)
  86.   {
  87.   match=NO;
  88.   sprintf(scrap,"%s%s",listdir,ffblk.ff_name); /* the file name in question */
  89.   for (nodeindex=0;(nodeindex<=maxnode)&&match==NO;nodeindex++)
  90.    {
  91.    sprintf(scrap2,"%sL%d.FTS",listdir,node[nodeindex].number);
  92.    if (stricmp(scrap,scrap2)==YES)
  93.     match=YES;
  94.    }
  95.   if (match==NO)
  96.    {
  97.    removedlists++;
  98.    printf("■ Removing %s\n",scrap);
  99.    unlink(scrap);
  100.    }
  101.   qwerty=findnext(&ffblk);
  102.   }
  103.  /*****************************************************************
  104.  * Yes, I could have just split the path.  But this way I'm a little closer
  105.  * to UNIX compatibility.  Sorta.
  106.  **********************************************************************/
  107.  sprintf(scrap,"%sDIRFILE\\L*.DIR",listdir);
  108.  qwerty=findfirst(scrap,&ffblk,0);
  109.  while (!qwerty)
  110.   {
  111.   match=NO;
  112.   sprintf(scrap,"%sDIRFILE\\%s",listdir,ffblk.ff_name); /* the file name in question */
  113.   for (nodeindex=0;(nodeindex<=maxnode)&&match==NO;nodeindex++)
  114.    {
  115.    sprintf(scrap2,"%sDIRFILE\\L%d.DIR",listdir,node[nodeindex].number);
  116.    if (stricmp(scrap,scrap2)==YES)
  117.     match=YES;
  118.    }
  119.   if (match==NO)
  120.    {
  121.    printf("■ Removing %s\n",scrap);
  122.    unlink(scrap);
  123.    }
  124.   qwerty=findnext(&ffblk);
  125.   }
  126.  }
  127.  
  128. /*************************************************************************
  129. * Requests any missing lists.  Simple spawning techniques.
  130. ************************************************************************/
  131.  
  132. void request_missing(void)
  133.  {
  134.  char misstemp[256],misstemp0[20];
  135.  
  136.  chdir(filedir);
  137.  for (nodeindex=0;(nodeindex<=maxnode);nodeindex++)
  138.   {
  139.   if (node[nodeindex].number==32767) /* like you need one from the net */
  140.    continue;
  141.   if (node[nodeindex].list==NO) /* Ah-ha! */
  142.    {
  143.    missinglists++;
  144.    sprintf(misstemp,"%s\\FTSREQ.EXE",filedir);
  145.    sprintf(misstemp0,"-@%d",node[nodeindex].number);
  146.    spawnl(P_WAIT,misstemp,"FTSREQ.EXE","-L",misstemp0,NULL);
  147.    }
  148.   }
  149.  }
  150.  
  151. /*************************************************************************
  152. * Requests any lists which have a value over passed "aged"
  153. ************************************************************************/
  154.  
  155. void request_old(void)
  156.  {
  157.  char oldtemp[256],oldtemp0[20];
  158.  
  159.  chdir(filedir);
  160.  for (nodeindex=0;(nodeindex<=maxnode);nodeindex++)
  161.   {
  162.   if (node[nodeindex].number==32767) /* like you need one from the net */
  163.    continue;
  164.   if ((node[nodeindex].age>=aged)||(aged==0)) /* If "aged" is 0==request all */
  165.    {
  166.    oldlists++;
  167.    sprintf(oldtemp,"%s\\FTSREQ.EXE",filedir);
  168.    sprintf(oldtemp0,"-@%d",node[nodeindex].number);
  169.    spawnl(P_WAIT,oldtemp,"FTSREQ.EXE","-L",oldtemp0,NULL);
  170.    }
  171.   }
  172.  }
  173.  
  174. /*************************************************************************
  175. * Main reads in arguments and node data, then passes to the relevant
  176. * subprocesses.  In theory, anyway.
  177. ************************************************************************/
  178.  
  179. void main(int argc, char *argv[])
  180.  {
  181.  FILE *read;
  182.  int missing=NO,old=NO;
  183.  
  184.  struct ftime timecrap;   /* time declarations */
  185.  tdtype *date1,*date2;
  186.  int month, day, year;
  187.  char timetemp[256];
  188.  
  189.  /* miscellaneous temp variables */
  190.  char crap[256],smallcrap[20],smallcrap0[20];
  191.  char *p;
  192.  int junk;
  193.  
  194.  /* end of defines, program starts */
  195.  printf("\n■ Fts'er v1.0 - A UrielSoft Product\n");
  196.  if (argc < 2)
  197.   {
  198.   printf("φ Usage is FTSER [path] -<a[age]/o[age]/m>\n");
  199.   printf("φ [path] is the DOS path for Filenet, withOUT trailing backslash.\n");
  200.   printf("φ Switches: \n");
  201.   printf("φ -a = Request lists older than [age] and missing lists\n");
  202.   printf("φ -o = Request lists older than [age]\n");
  203.   printf("φ -m = Request missing lists\n");
  204.   printf("φ [age] is a value in days, and defaults to 30.\n");
  205.   printf("φ [age] == 0 requests all lists.\n");
  206.   printf("φ Lists from non-existent nodes are automatically purged.\n");
  207.   exit(100);
  208.   }
  209.  for (nodeindex = 0; nodeindex < 300;nodeindex++)
  210.   {
  211.   node[nodeindex].number = 32767; /* setting to a "stop" value */
  212.   node[nodeindex].list=NO;
  213.   node[nodeindex].age=0;
  214.   }
  215.  for (listindex = 0; listindex < 30;listindex++)
  216.   bbslist[listindex].number = 32767; /* setting to "stop" value */
  217.  
  218.  if ((strncmpi("-a",argv[2],2)==YES)||(strncmpi("-m",argv[2],2)==YES))
  219.   missing=YES;
  220.  if ((strncmpi("-a",argv[2],2)==YES)||(strncmpi("-o",argv[2],2)==YES))
  221.   {
  222.   old=YES;
  223.   sprintf(smallcrap,"%s",argv[2]); /*redundancy; sometimes have problems with argvs */
  224.   for (junk=2;junk<=(strlen(smallcrap));junk++)
  225.    smallcrap0[junk-2]=smallcrap[junk];  /*this should strip -? and leave age */
  226.   if (atoi(smallcrap0)==0) /* error in atoi? */
  227.    {
  228.    if (smallcrap[3]=='0')
  229.     aged=0; /* nope, atoi returned the correct value instead of an error */
  230.    } else {  /* atoi returned non-zero number */
  231.    aged=atoi(smallcrap0);
  232.    }  /* If neither called, age remains at 30 */
  233.   printf("■ Filelist Request Age set to %d days.\n",aged);
  234.   }
  235.  sprintf(filedir,"%s",argv[1]);
  236.  if (chdir(filedir)!=YES)
  237.   {
  238.   printf("φ Error in changing to Filenet directory! Check paths and drives!\n");
  239.   exit(100);
  240.   }
  241.  /* must find out where filelist directory is located! */
  242.  /* okay, so I could have this now run without telling it anything. */
  243.  /* But I don't want to.  So there.  Ha.  I *LIKE* programs that tell you */
  244.  /* about themselves when run without arguments and you're an idiot. =) */
  245.  sprintf(crap,"%s\\FDLFTS.CFG",filedir);
  246.  read=fsh_open(crap,"rt");
  247.  while ((fgets(crap,254,read)!=NULL))
  248.   {
  249.   if (strnicmp(crap,"ALT_PATH",8)==YES)
  250.    sscanf(crap,"%s%s",smallcrap,listdir);
  251. //  if (strnicmp(crap,"LOG_PATH",8)==YES)  /* could easily be enabled for */
  252. //   sscanf(crap,"%s%s",smallcrap,logpath); /* logging, but most is already done! */
  253.   }
  254.  fclose(read);
  255.  /* reading in correct bbslists, etc */
  256.  sprintf(crap,"%s\\BBSLIST.0",filedir);
  257.  read=fsh_open(crap,"rt");
  258.  if (read!=NULL)
  259.   {
  260.   maxlist=0;  /* starting at record zero - we also set maxlist here */
  261.   maxnode=0;
  262.   nodeindex=0; /* these start at zero as we first start this run */
  263.   while ((fgets(crap,254,read)!=NULL))
  264.    {
  265.    sscanf(crap,"%s",smallcrap);  /* just want the first bit... */
  266.    if ((strstr(smallcrap,"~"))||(strstr(smallcrap,":"))||(strstr(smallcrap,"99")))
  267.     continue; /* control characters, other stuff I'm not interested in nixed.*/
  268.    junk=atoi(smallcrap); /* make it an integer! */
  269.    if (junk!=99) /* doublechecking */
  270.     {
  271.     bbslist[maxlist].number=junk;
  272.     maxlist++;   /* saved the bbslist number in our structure */
  273.     }
  274.    }  /* last valid entry is maxlist record */
  275.   fclose(read);
  276.   } else {
  277.   printf("φ Your BBSLIST.0 is gone! Request a new set of network files!\n");
  278.   exit(100);
  279.   }
  280.  date1 = CreateDate(); /* pulled outside loop to minimize allocations */
  281.  date2 = TimeDate();   /* The current time/date info. */
  282.  
  283.  for (listindex=0;listindex<=maxlist;listindex++)
  284.   {
  285.   sprintf(crap,"%s\\BBSLIST.%d",filedir,bbslist[listindex].number);
  286.   read=fsh_open(crap,"rt");
  287.   while ((fgets(crap,254,read)) && (crap!=NULL)) /* while getting valid data from file */
  288.    {
  289.    if (crap[0]!='@') /* not a node for some reason */
  290.     continue;
  291.    sscanf(crap,"%s",smallcrap);
  292.    p=NULL;
  293.    p=smallcrap0;
  294.    for (junk=1;junk<=((strlen(smallcrap))-1)&&smallcrap[junk]!='\0';junk++)
  295.     {
  296.     *p++=smallcrap[junk];
  297.     }
  298.    *p='\0';
  299.    node[nodeindex].number=atoi(smallcrap0);
  300.    sprintf(crap,"%sL%d.FTS",listdir,node[nodeindex].number);
  301.    if (access(crap,0)==YES)
  302.     {
  303.     node[nodeindex].list=YES;
  304.     junk=open(crap,O_RDONLY,O_BINARY);
  305.     if (getftime(junk,&timecrap)!=0)
  306.     close(junk);
  307.  
  308.     if (LoadDate(date1,timecrap.ft_month,timecrap.ft_day,(timecrap.ft_year+1980)) == -1 )
  309.      {
  310. /*SURGE - change this from such an unelegant break! */
  311.      printf("φ DATE ERROR!\n");
  312.      fcloseall();
  313.      exit(100);
  314.      }
  315.     node[nodeindex].age = DateDiff(date1, date2);
  316.     }
  317.    maxnode++;
  318.    nodeindex++;  /* added a new nodenumber! */
  319.    }
  320.   fclose(read);
  321.   }
  322.  FreeDate(&date1); /* moved to outside the loop to try to avoid corruption */
  323.  /*Right here we have read in all the information.  We have a list of
  324.  * nodes, whether they have a nodelist or not, and if so, how old it is.*/
  325.  extra_lists();
  326.  if (missing==YES)
  327.   request_missing();
  328.  if (old==YES)
  329.   request_old();
  330.  printf("■ Removed %d unused file lists!\n■ Requested %d missing lists!\n■ Requested %d old lists!\n",removedlists,missinglists,oldlists);
  331.  exit(0);
  332.  }
  333.  
  334. /************************************************************************
  335. * Share and Multitasking stolen wholesale from the PPP project around
  336. * Beta-85 or so.
  337. ************************************************************************/
  338.  
  339. void dv_pause(void)
  340. {
  341.   __emit__(0xb8, 0x1a, 0x10, 0xcd, 0x15);
  342.   __emit__(0xb8, 0x00, 0x10, 0xcd, 0x15);
  343.   __emit__(0xb8, 0x25, 0x10, 0xcd, 0x15);
  344. }
  345.  
  346. void win_pause(void)
  347. {
  348.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  349. }
  350.  
  351. int get_dos_version(void)
  352. {
  353.   _AX = 0x3000;
  354.   geninterrupt(0x21);
  355.   if (_AX % 256 >= 10) {
  356.     multitasker |= MT_OS2;
  357.   }
  358.   return (_AX);
  359. }
  360.  
  361. int get_dv_version(void)
  362. {
  363.   int v;
  364.  
  365.   if (multitasker & MT_OS2)
  366.     return 0;
  367.   _AX = 0x2b01;
  368.   _CX = 0x4445;
  369.   _DX = 0x5351;
  370.   geninterrupt(0x21);
  371.   if (_AL == 0xff) {
  372.     return 0;
  373.   } else {
  374.     v = _BX;
  375.     multitasker |= MT_DESQVIEW;
  376.     return v;
  377.   }
  378. }
  379.  
  380. int get_win_version(void)
  381. {
  382.   int v = 0;
  383.  
  384.   __emit__(0x55, 0x06, 0x53);
  385.   _AX = 0x352f;
  386.   geninterrupt(0x21);
  387.   _AX = _ES;
  388.   if (_AX | _BX) {
  389.     _AX = 0x1600;
  390.     geninterrupt(0x2f);
  391.     v = _AX;
  392.     if (v % 256 <= 1)
  393.       v = 0;
  394.   }
  395.   __emit__(0x5b, 0x07, 0x5d);
  396.   if (v != 0)
  397.     multitasker |= MT_WINDOWS;
  398.   return (v);
  399. }
  400.  
  401. int get_nb_version(void)
  402. {
  403.   _AX = 0;
  404.   geninterrupt(0x2A);
  405.   return (_AH);
  406. }
  407.  
  408. void detect_multitask(void)
  409. {
  410.   get_dos_version();
  411.   get_win_version();
  412.   get_dv_version();
  413.   if (multitasker < 2)
  414.     if (get_nb_version())
  415.       multitasker = MT_NB;
  416. }
  417.  
  418. void giveup_timeslice(void)
  419. {
  420.   if (multitasker) {
  421.     switch (multitasker) {
  422.  case 1:
  423.  case 3:
  424.     dv_pause();
  425.     break;
  426.       case 2:
  427.       case 4:
  428.       case 5:
  429.       case 6:
  430.       case 7:
  431.     win_pause();
  432.         break;
  433.       default:
  434.         break;
  435.     }
  436.   }
  437. }
  438.  
  439. long sh_lseek(int handle, long offset, int fromwhere)
  440. {
  441.   if (handle == -1) {
  442.     return (-1L);
  443.   }
  444.   return (lseek(handle, offset, fromwhere));
  445. }
  446.  
  447. FILE *fsh_open(char *path, char *fmode)
  448. {
  449.   FILE *f;
  450.   int count, share, md, fd;
  451.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  452.  
  453.   share = SH_DENYWR;
  454.   md = 0;
  455.   if (((char *) strchr(fmode, 'w')) != NULL) {
  456.     share = SH_DENYRD;
  457.     md = O_RDWR | O_CREAT | O_TRUNC;
  458.   } else
  459.     if (((char *) strchr(fmode, 'a')) != NULL) {
  460.     share = SH_DENYRD;
  461.     md = O_RDWR | O_CREAT;
  462.   } else {
  463.     md = O_RDONLY;
  464.   }
  465.   if (((char *) strchr(fmode, 'b')) != NULL) {
  466.     md |= O_BINARY;
  467.   }
  468.   if (((char *) strchr(fmode, '+')) != NULL) {
  469.     md &= ~O_RDONLY;
  470.     md |= O_RDWR;
  471.     share = SH_DENYRD;
  472.   }
  473.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  474.   if (fd < 0) {
  475.     count = 1;
  476.     fnsplit(path, drive, dir, file, ext);
  477.     if ((access(path, 0)) != -1) {
  478.       delay(WAIT_TIME);
  479.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  480.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  481.     if (count % 2)
  482.       delay(WAIT_TIME);
  483.     else
  484.       giveup_timeslice();
  485.     count++;
  486.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  487.       }
  488.     }
  489.   }
  490.   if (fd > 0) {
  491.     if (((char *) strchr(fmode, 'a')) != NULL)
  492.       sh_lseek(fd, 0L, SEEK_END);
  493.     f = fdopen(fd, fmode);
  494.     if (!f) {
  495.       close(fd);
  496.     }
  497.   } else
  498.     f = 0;
  499.   return (f);
  500. }
  501.