home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / ovrmisc.c < prev    next >
Text File  |  1998-08-01  |  37KB  |  1,390 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <stdlib.h>
  22. #include <dos.h>
  23. #include <string.h>
  24. #include <dir.h>
  25. #include <time.h>
  26. #include <io.h>
  27. #include <fcntl.h>
  28. #include <share.h>
  29. #include <alloc.h>
  30. #include <errno.h>
  31. #include <sys\stat.h>
  32.  
  33. #include <cxl\cxlstr.h>
  34. #include <cxl\cxlwin.h>
  35. #include <cxl\cxlvid.h>
  36.  
  37. #include "sched.h"
  38. #include "lsetup.h"
  39. #include "msgapi.h"
  40. #include "externs.h"
  41. #include "prototyp.h"
  42.  
  43. #define DOWN_FILES  0x0020
  44. #define NO_MESSAGE  0x0040
  45.  
  46. extern int blanked;
  47. extern word serial_no;
  48. extern char *config_file, *VNUM;
  49. extern long elapsed;
  50.  
  51. void mprintf (FILE *fp, char *format, ...);
  52.  
  53. static int lora_get_bbs_record (int, int, int, int);
  54. static int update_nodelist (char *, char *);
  55. static int add_local_info (int, int, int, int);
  56.  
  57. void check_duplicate_key (word keyno)
  58. {
  59. //   int fd;
  60.  
  61.    activation_key ();
  62.    if (registered && serial_no == keyno) {
  63.       status_line ("!Duplicate key detected");
  64.       modem_hangup ();
  65.  
  66. /*
  67.       memset (config, 0, sizeof (struct _configuration));
  68.  
  69.       fd = open (config_file, O_WRONLY|O_BINARY);
  70.       write (fd, config, sizeof (struct _configuration));
  71.       close (fd);
  72.  
  73.       fclose (logf);
  74.  
  75.       logf = fopen ("SECURITY.CHK", "at");
  76.       status_line ("!Security breach");
  77.       fclose (logf);
  78.  
  79.       _dos_setfileattr ("SECURITY.CHK", _A_RDONLY|_A_HIDDEN|_A_SYSTEM);
  80. */
  81.    }
  82. }
  83.  
  84. void replace_tearline (FILE *fpd, char *buff)
  85. {
  86.    char wrp[90], newtear[90];
  87.  
  88.    if (registered && config->tearline[0]) {
  89.       strcpy (newtear, config->tearline);
  90.       sprintf (wrp, "%s%s", VNUM, registered ? "+" : NOREG);
  91.       strsrep (newtear, "%1", wrp);
  92.    }
  93.    else
  94.       sprintf (newtear, "%s%s", VERSION, registered ? "+" : NOREG);
  95.  
  96.    if (!registered) {
  97.       mprintf (fpd, msgtxt[M_TEAR_LINE], newtear, "");
  98.       return;
  99.    }
  100.  
  101.    if (strstr (buff, "Lora") != NULL) {
  102.       mprintf (fpd, "%s\r\n", buff);
  103.       return;
  104.    }
  105.  
  106.    if (config->replace_tear == 1 || config->replace_tear == 2) {
  107.       strcpy (wrp, newtear);
  108.  
  109.       if (config->replace_tear == 2) {
  110.          if (strlen (buff) + strlen (wrp) <= 35)
  111.             strcat (buff, wrp);
  112.       }
  113.       else
  114.          strcat (buff, wrp);
  115.  
  116.       mprintf (fpd, "%s\r\n", buff);
  117.    }
  118.    else if (config->replace_tear == 3)
  119.       mprintf (fpd, msgtxt[M_TEAR_LINE], newtear, "");
  120. }
  121.  
  122. void put_tearline (FILE *fpd)
  123. {
  124.    char wrp[30], newtear[60];
  125.  
  126.    if (registered) {
  127.       strcpy (newtear, config->tearline);
  128.       sprintf (wrp, "%s%s", VNUM, registered ? "+" : NOREG);
  129.       strsrep (newtear, "%1", wrp);
  130.    }
  131.    else
  132.       sprintf (newtear, "%s%s", VERSION, registered ? "+" : NOREG);
  133.  
  134.    fprintf (fpd, msgtxt[M_TEAR_LINE], newtear, "");
  135. }
  136.  
  137. void throughput (opt, bytes)
  138. int opt;
  139. unsigned long bytes;
  140.  
  141. {
  142.    static long started = 0L;
  143.    static long elapsed;
  144.  
  145.    if (!opt)
  146.       started = time (NULL);
  147.    else if (started)
  148.       {
  149.       elapsed = time (NULL);
  150.       /* The next line tests for day wrap without the date rolling over */
  151.       if (elapsed < started)
  152.          elapsed += 86400L;
  153.       elapsed -= started;
  154.       if (elapsed == 0L)
  155.          elapsed = 1L;
  156.       cps = (long) (bytes / (unsigned long) elapsed);
  157.       started = (cps * 1000L) / ((long) rate);
  158.       status_line ((char *) msgtxt[M_CPS_MESSAGE], cps, bytes, started);
  159.       }
  160. }                                                /* throughput */
  161.  
  162. long zfree (drive)
  163. char *drive;
  164. {
  165.    struct diskfree_t df;
  166.    unsigned char driveno;
  167.  
  168.    if (drive[0] != '\0' && drive[1] == ':')
  169.       {
  170.       driveno = (unsigned char) (islower (*drive) ? toupper (*drive) : *drive);
  171.       driveno = (unsigned char) (driveno - 'A' + 1);
  172.       }
  173.    else driveno = 0;                             /* Default drive    */
  174.  
  175.    if (!_dos_getdiskfree (driveno, &df))
  176.       return (df.avail_clusters * df.bytes_per_sector * df.sectors_per_cluster);
  177.    else
  178.       return (0);
  179. }
  180.  
  181. void send_can ()
  182. {
  183.    int i;
  184.  
  185.    CLEAR_INBOUND();
  186.    CLEAR_OUTBOUND();
  187.  
  188.    for (i = 0; i < 10; i++)
  189.       SENDBYTE (0x18);
  190.    for (i = 0; i < 10; i++)
  191.       SENDBYTE (0x08);
  192. }
  193.  
  194. void remove_abort (fname, rname)
  195. char *fname, *rname;
  196. {
  197.         FILE *abortlog, *newlog;
  198.         char namebuf[100];
  199.         char linebuf[100];
  200.         char *p;
  201.         int c;
  202.  
  203.         if (!dexists (fname))
  204.                 return;
  205.  
  206.    if ((abortlog = fopen (fname, "ra")) != NULL)
  207.       {
  208.       strcpy (namebuf, fname);
  209.       strcpy (namebuf + strlen (namebuf) - 1, "TMP");
  210.       c = 0;
  211.       if ((newlog = fopen (namebuf, "wa")) == NULL)
  212.          {
  213.          fclose (abortlog);
  214.          }
  215.       else
  216.          {
  217.          while (!feof (abortlog))
  218.             {
  219.             linebuf[0] = '\0';
  220.             if (!fgets (linebuf, 64, abortlog))
  221.                break;
  222.             p = linebuf;
  223.             while (*p > ' ')
  224.                ++p;
  225.             *p = '\0';
  226.             if (stricmp (linebuf, rname))
  227.                {
  228.                *p = ' ';
  229.                fputs (linebuf, newlog);
  230.                ++c;
  231.                }
  232.             }
  233.          fclose (abortlog);
  234.          fclose (newlog);
  235.          unlink (fname);
  236.          if (c)
  237.             rename (namebuf, fname);
  238.          else unlink (namebuf);
  239.          }
  240.       }
  241. }
  242.  
  243. void unique_name (fname)
  244. char *fname;
  245. {
  246.    static char suffix[] = ".001";
  247.     char *p,a_reached=0;
  248.     int n;
  249.  
  250.     if (dexists (fname)) {                /* If file already exists...      */
  251.         p = fname;
  252.         while (*p && *p != '.')
  253.             p++;                            /* ...find the extension, if any  */
  254.  
  255.         for (n = 0; n < 4; n++) {          /* ...fill it out if neccessary   */
  256.             if (!*p) {
  257.                 *p = suffix[n];
  258.                 *(++p) = '\0';
  259.             }
  260.             else
  261.                 p++;
  262.         }
  263.  
  264.         while (dexists (fname)) {          /* ...If 'file.ext' exists suffix++ */
  265.             p = fname + strlen (fname) - 1;
  266.             for (n = 3; n--;) {
  267.                 if (!isdigit (*p)&&!a_reached)
  268.                     *p = '0';
  269.                 if (++(*p) <= '9')
  270.                     break;
  271.                 else {
  272.                     if (*p < 'A') {
  273.                         *p = 'A';
  274.                         a_reached=1;
  275.                         break;
  276.                     }
  277.                     else if (*p <= 'Z')
  278.                         break;
  279.                     else {
  280.                         *p-- = '0';
  281.                         a_reached=0;
  282.                     }
  283.                 }                                    /* for */
  284.             }                                       /* while */
  285.         }                                          /* if exist */
  286.     }
  287. }                                                /* unique_name */
  288.  
  289. int check_failed (fname, theirname, info, ourname)
  290. char *fname, *theirname, *info, *ourname;
  291. {
  292.    FILE *abortlog;
  293.    char linebuf[64];
  294.         char *p, *badname;
  295.         int ret;
  296.  
  297.         ret = 0;
  298.    if ((abortlog = fopen (fname, "ra")) != NULL)
  299.       {
  300.       while (!feof (abortlog))
  301.          {
  302.          linebuf[0] = '\0';
  303.          if (!fgets ((p = linebuf), 64, abortlog))
  304.             break;
  305.          while (*p >= ' ')
  306.             ++p;
  307.          *p = '\0';
  308.          p = strchr (linebuf, ' ');
  309.          *p = '\0';
  310.          if (!stricmp (linebuf, theirname))
  311.             {
  312.             p = strchr ((badname = ++p), ' ');
  313.             *p = '\0';
  314.             if (!stricmp (++p, info))
  315.                {
  316.                strcpy (ourname, badname);
  317.                                         ret = 1;
  318.                break;
  319.                }
  320.             }
  321.          }
  322.       fclose (abortlog);
  323.       }
  324.  
  325.         return (ret);
  326. }
  327.  
  328. void add_abort (fname, rname, cname, cpath, info)
  329. char *fname, *rname, *cname, *cpath, *info;
  330. {
  331.         FILE *abortlog;
  332.         char namebuf[100];
  333.  
  334.    strcpy (namebuf, cpath);
  335.    strcat (namebuf, "BadWaZOO.001");
  336.    unique_name (namebuf);
  337.    rename (cname, namebuf);
  338.    if ((abortlog = fopen (fname, "at")) == NULL)
  339.       {
  340.       unlink (namebuf);
  341.       }
  342.    else
  343.       {
  344.       fprintf (abortlog, "%s %s %s\n", rname, namebuf + strlen (cpath), info);
  345.       fclose (abortlog);
  346.       }
  347. }
  348.  
  349. int get_bbs_record (int zone, int net, int node, int point)
  350. {
  351.    int i;
  352.  
  353.    memset (&nodelist, 0, sizeof (struct _node));
  354.  
  355.    i = lora_get_bbs_record (zone, net, node, point);
  356.    i += add_local_info (zone, net, node, point);
  357.  
  358.    return (i);
  359. }
  360.  
  361. int get_bbs_local_record (int zone, int net, int node, int point)
  362. {
  363.    int i;
  364.  
  365.    memset (&nodelist, 0, sizeof (struct _node));
  366.  
  367.    i = add_local_info (zone, net, node, point);
  368.  
  369.    return (i);
  370. }
  371.  
  372. struct _idx_header {
  373.    char name[14];
  374.    long entry;
  375. };
  376.  
  377. struct _idx_entry {
  378.    short zone;
  379.    short net;
  380.    short node;
  381.    long  offset;
  382. };
  383.  
  384. void nlcomp_system ()
  385. {
  386.    wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  387.  
  388.    prints (7, 54, LCYAN|_BLACK, " Nodelist:");
  389.    prints (8, 54, LCYAN|_BLACK, "NET addr.:");
  390.    prints (9, 54, LCYAN|_BLACK, "    Total:");
  391. }
  392.  
  393. void diffupdate_system (void)
  394. {
  395.    wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  396.  
  397.    prints (7, 54, LCYAN|_BLACK, " Nodelist:");
  398.    prints (8, 54, LCYAN|_BLACK, " Nodediff:");
  399.    prints (9, 54, LCYAN|_BLACK, "     Done:");
  400. }
  401.  
  402. int get_last_nodelist (char *name)
  403. {
  404.    int i, max = -1;
  405.    char filename[128], *p;
  406.    struct ffblk blk;
  407.  
  408.    sprintf (filename, "%s%s.*", config->net_info, name);
  409.    if (findfirst (filename, &blk, 0))
  410.       return (-1);
  411.  
  412.    do {
  413.       if ((p = strchr (blk.ff_name, '.')) == NULL)
  414.          continue;
  415.       p++;
  416.       i = atoi (p);
  417.       if (i > max)
  418.          max = i;
  419.    } while (!findnext (&blk));
  420.  
  421.    return (max);
  422. }
  423.  
  424. void build_nodelist_index (force)
  425. int force;
  426. {
  427.    FILE *fps, *fpd;
  428.    short nzone, nnet, nnode, i, records, cf, m;
  429.    char filename[80], linea[512], build, *p, final[14];
  430.    long hdrpos, entrypos, totalnodes, totaltime;
  431.    struct stat statbuf, statidx;
  432.    struct _idx_header header;
  433.    struct _idx_entry entry;
  434.  
  435.    cf = 0;
  436.    totalnodes = 0L;
  437.    build = 0;
  438.    records = 0;
  439.    nzone = config->alias[0].zone;
  440.    nnet = config->alias[0].net;
  441.  
  442.    // Verifica che il file node.idx sia accessibile in lettura/scrittura
  443.    // nel caso non lo sia, signfica che un altro task lo sta usando per
  444.     // ricompilare la nodelist, per cui esce immediatamente.
  445.    sprintf (filename, "%sNODE.IDX", config->net_info);
  446.    if ((i = sopen (filename, O_RDWR|O_BINARY|O_CREAT, SH_DENYRW, S_IREAD|S_IWRITE)) == -1 && errno == EACCES)
  447.       return;
  448.    close (i);
  449.  
  450.    if (stat (filename, &statidx) == -1)
  451.       build = 1;
  452.  
  453.    for (cf = 0; cf < 10; cf++) {
  454.       sprintf (filename, "%s%s", config->net_info, config->nl[cf].list_name);
  455.       if (!stat (filename, &statbuf)) {
  456.          if (statbuf.st_mtime > statidx.st_mtime)
  457.             build = 1;
  458.       }
  459.    }
  460.  
  461.    memset ((char *)&nodelist, 0, sizeof (struct _node));
  462.  
  463.    sprintf (filename, "%sNODE.IDX", config->net_info);
  464.    if ((fps = sh_fopen (filename, "rb", SH_DENYWR)) != NULL) {
  465.       while (fread ((char *)&header, sizeof (struct _idx_header), 1, fps) == 1) {
  466.          sprintf (filename, "%s%s", config->net_info, header.name);
  467.          if (!stat (filename, &statbuf)) {
  468.             if (statbuf.st_mtime > statidx.st_mtime) {
  469.                build = 1;
  470.                break;
  471.             }
  472.          }
  473.          else {
  474.             build = 1;
  475.             break;
  476.          }
  477.  
  478.          fseek (fps, header.entry * sizeof (struct _idx_entry), SEEK_CUR);
  479.       }
  480.  
  481.       fclose (fps);
  482.    }
  483.    else
  484.       build = 1;
  485.  
  486.    if (build || force) {
  487.       status_line(":Rebuild nodelist index");
  488.       nlcomp_system ();
  489.       local_status ("NL Comp.");
  490.  
  491.       totaltime = timerset (0);
  492.  
  493.       sprintf (filename, "%sNODE.IDX", config->net_info);
  494.       fpd = sh_fopen (filename, "w+b", SH_DENYRW);
  495.  
  496.       for (cf = 0; cf < 10; cf++) {
  497.          if (config->nl[cf].list_name[0] == '\0')
  498.             continue;
  499.  
  500.          time_release ();
  501.  
  502.          if (strchr (config->nl[cf].list_name, '.') == NULL && config->nl[cf].diff_name[0]) {
  503.             i = update_nodelist (config->nl[cf].list_name, config->nl[cf].diff_name);
  504.             for (;;) {
  505.                m = update_nodelist (config->nl[cf].list_name, config->nl[cf].diff_name);
  506.                if (m == i)
  507.                   break;
  508.                i = m;
  509.             }
  510.             if (i == -1)
  511.                continue;
  512.             sprintf (final, "%s.%03d", config->nl[cf].list_name, i);
  513.          }
  514.          else if (strchr (config->nl[cf].list_name, '.') == NULL) {
  515.             i = get_last_nodelist (config->nl[cf].list_name);
  516.             if (i == -1)
  517.                continue;
  518.             sprintf (final, "%s.%03d", config->nl[cf].list_name, i);
  519.          }
  520.          else
  521.             strcpy (final, config->nl[cf].list_name);
  522.          sprintf (filename, "%s%s", config->net_info, final);
  523.          fps = fopen (filename, "rb");
  524.          if (fps == NULL)
  525.             continue;
  526.  
  527.          status_line ("+Compiling %s", fancy_str (filename));
  528.          prints (7, 65, YELLOW|_BLACK, "            ");
  529.          prints (7, 65, YELLOW|_BLACK, strupr (final));
  530.  
  531.          hdrpos = ftell  (fpd);
  532.          memset ((char *)&header, 0, sizeof (struct _idx_header));
  533.          strcpy (header.name, strupr(final));
  534.          fwrite ((char *)&header, sizeof (struct _idx_header), 1, fpd);
  535.  
  536.          entrypos = ftell (fps);
  537.          nzone = config->alias[0].zone;
  538.          nnet = config->alias[0].net;
  539.  
  540.          while (fgets(linea, 511, fps) != NULL) {
  541.             if (linea[0] == ';') {
  542.                entrypos = ftell (fps);
  543.                continue;
  544.             }
  545.  
  546.             if (strnicmp (linea, "Down,", 5))
  547.                totalnodes++;
  548.  
  549.             if ( totalnodes && !(totalnodes % 32) ) {
  550.                time_release ();
  551.  
  552.                if (timerset (0) > totaltime) {
  553.                   sprintf (filename, "%ld (%.0f/s) ", totalnodes, (float)totalnodes / ((float)(timerset (0) - totaltime) / 100));
  554.                   filename[14] = '\0';
  555.                   prints (9, 65, YELLOW|_BLACK, filename);
  556.                }
  557.  
  558.                prints (8, 65, YELLOW|_BLACK, "              ");
  559.                sprintf (filename, "%d:%d", nzone, nnet);
  560.                prints (8, 65, YELLOW|_BLACK, filename);
  561.             }
  562.  
  563.             p = strtok (linea, ",");
  564.             if (stricmp (p, "Boss") && stricmp (p, "Zone") && stricmp (p, "Region") && stricmp (p, "Host")) {
  565.                entrypos = ftell (fps);
  566.                continue;
  567.             }
  568.  
  569.             nnode = 0;
  570.             if (!stricmp (p, "Boss")) {
  571.                p = strtok (NULL, ",");
  572.                parse_netnode (p, (int *)&nzone, (int *)&nnet, (int *)&nnode, (int *)&i);
  573.             }
  574.             else if (!stricmp (p, "Zone")) {
  575.                p = strtok (NULL, ",");
  576.                nzone = nnet = atoi (p);
  577.             }
  578.             else {
  579.                p = strtok (NULL, ",");
  580.                nnet = atoi (p);
  581.             }
  582.  
  583.             entry.zone = nzone;
  584.             entry.net = nnet;
  585.             entry.node = nnode;
  586.             entry.offset = entrypos;
  587.             fwrite ((char *)&entry, sizeof (struct _idx_entry), 1, fpd);
  588.             header.entry++;
  589.             records++;
  590.             entrypos = ftell (fps);
  591.          }
  592.  
  593.          fclose (fps);
  594.  
  595.          fseek (fpd, hdrpos, SEEK_SET);
  596.          fwrite ((char *)&header, sizeof (struct _idx_header), 1, fpd);
  597.          fseek (fpd, 0L, SEEK_END);
  598.       }
  599.  
  600.       fclose (fpd);
  601.  
  602.       status_line ("+%ld total nodes, %d records written", totalnodes, records);
  603.  
  604.       idle_system ();
  605.       mtask_find();
  606.    }
  607. }
  608.  
  609. static int lora_get_bbs_record(zone, net, node, point)
  610. int zone, net, node, point;
  611. {
  612.    FILE *fp, *fpn;
  613.    short i, checkp, zo, ne, no;
  614.    char filename[80], linea[512], *p, first;
  615.    long num;
  616.    struct _idx_header header;
  617.    struct _idx_entry entry;
  618.  
  619.    if (point)
  620.       point = 0;
  621.  
  622.    memset ((char *)&nodelist, 0, sizeof (struct _node));
  623.  
  624.    sprintf (filename, "%sNODE.IDX", config->net_info);
  625.    if ((fp = sh_fopen (filename, "rb", SH_DENYWR)) == NULL)
  626.       return (0);
  627.  
  628.    while (fread ((char *)&header, sizeof (struct _idx_header), 1, fp) == 1) {
  629.       for (num = 0L; num < header.entry; num++) {
  630.          if (fread ((char *)&entry, sizeof (struct _idx_entry), 1, fp) != 1)
  631.             break;
  632.          if ((zone && entry.zone == zone) && entry.net == net) {
  633.             if (entry.node && entry.node != node)
  634.                continue;
  635.             if (strchr (header.name, '.') == NULL) {
  636.                i = update_nodelist (header.name, NULL);
  637.                if (i == -1)
  638.                   return (0);
  639.                sprintf (filename, "%s%s.%03d", config->net_info, header.name, i);
  640.             }
  641.             else
  642.                sprintf (filename, "%s%s", config->net_info, header.name);
  643.  
  644.             fpn = sh_fopen (filename, "rb", SH_DENYWR);
  645.             if (fpn == NULL) {
  646.                fclose (fp);
  647.                return (0);
  648.             }
  649.  
  650.             fseek (fpn, entry.offset, SEEK_SET);
  651.  
  652.             first = 0;
  653.             checkp = 0;
  654.  
  655.             while (fgets(linea, 511, fpn) != NULL) {
  656.                if (linea[0] == ';')
  657.                   continue;
  658.  
  659.                if (linea[0] != ',') {
  660.                   p = strtok (linea, ",");
  661.                   if (!stricmp (p, "Zone") || !stricmp (p, "Region") || !stricmp (p, "Host")) {
  662.                      if (first)
  663.                         break;
  664.                      else
  665.                         first = 1;
  666.                      p = strtok (NULL, ",");
  667.                      *p = '\0';
  668.                   }
  669.                   else if (!stricmp (p, "Boss")) {
  670.                      if (first)
  671.                         break;
  672.                      p = strtok (NULL, ",");
  673.                      parse_netnode (p, (int *)&zo, (int *)&ne, (int *)&no, (int *)&i);
  674.                      if (zo == zone && ne == net && no == node && point) {
  675.                         first = 1;
  676.                         checkp = 1;
  677.                      }
  678.                   }
  679.                   else
  680.                      p = strtok (NULL, ",");
  681.                }
  682.                else
  683.                   p = strtok (linea, ",");
  684.  
  685.                if (p == NULL)
  686.                   continue;
  687.                if (checkp) {
  688.                   if (atoi (p) != point)
  689.                      continue;
  690.                }
  691.                else {
  692.                   if (atoi (p) != node || point)
  693.                      continue;
  694.                }
  695.  
  696.                p = strtok (NULL, ",");
  697.                if (strlen (p) > 33)
  698.                   p[33] = '\0';
  699.                strcpy (nodelist.name, p);
  700.                strischg (nodelist.name, "_", " ");
  701.  
  702.                p = strtok (NULL, ",");
  703.                if (strlen (p) > 29)
  704.                   p[29] = '\0';
  705.                strcpy (nodelist.city, p);
  706.                strischg (nodelist.city, "_", " ");
  707.  
  708.                p = strtok (NULL, ",");
  709.                if (strlen (p) > 35)
  710.                   p[35] = '\0';
  711.                strcpy (nodelist.sysop, p);
  712.                strischg (nodelist.sysop, "_", " ");
  713.  
  714.                p = strtok (NULL, ",");
  715.                if (strlen (p) > 39)
  716.                   p[39] = '\0';
  717.                strcpy (nodelist.phone, p);
  718.  
  719.                p = strtok (NULL, ",");
  720.                nodelist.rate = atoi (p) / 300;
  721.  
  722.                if ((p = strtok (NULL, "")) != NULL)
  723.                   for (i = 0; i < 10; i++) {
  724.                      if (!config->prefixdial[i].flag[0])
  725.                         continue;
  726.                      if (stristr (p, config->prefixdial[i].flag) != NULL) {
  727.                         nodelist.modem = i + 20;
  728.                         break;
  729.                      }
  730.                   }
  731.  
  732.                fclose (fp);
  733.                fclose (fpn);
  734.  
  735.                return (1);
  736.             }
  737.  
  738.             fclose (fpn);
  739.          }
  740.       }
  741.    }
  742.  
  743.    fclose (fp);
  744.  
  745.    return (0);
  746. }
  747.  
  748. static int add_local_info (zone, net, node, point)
  749. int zone, net, node, point;
  750. {
  751.    int fd, r, rep, ora, i, c1, c2, c3, c4, wd;
  752.    char filename[80], deftrasl[60];
  753.    long tempo;
  754.    struct tm *tim;
  755.    NODEINFO ni;
  756.    ACCOUNT ai;
  757.  
  758.    sprintf (filename, "%sNODES.DAT", config->net_info);
  759.    if ((fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE)) == -1)
  760.       return (0);
  761.  
  762.    c1 = c2 = c3 = c4 = 0;
  763.    r = 0;
  764.    rep = 0;
  765.    deftrasl[0] = '\0';
  766.  
  767.    while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  768.       if (zone == ni.zone && net == ni.net && node == ni.node && point == ni.point) {
  769.          strcpy (nodelist.password, strupr(ni.pw_session));
  770.          nodelist.modem = ni.modem_type;
  771.          strcpy (nodelist.pw_areafix, ni.pw_areafix);
  772.          strcpy (nodelist.pw_tic, ni.pw_tic);
  773.          strcpy (nodelist.sysop, ni.sysop_name);
  774.          if (ni.system[0])
  775.             strcpy (nodelist.name, ni.system);
  776.          if (ni.phone[0])
  777.             strcpy (nodelist.phone, ni.phone);
  778.             nodelist.akainfo = ni.aka;
  779.             nodelist.tic_akainfo = ni.tic_aka;
  780.          r = 1;
  781.          break;
  782.       }
  783.  
  784.    close (fd);
  785.  
  786.    sprintf (filename, "%sCOST.DAT", config->net_info);
  787.    fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  788.  
  789.    while (read (fd, (char *)&ai, sizeof (ACCOUNT)) == sizeof (ACCOUNT)) {
  790.       if (!strncmp (nodelist.phone, ai.search, strlen (ai.search))) {
  791.          strisrep (nodelist.phone, ai.search, ai.traslate);
  792.  
  793.          tempo = time (NULL);
  794.          tim = localtime (&tempo);
  795.          ora = tim->tm_hour * 60 + tim->tm_sec;
  796.          wd = 1 << tim->tm_wday;
  797.          for (i = 0; i < MAXCOST; i++)
  798.             if ((ai.cost[i].days & wd)) {
  799.                if (ai.cost[i].start < ai.cost[i].stop) {
  800.                   if (ora >= ai.cost[i].start && ora <= ai.cost[i].stop) {
  801.                      nodelist.cost = ai.cost[i].cost;
  802.                      nodelist.time = ai.cost[i].time;
  803.                      nodelist.cost_first = ai.cost[i].cost_first;
  804.                      nodelist.time_first = ai.cost[i].time_first;
  805.                      break;
  806.                   }
  807.                }
  808.                else {
  809.                   if (ora >= ai.cost[i].start && ora <= 1439) {
  810.                      nodelist.cost = ai.cost[i].cost;
  811.                      nodelist.time = ai.cost[i].time;
  812.                      nodelist.cost_first = ai.cost[i].cost_first;
  813.                      nodelist.time_first = ai.cost[i].time_first;
  814.                      break;
  815.                   }
  816.                   if (ora >= 0 && ora <= ai.cost[i].stop) {
  817.                      nodelist.cost = ai.cost[i].cost;
  818.                      nodelist.time = ai.cost[i].time;
  819.                      nodelist.cost_first = ai.cost[i].cost_first;
  820.                      nodelist.time_first = ai.cost[i].time_first;
  821.                      break;
  822.                   }
  823.                }
  824.             }
  825.  
  826.          rep = 1;
  827.          break;
  828.       }
  829.       else if (!strcmp (ai.search, "/")) {
  830.          strcpy (deftrasl, ai.traslate);
  831.          c1 = ai.cost[i].cost;
  832.          c2 = ai.cost[i].time;
  833.          c3 = ai.cost[i].cost_first;
  834.          c4 = ai.cost[i].time_first;
  835.       }
  836.    }
  837.  
  838.    if (!rep && deftrasl[0]) {
  839.       strcpy (filename, deftrasl);
  840.       strcat (filename, nodelist.phone);
  841.       strcpy (nodelist.phone, filename);
  842.       nodelist.cost = c1;
  843.       nodelist.time = c2;
  844.       nodelist.cost_first = c3;
  845.       nodelist.time_first = c4;
  846.    }
  847.  
  848.    close (fd);
  849.  
  850.    return (r);
  851. }
  852.  
  853. void set_protocol_flags (int zone, int net, int node, int point)
  854. {
  855.    int fd;
  856.    char filename[80];
  857.    NODEINFO ni;
  858.  
  859.    sprintf (filename, "%sNODES.DAT", config->net_info);
  860.    fd = open (filename, O_RDONLY|O_BINARY);
  861.  
  862.    while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  863.       if (zone == ni.zone && net == ni.net && node == ni.node && point == ni.point) {
  864.          if (config->janus)
  865.             config->janus = ni.janus;
  866.          if (config->emsi)
  867.             config->emsi = ni.emsi;
  868.          if (config->wazoo)
  869.             config->wazoo = ni.wazoo;
  870.          break;
  871.       }
  872.  
  873.    close (fd);
  874. }
  875.  
  876. long get_phone_cost (zo, ne, no, online)
  877. int zo, ne, no;
  878. long online;
  879. {
  880.    long cost;
  881.  
  882.    if (!get_bbs_record (zo, ne, no, 0))
  883.       return (0);
  884.  
  885.    online *= 10L;
  886.  
  887.    if (nodelist.time_first) {
  888.       if (online > (long)nodelist.time_first) {
  889.          cost = (long)nodelist.cost_first;
  890.          online -= (long)nodelist.time_first;
  891.       }
  892.       else
  893.          cost = 0L;
  894.    }
  895.    else
  896.       cost = 0L;
  897.  
  898.    if (online <= 0L)
  899.       return (cost);
  900.  
  901.    if (nodelist.time) {
  902.       cost += (online / (long)nodelist.time) * (long)nodelist.cost;
  903.       if ((online % (long)nodelist.time) != 0)
  904.          cost += (long)nodelist.cost;
  905.    }
  906.  
  907.    return (cost);
  908. }
  909.  
  910. void add_packet_pw (pkthdr)
  911. struct _pkthdr2 *pkthdr;
  912. {
  913.    int fd;
  914.    char filename[80];
  915.    NODEINFO ni;
  916.  
  917.    sprintf (filename, "%sNODES.DAT", config->net_info);
  918.    fd = open (filename, O_RDONLY|O_BINARY);
  919.  
  920.    while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  921.       if (pkthdr->dest_zone == ni.zone && pkthdr->dest_net == ni.net && pkthdr->dest_node == ni.node && pkthdr->dest_point == ni.point) {
  922.             strncpy (pkthdr->password, strupr(ni.pw_packet),8);
  923.          break;
  924.       }
  925.  
  926.    close (fd);
  927. }
  928.  
  929.  
  930. #define isLeap(x) ((x)%1000)?((((x)%100)?(((x)%4)?0:1):(((x)%400)?0:1))):(((x)%4000)?1:0)
  931.  
  932. int update_nodelist (name, diff)
  933. char *name, *diff;
  934. {
  935.    FILE *fps, *fpd, *fpn;
  936.    int i, max = -1, next, m;
  937.    char filename[128], linea[512], *p;
  938.    struct ffblk blk;
  939.    long tempo;
  940.    float t;
  941.    struct tm *tim;
  942.  
  943.    tempo = time (NULL);
  944.    tim = localtime(&tempo);
  945.  
  946.    sprintf (filename, "%s%s.*", config->net_info, name);
  947.    if (findfirst (filename, &blk, 0))
  948.       return (-1);
  949.  
  950.    do {
  951.       if ((p = strchr (blk.ff_name, '.')) == NULL)
  952.          continue;
  953.       p++;
  954.       i = atoi (p);
  955.       if (i > max)
  956.      max = i;
  957.    } while (!findnext (&blk));
  958.  
  959.    next = max + 7;
  960.    if ((isLeap (tim->tm_year - 1)) && next > 366)
  961.       next -= 366;
  962.    else if (!(isLeap (tim->tm_year - 1)) && next > 365)
  963.       next -= 365;
  964.  
  965.    if (diff == NULL || *diff == '\0')
  966.       return (max);
  967.  
  968.    sprintf (filename, "%s%s.%03d", config->net_info, diff, next);
  969.    if (!dexists (filename))
  970.       return (max);
  971.  
  972.    diffupdate_system ();
  973.  
  974.    sprintf (filename, "%s.%03d", name, max);
  975.    prints (7, 65, YELLOW|_BLACK, filename);
  976.    sprintf (filename, "%s.%03d", diff, next);
  977.    prints (8, 65, YELLOW|_BLACK, filename);
  978.    prints (9, 65, YELLOW|_BLACK, "0%%");
  979.  
  980.    status_line ("+Updating %s.%03d with %s.%03d", name, max, diff, next);
  981.  
  982.    sprintf (filename, "%s%s.%03d", config->net_info, diff, next);
  983.    fps = sh_fopen (filename, "rt", SH_DENYRW);
  984.    setvbuf (fps, NULL, _IOFBF, 2048);
  985.  
  986.    sprintf (filename, "%s%s.%03d", config->net_info, name, max);
  987.    fpn = sh_fopen (filename, "rt", SH_DENYNONE);
  988.    setvbuf (fpn, NULL, _IOFBF, 2048);
  989.  
  990.    sprintf (filename, "%s%s.%03d", config->net_info, name, next);
  991.    fpd = sh_fopen (filename, "wt", SH_DENYRW);
  992.    setvbuf (fpd, NULL, _IOFBF, 2048);
  993.  
  994.    fgets(linea, 511, fps);
  995.    fgets(filename, 127, fpn);
  996.    if (stricmp (linea, filename)) {
  997.       status_line ("!%s.%03d doesn't match %s.%03d", diff, next, name, max);
  998.       fclose (fpd);
  999.       fclose (fpn);
  1000.       fclose (fps);
  1001.  
  1002.       sprintf (filename, "%s%s.%03d", config->net_info, name, next);
  1003.       unlink (filename);
  1004.       sprintf (filename, "%s%s.%03d", config->net_info, diff, next);
  1005.       unlink (filename);
  1006.  
  1007.       nlcomp_system ();
  1008.       return (max);
  1009.    }
  1010.  
  1011.    rewind (fpn);
  1012.  
  1013.    while (fgets(linea, 511, fps) != NULL) {
  1014.       while (linea[strlen (linea) -1] == 0x0D || linea[strlen (linea) -1] == 0x0A || linea[strlen (linea) -1] == ' ')
  1015.          linea[strlen (linea) -1] = '\0';
  1016.  
  1017.       if (linea[0] == 'A' && isdigit(linea[1])) {
  1018.          m = atoi (&linea[1]);
  1019.          for (i = 0; i < m; i++) {
  1020.             fgets(linea, 511, fps);
  1021.             fputs(linea, fpd);
  1022.          }
  1023.       }
  1024.       else if (linea[0] == 'C' && isdigit(linea[1])) {
  1025.          m = atoi (&linea[1]);
  1026.          for (i = 0; i < m; i++) {
  1027.             fgets(linea, 511, fpn);
  1028.             fputs(linea, fpd);
  1029.          }
  1030.       }
  1031.       else if (linea[0] == 'D' && isdigit(linea[1])) {
  1032.          m = atoi (&linea[1]);
  1033.          for (i = 0; i < m; i++)
  1034.             fgets(linea, 511, fpn);
  1035.       }
  1036.  
  1037.       t = (float)ftell (fps) * (float)100 / (float)filelength (fileno (fps));
  1038.       sprintf (linea, "%04.1f%%", t);
  1039.       prints (9, 65, YELLOW|_BLACK, linea);
  1040.       time_release ();
  1041.    }
  1042.  
  1043.    fclose (fpd);
  1044.    fclose (fpn);
  1045.    fclose (fps);
  1046.  
  1047.    sprintf (filename, "%s%s.%03d", config->net_info, name, max);
  1048.    unlink (filename);
  1049.    sprintf (filename, "%s%s.%03d", config->net_info, diff, next);
  1050.    unlink (filename);
  1051.  
  1052.    nlcomp_system ();
  1053.  
  1054.    return (next);
  1055. }
  1056.  
  1057. char *random_origins (void)
  1058. {
  1059.    FILE *fp;
  1060.    struct time dt;
  1061.  
  1062.    if (sys.origin[0] == '@') {
  1063.       gettime (&dt);
  1064.       srand (dt.ti_sec * 100 + dt.ti_hund);
  1065.  
  1066.       fp = fopen (&sys.origin[1], "rt");
  1067.       fseek (fp, (long)random ((int)filelength(fileno (fp))), SEEK_SET);
  1068.       fgets (e_input, 120, fp);
  1069.       if (fgets (e_input, 120, fp) == NULL) {
  1070.          rewind (fp);
  1071.          fgets (e_input, 120, fp);
  1072.       }
  1073.  
  1074.       fclose (fp);
  1075.    }
  1076.    else
  1077.       strcpy (e_input, sys.origin);
  1078.  
  1079.    return (e_input);
  1080. }
  1081.  
  1082. int yesno_question(def)
  1083. int def;
  1084. {
  1085.     char stringa[MAX_CMDLEN], c, bigyes[4], bigno[4], rescode[50];
  1086.  
  1087.    sprintf(bigyes, "%c/%c", toupper(bbstxt[B_YES][0]), tolower(bbstxt[B_NO][0]));
  1088.    sprintf(bigno, "%c/%c", tolower(bbstxt[B_YES][0]), toupper(bbstxt[B_NO][0]));
  1089.  
  1090.    if (!(def & NO_MESSAGE)) {
  1091.         sprintf (rescode, " [%s", (def & DEF_YES) ? bigyes : bigno);
  1092.         strcat (rescode, (def & EQUAL) ? "/=" : "");
  1093.         strcat (rescode, (def & DOWN_FILES) ? "/d" : "");
  1094.         strcat (rescode, (def & TAG_FILES) ? "/t" : "");
  1095.         strcat (rescode, (def & QUESTION) ? "/?" : "");
  1096.         strcat (rescode, "]?  ");
  1097.  
  1098.         m_print (rescode);
  1099.    }
  1100.    else
  1101.       m_print (" ");
  1102.  
  1103.    cmd_string[0] = '\0';
  1104.  
  1105.    do {
  1106.       m_print ("\b \b");
  1107.       if (!cmd_string[0]) {
  1108.          if (usr.hotkey)
  1109.             cmd_input (stringa, 1);
  1110.          else
  1111.             chars_input (stringa, 1, INPUT_NOLF);
  1112.  
  1113.          c = toupper(stringa[0]);
  1114.       }
  1115.       else {
  1116.          c = toupper(cmd_string[0]);
  1117.          strcpy (&cmd_string[0], &cmd_string[1]);
  1118.          strtrim (cmd_string);
  1119.       }
  1120.       if (c == '?' && (def & QUESTION))
  1121.          break;
  1122.       if (c == '=' && (def & EQUAL))
  1123.          break;
  1124.       if (c == 'D' && (def & DOWN_FILES))
  1125.          break;
  1126.       if (c == 'T' && (def & TAG_FILES))
  1127.          break;
  1128.       if (time_remain() <= 0 || !CARRIER)
  1129.          return (DEF_NO);
  1130.    } while (c != bigyes[0] && c != bigno[2] && c != '\0');
  1131.  
  1132.    if (!(def & NO_LF))
  1133.       m_print(bbstxt[B_ONE_CR]);
  1134.  
  1135. //   strcpy (cmd_string, &stringa[1]);
  1136.  
  1137.    if (c == '?' && (def & QUESTION))
  1138.       return (QUESTION);
  1139.  
  1140.    if (c == '=' && (def & EQUAL))
  1141.       return (EQUAL);
  1142.  
  1143.    if (c == 'D' && (def & DOWN_FILES))
  1144.       return (DOWN_FILES);
  1145.  
  1146.    if (c == 'T' && (def & TAG_FILES))
  1147.       return (TAG_FILES);
  1148.  
  1149.    if (def & DEF_YES) {
  1150.       if (c == bigno[2])
  1151.          return (DEF_NO);
  1152.       else
  1153.          return (DEF_YES);
  1154.    }
  1155.    else {
  1156.       if (c == bigyes[0])
  1157.          return (DEF_YES);
  1158.       else
  1159.          return (DEF_NO);
  1160.    }
  1161. }
  1162.  
  1163. void big_pause (secs)
  1164. int secs;
  1165. {
  1166.    long timeout, timerset ();
  1167.  
  1168.    timeout = timerset ((unsigned int) (secs * 100));
  1169.    while (!timeup (timeout)) {
  1170.       if (PEEKBYTE() != -1)
  1171.          break;
  1172.    }
  1173. }
  1174.  
  1175. void press_enter()
  1176. {
  1177.    char stringa[2];
  1178.  
  1179.     m_print("ì%s", bbstxt[B_PRESS_ENTER]);
  1180.    chars_input(stringa,0,INPUT_NOLF);
  1181.  
  1182.    m_print("\r");
  1183.     space (strlen (bbstxt[B_PRESS_ENTER]) + 1);
  1184.    m_print("\r");
  1185.    restore_last_color ();
  1186. }
  1187.  
  1188. int continua()
  1189. {
  1190.    int i;
  1191.  
  1192.    if (nopause)
  1193.       return(1);
  1194.  
  1195.    m_print(bbstxt[B_MORE]);
  1196.    i = yesno_question(DEF_YES|EQUAL|NO_LF);
  1197.  
  1198.    m_print("\r");
  1199.    space (strlen (bbstxt[B_MORE]) + 14);
  1200.    m_print("\r");
  1201.    restore_last_color ();
  1202.  
  1203.    if(i == DEF_NO) {
  1204.            nopause = 0;
  1205.            return(0);
  1206.    }
  1207.  
  1208.    if (i == EQUAL)
  1209.       nopause = 1;
  1210.  
  1211.    return(1);
  1212. }
  1213.  
  1214. int more_question(line)
  1215. int line;
  1216. {
  1217.    if(!(line++ < (usr.len-1)) && usr.more) {
  1218.       line = 1;
  1219.       if(!continua())
  1220.          return(0);
  1221.    }
  1222.  
  1223.    return(line);
  1224. }
  1225.  
  1226.  
  1227. char *data(d)
  1228. char *d;
  1229. {
  1230.    long tempo;
  1231.    struct tm *tim;
  1232.  
  1233.    tempo=time(0);
  1234.    tim=localtime(&tempo);
  1235.  
  1236.    sprintf(d,"%02d %3s %02d  %2d:%02d:%02d",tim->tm_mday,mtext[tim->tm_mon],\
  1237.               tim->tm_year,tim->tm_hour,tim->tm_min,tim->tm_sec);
  1238.    return(d);
  1239. }
  1240.  
  1241. void timer (decs)
  1242. int decs;
  1243. {
  1244.    long timeout;
  1245.  
  1246.    timeout = timerset ((unsigned int) (decs * 10));
  1247.  
  1248.    while (!timeup (timeout)) {
  1249.       time_release();
  1250.       release_timeslice ();
  1251.    }
  1252. }
  1253.  
  1254. void update_filesio (sent, received)
  1255. int sent, received;
  1256. {
  1257.    char string[20];
  1258.  
  1259.    if (caller || emulator)
  1260.       return;
  1261.  
  1262.    prints (8, 65, YELLOW|_BLACK, "              ");
  1263.    sprintf (string, "%d/%d", received, sent);
  1264.    prints (8, 65, YELLOW|_BLACK, string);
  1265.    time_release ();
  1266. }
  1267.  
  1268. int check_new_messages (char *dir)
  1269. {
  1270.    int fd, i, last;
  1271.    char filename[80], *p;
  1272.    struct ffblk blk;
  1273.  
  1274.    last = 0;
  1275.  
  1276.    sprintf (filename, "%s*.MSG", dir);
  1277.  
  1278.    if (!findfirst (filename, &blk, 0))
  1279.       do {
  1280.          if ((p = strchr (blk.ff_name,'.')) != NULL)
  1281.             *p = '\0';
  1282.  
  1283.          i = atoi (blk.ff_name);
  1284.          if (last < i || !last)
  1285.             last = i;
  1286.       } while (!findnext (&blk));
  1287.  
  1288.    i = 0;
  1289.  
  1290.    sprintf (filename, "%sLASTREAD", dir);
  1291.    fd = sh_open (filename, SH_DENYWR, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  1292.    if (fd != -1) {
  1293.       read (fd, (char *)&i, sizeof (short));
  1294.       close (fd);
  1295.    }
  1296.    else
  1297.       i = last;
  1298.  
  1299.    return (i < last);
  1300. }
  1301.  
  1302. void check_new_netmail (void)
  1303. {
  1304.    char filename[80];
  1305.  
  1306.    if (config->newmail_flash) {
  1307.       if (check_new_messages (config->netmail_dir))
  1308.             prints (23, 54, YELLOW|_BLACK, "MAIL");
  1309.         else
  1310.             prints (23, 54, YELLOW|_BLACK, "    ");
  1311.     }
  1312.     else
  1313.         prints (23, 54, YELLOW|_BLACK, "    ");
  1314.  
  1315.     if (config->mymail_flash) {
  1316.         if (check_new_messages (config->my_mail))
  1317.             prints (23, 59, YELLOW|_BLACK, "PERSONAL");
  1318.         else
  1319.             prints (23, 59, YELLOW|_BLACK, "        ");
  1320.     }
  1321.     else
  1322.         prints (23, 59, YELLOW|_BLACK, "        ");
  1323.  
  1324.     sprintf (filename, "%sRCVFAX.FLG", config->sys_path);
  1325.     if (dexists (filename))
  1326.         prints (23, 68, YELLOW|_BLACK, "FAX");
  1327.     else
  1328.         prints (23, 68, YELLOW|_BLACK, "   ");
  1329. }
  1330.  
  1331. int montday[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1332.  
  1333. int daysleft (struct date *d1, struct date *d2)
  1334. {
  1335.     int i, diff = 0, m;
  1336.  
  1337.     if (d1->da_year < 90)
  1338.         d1->da_year += 2000;
  1339.     else
  1340.         d1->da_year += 1900;
  1341.     if (d2->da_year < 90)
  1342.       d2->da_year += 2000;
  1343.    else
  1344.       d2->da_year += 1900;
  1345.  
  1346.    if (d1->da_year > d2->da_year)
  1347.       d2->da_year += 100;
  1348.  
  1349.    if (d1->da_year < d2->da_year) {
  1350.       for (i = d1->da_year + 1; i < d2->da_year; i++) {
  1351.          m = i;
  1352.          diff += (isLeap (m)) ? 366 : 365;
  1353.       }
  1354.  
  1355.       diff += montday[d1->da_mon] - d1->da_day;
  1356.       for (i = d1->da_mon + 1; i <= 12; i++)
  1357.          diff += montday[i];
  1358.       if (d1->da_mon <= 2 && (isLeap (d1->da_year)))
  1359.          diff++;
  1360.       for (i = 1; i < d2->da_mon; i++)
  1361.          diff += montday[i];
  1362.       if (d2->da_mon > 2 && (isLeap (d2->da_year)))
  1363.          diff++;
  1364.       diff += d2->da_day;
  1365.  
  1366.       return (diff);
  1367.    }
  1368.    else if (d1->da_year == d2->da_year) {
  1369.       if (d1->da_mon > d2->da_mon)
  1370.          return (-1);
  1371.  
  1372.       else if (d1->da_mon < d2->da_mon) {
  1373.          diff += montday[d1->da_mon] - d1->da_day;
  1374.          for (i = d1->da_mon + 1; i < d2->da_mon; i++)
  1375.             diff += montday[i];
  1376.          if (d1->da_mon <= 2 && (isLeap (d1->da_year)))
  1377.             diff++;
  1378.          diff += d2->da_day;
  1379.  
  1380.          return (diff);
  1381.       }
  1382.  
  1383.       else
  1384.          return (d2->da_day - d1->da_day);
  1385.    }
  1386.  
  1387.    return (-1);
  1388. }
  1389.  
  1390.