home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / video.c < prev    next >
C/C++ Source or Header  |  1998-08-04  |  21KB  |  753 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 <process.h>
  21. #include <dos.h>
  22. #include <time.h>
  23. #include <string.h>
  24. #include <io.h>
  25. #include <fcntl.h>
  26. #include <conio.h>
  27. #include <stdlib.h>
  28. #include <dir.h>
  29. #include <sys/stat.h>
  30.  
  31. #include <cxl\cxlvid.h>
  32. #include <cxl\cxlwin.h>
  33. #include <cxl\cxlstr.h>
  34.  
  35. #include "lsetup.h"
  36. #include "sched.h"
  37. #include "msgapi.h"
  38. #include "externs.h"
  39. #include "prototyp.h"
  40. #include "exec.h"
  41.  
  42. extern int blanked;
  43.  
  44. int spawn_program (int swapout, char *outstring);
  45. void idle_system (void);
  46. void clown_clear (void);
  47. void stop_blanking (void);
  48. void open_logfile (void);
  49. void no_test_key (void);
  50.  
  51. #define UpdateCRC(c,crc) (cr3tab[((int) crc ^ c) & 0xff] ^ ((crc >> 8) & 0x00FFFFFFL))
  52. static char *reg_prompt = "[UnRegistered]";
  53.  
  54. struct _fossil_info
  55. {
  56.    int size;
  57.    char majver;
  58.    char minver;
  59.    char far *id;
  60.    int input_size;
  61.    int input_free;
  62.    int output_size;
  63.    int output_free;
  64.    char width;
  65.    char height;
  66.    char baud;
  67. };
  68.  
  69. static int fossil_inf(struct _fossil_info far *);
  70. static void virtual_screen (void);
  71. static void system_autoupdate (void);
  72.  
  73. int ox, oy, wh1;
  74. char serial_id[3];
  75. word serial_no;
  76.  
  77. /*---------------------------------------------------------------------------
  78.         void setup_screen (void);
  79.  
  80.         Disegna le due parti piu' importanti dello schermo, dalla riga 1 alla
  81.         riga 23 (dove viene visualizzato il tracciato delle chiamate) e dalla
  82.         riga 24 alla riga 25 (dove appaiono i vari messaggi di stato).
  83. ---------------------------------------------------------------------------*/
  84. void setup_screen ()
  85. {
  86.         char stringa[40];
  87.  
  88.         virtual_screen ();
  89.  
  90.         cclrscrn(LGREY|_BLACK);
  91.         ox = wherex ();
  92.         oy = wherey ();
  93.         hidecur ();
  94.  
  95.         wh1 = wopen (0, 0, 24, 79, 5, LGREY|_BLACK, LGREY|_BLACK);
  96.         wactiv (wh1);
  97.  
  98.         wbox (1, 0, 24, 79, 0, LGREY|_BLACK);
  99.         whline (12, 0, 80, 0, LGREY|_BLACK);
  100.         whline (22, 0, 80, 0, LGREY|_BLACK);
  101.         wvline (22,31, 3, 0, LGREY|_BLACK);
  102.         wvline (22,41, 3, 0, LGREY|_BLACK);
  103.         wvline (1, 52, 24, 0, LGREY|_BLACK);
  104. //   wvline (22, 21, 3, 0, LGREY|_BLACK);
  105.         sprintf (stringa, "%d:%d/%d.%d", config->alias[0].zone, config->alias[0].net, config->alias[0].node, config->alias[0].point);
  106.         prints (0, 1, LGREEN|_BLACK, stringa);
  107.         prints (0, 78 - strlen (VERSION), LGREEN|_BLACK, VERSION);
  108. //   prints (0, 78 - strlen (system_name), LGREEN|_BLACK, system_name);
  109.         prints (1, 1, LCYAN|_BLACK, "LOG");
  110.         prints (1, 53, LCYAN|_BLACK, "SYSTEM");
  111.         prints (12, 1, LCYAN|_BLACK, "OUTBOUND");
  112.         prints (12, 53, LCYAN|_BLACK, "MODEM");
  113.         prints (22, 1, LCYAN|_BLACK, "EVENT: ");
  114.         prints (22, 32, LCYAN|_BLACK, "M'TASKER");
  115.         prints (22, 42, LCYAN|_BLACK, "KEYBD");
  116.         prints (22, 53, LCYAN|_BLACK, "RECEIVED");
  117.         prints (13, 2, YELLOW|_BLACK, "Node            Try/Con  Type  Size    Status");
  118.  
  119.         prints (5, 54, LCYAN|_BLACK, "   Status:");
  120.         prints (6, 54, LCYAN|_BLACK, "  Elapsed:");
  121.  
  122.         idle_system ();
  123.  
  124.         activation_key ();
  125.    sprintf (stringa, "%s", VERSION);
  126.         prints (0, 78 - strlen (stringa), LGREEN|_BLACK, stringa);
  127. }
  128.  
  129. /*---------------------------------------------------------------------------
  130.         void idle_system (void);
  131.  
  132. ---------------------------------------------------------------------------*/
  133. void idle_system ()
  134. {
  135.         char string[20];
  136.  
  137.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  138.  
  139.         prints (7, 54, LCYAN|_BLACK, "     Next:");
  140.         prints (8, 54, LCYAN|_BLACK, "Remaining:");
  141.         prints (9, 54, LCYAN|_BLACK, "  Current:");
  142.         prints (10, 54, LCYAN|_BLACK, "     Port:");
  143. //      prints (11, 54, LCYAN|_BLACK, " M'tasker:");
  144.         mtask_find ();
  145.         sprintf (string, "%-6lu Com%d", rate, com_port + 1);
  146.         prints (10, 65, YELLOW|_BLACK, string);
  147. }
  148.  
  149. /*---------------------------------------------------------------------------
  150.         void blank_system (void);
  151.  
  152. ---------------------------------------------------------------------------*/
  153. void blank_system ()
  154. {
  155.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  156. }
  157.  
  158. /*---------------------------------------------------------------------------
  159.         void toss_system (void);
  160.  
  161. ---------------------------------------------------------------------------*/
  162. void toss_system ()
  163. {
  164.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  165.  
  166.         prints (7, 54, LCYAN|_BLACK, "   Packet:");
  167.         prints (8, 54, LCYAN|_BLACK, "     Date:");
  168.         prints (9, 54, LCYAN|_BLACK, "     Time:");
  169.         prints (10, 54, LCYAN|_BLACK, "     From:");
  170.         prints (11, 54, LCYAN|_BLACK, " Received:");
  171. }
  172.  
  173. /*---------------------------------------------------------------------------
  174.         void unpack_system (void);
  175.  
  176. ---------------------------------------------------------------------------*/
  177. void unpack_system ()
  178. {
  179.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  180.  
  181.         prints (7, 54, LCYAN|_BLACK, "   Packet:");
  182.         prints (8, 54, LCYAN|_BLACK, "   Method:");
  183. }
  184.  
  185. /*---------------------------------------------------------------------------
  186.         void scan_system (void);
  187.  
  188. ---------------------------------------------------------------------------*/
  189. void scan_system ()
  190. {
  191.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  192.  
  193.         prints (7, 54, LCYAN|_BLACK, "  Message:");
  194.         prints (8, 54, LCYAN|_BLACK, "     Area:");
  195.         prints (9, 54, LCYAN|_BLACK, "     Base:");
  196.         prints (10, 54, LCYAN|_BLACK, "Forwarded:");
  197. }
  198.  
  199. /*---------------------------------------------------------------------------
  200.         void pack_system (void);
  201.  
  202. ---------------------------------------------------------------------------*/
  203. void pack_system ()
  204. {
  205.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  206.  
  207.         prints (7, 54, LCYAN|_BLACK, "     Node:");
  208.         prints (8, 54, LCYAN|_BLACK, " Filename:");
  209.         prints (9, 54, LCYAN|_BLACK, "   Method:");
  210. }
  211.  
  212. /*---------------------------------------------------------------------------
  213.         void dial_system (void);
  214.  
  215.         Finestra di stato adatta per le operazioni di chiamata di un altro BBS.
  216.         Viene visualizzato cosa sta facendo il mailer, chi sta chiamando e il
  217.         timeout dell'azione corrente.
  218.  
  219.         Local status puo' essere "Dialing" e "Connect".
  220.         Action puo' essere "Waiting", "YooHoo/2U2", "EMSI/C1", "EMSI/C2" oppure
  221.         "FTSC-001".
  222. ---------------------------------------------------------------------------*/
  223. void dial_system ()
  224. {
  225.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  226.  
  227.         prints (7, 54, LCYAN|_BLACK, "   Action:");
  228.         prints (8, 54, LCYAN|_BLACK, "  Timeout:");
  229. }
  230.  
  231. void filetransfer_system ()
  232. {
  233.         wfill (7, 53, 11, 78, ' ', LCYAN|_BLACK);
  234.  
  235.         prints (7, 55, LCYAN|_BLACK, "Protocol:");
  236.         prints (8, 54, LCYAN|_BLACK, "Files I/O:");
  237. }
  238.  
  239. /*---------------------------------------------------------------------------
  240.         void setup_bbs_screen (void);
  241.  
  242.         Apre lo schermo da utilizzare per la parte BBS, con due righe di stato
  243.         in basso e il resto della schermo da dedicare alla visualizzazione di
  244.         cio' che l'utente sta facendo.
  245. ---------------------------------------------------------------------------*/
  246. void setup_bbs_screen ()
  247. {
  248.         int i;
  249.  
  250.         if (local_mode != 2)
  251.                 clown_clear ();
  252.  
  253.         i = whandle();
  254.  
  255.         if (local_mode != 2) {
  256.                 status = wopen (23, 0, 24, 79, 5, BLACK|_LGREY, BLACK|_LGREY);
  257.                 wactiv (status);
  258.                 wprints (0, 65, BLACK|_LGREY, " [Time:      ]");
  259.                 wprints (1, 79 - strlen (reg_prompt), BLACK|_LGREY, reg_prompt);
  260.         }
  261.  
  262.         mainview = wopen (0, 0, (local_mode == 2) ? 24 : 22, 79, 5, LGREY|_BLACK, LGREY|_BLACK);
  263.         wactiv (mainview);
  264.  
  265.         f4_status ();
  266. }
  267.  
  268. /*---------------------------------------------------------------------------
  269.   void activation_key (void);
  270. ---------------------------------------------------------------------------*/
  271.  
  272. void activation_key()
  273. {
  274.         memset (serial_id, 0, 3);
  275.    reg_prompt = "  [Registered]";
  276.    registered = 1;
  277.    serial_no = 0;
  278.    serial_id[0] = 'F';
  279.    serial_id[1] = 'V';
  280. }
  281.  
  282. static int os2_active (void)
  283. {
  284.    return (1);
  285. }
  286.  
  287. /*---------------------------------------------------------------------------
  288.    void mtask_find (void)
  289.  
  290.         Cerca di identificare il multitasker sotto cui e' installato il programma.
  291.    Per ogni multitasker esiste una routine di time_release appropriata per
  292.         dare agli altri task il tempo CPU non usato da questo task.
  293. ---------------------------------------------------------------------------*/
  294. void mtask_find ()
  295. {
  296.          wprints (23, 33, YELLOW|_BLACK, "OS/2");
  297. }
  298.  
  299. void write_sysinfo()
  300. {
  301.         int fd;
  302.         char filename[80];
  303.         long pos;
  304.         struct _linestat lt;
  305.  
  306.         strcode (sysinfo.pwd, "YG&%FYTF%$RTD");
  307.  
  308.    sprintf (filename, "%sSYSINFO.DAT", config->sys_path);
  309.    fd = shopen(filename, O_BINARY|O_RDWR);
  310.    write(fd, (char *)&sysinfo, sizeof(struct _sysinfo));
  311.  
  312.    pos = tell (fd);
  313.    while (read(fd, (char *)<, sizeof(struct _linestat)) == sizeof (struct _linestat)) {
  314.       if (lt.line == line_offset)
  315.          break;
  316.       pos = tell (fd);
  317.    }
  318.  
  319.    if (lt.line == line_offset) {
  320.       lseek (fd, pos, SEEK_SET);
  321.       write (fd, (char *)&linestat, sizeof(struct _linestat));
  322.    }
  323.  
  324.    close (fd);
  325.  
  326.    strcode (sysinfo.pwd, "YG&%FYTF%$RTD");
  327. }
  328.  
  329. void read_sysinfo (void)
  330. {
  331.    int fd, iyear, imday, iwday, imon, modif;
  332.    char filename[80];
  333.    long tempo;
  334.    struct tm *tim;
  335.  
  336.    modif = 0;
  337.  
  338.    sprintf (filename, "%sSYSINFO.DAT", config->sys_path);
  339.    if ((fd = sh_open (filename, SH_DENYRW, O_BINARY|O_RDWR, S_IREAD|S_IWRITE)) == -1) {
  340.       fd = sh_open (filename, SH_DENYRW, O_BINARY|O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
  341.       memset((char *)&sysinfo, 0, sizeof(struct _sysinfo));
  342.       status_line ("!Creating SYSINFO.DAT file");
  343.       write (fd, (char *)&sysinfo, sizeof(struct _sysinfo));
  344.       lseek (fd, 0, SEEK_SET);
  345.    }
  346.  
  347.    read (fd, (char *)&sysinfo, sizeof (struct _sysinfo));
  348.    memset ((char *)&linestat, 0, sizeof (struct _linestat));
  349.  
  350.    tempo = time (NULL);
  351.    tim = localtime (&tempo);
  352.  
  353.    imday = tim->tm_mday;
  354.    iwday = tim->tm_wday;
  355.    imon = tim->tm_mon;
  356.    iyear = tim->tm_year;
  357.  
  358.    while (read (fd, (char *)&linestat, sizeof (struct _linestat)) == sizeof (struct _linestat)) {
  359.       if (linestat.line == line_offset)
  360.          break;
  361.    }
  362.  
  363.    if (linestat.line != line_offset) {
  364.       memset ((char *)&linestat, 0, sizeof (struct _linestat));
  365.       sprintf (linestat.startdate, "%02d-%02d-%02d", tim->tm_mon + 1, tim->tm_mday, tim->tm_year % 100);
  366.       linestat.line = line_offset;
  367.       write (fd, (char *)&linestat, sizeof (struct _linestat));
  368.    }
  369.  
  370.    close (fd);
  371.  
  372.    if (sysinfo.pwd[0]) {
  373.       strcode (sysinfo.pwd, "YG&%FYTF%$RTD");
  374.       password = sysinfo.pwd;
  375.       locked = 1;
  376.    }
  377.  
  378.    if (!local_mode) {
  379.       tim = localtime (&sysinfo.today.timestamp);
  380.       if (tim == NULL || tim->tm_mday != imday) {
  381.          memcpy ((char *)&sysinfo.yesterday, (char *)&sysinfo.today, sizeof (struct _daystat));
  382.          memset ((char *)&sysinfo.today, 0, sizeof (struct _daystat));
  383.          sysinfo.today.timestamp = tempo;
  384.          if (!iwday) {
  385.             memset ((char *)&sysinfo.week, 0, sizeof (struct _daystat));
  386.             sysinfo.week.timestamp = tempo;
  387.          }
  388.          system_autoupdate ();
  389.          modif = 1;
  390.       }
  391.  
  392.       tim = localtime (&sysinfo.month.timestamp);
  393.       if (tim == NULL || tim->tm_mon != imon) {
  394.          memset ((char *)&sysinfo.month, 0, sizeof (struct _daystat));
  395.          sysinfo.month.timestamp = tempo;
  396.          modif = 1;
  397.       }
  398.  
  399.       tim = localtime (&sysinfo.year.timestamp);
  400.       if (tim == NULL || tim->tm_year != iyear) {
  401.          memset ((char *)&sysinfo.year, 0, sizeof (struct _daystat));
  402.          sysinfo.year.timestamp = tempo;
  403.          modif = 1;
  404.       }
  405.  
  406.       if (modif)
  407.          write_sysinfo ();
  408.    }
  409. }
  410.  
  411. void update_sysinfo_calls (void)
  412. {
  413.    int fd;
  414.    char filename[80];
  415.  
  416.    sprintf (filename, "%sSYSINFO.DAT", config->sys_path);
  417.    fd = sh_open (filename, SH_DENYRW, O_BINARY|O_RDWR, S_IREAD|S_IWRITE);
  418.  
  419.    read (fd, (char *)&sysinfo, sizeof (struct _sysinfo));
  420.  
  421.    sysinfo.total_calls++;
  422.    sysinfo.today.humancalls++;
  423.    sysinfo.week.humancalls++;
  424.    sysinfo.month.humancalls++;
  425.    sysinfo.year.humancalls++;
  426.  
  427.    lseek (fd, 0L, SEEK_SET);
  428.    write (fd, (char *)&sysinfo, sizeof (struct _sysinfo));
  429.  
  430.    memset ((char *)&linestat, 0, sizeof (struct _linestat));
  431.  
  432.    while (read (fd, (char *)&linestat, sizeof (struct _linestat)) == sizeof (struct _linestat)) {
  433.       if (linestat.line == line_offset)
  434.          break;
  435.    }
  436.  
  437.    close (fd);
  438.  
  439.    if (sysinfo.pwd[0])
  440.       strcode (sysinfo.pwd, "YG&%FYTF%$RTD");
  441. }
  442.  
  443. static int fossil_inf(finfo)
  444. struct _fossil_info far *finfo;
  445. {
  446.    return (0);
  447. }
  448.  
  449. void fossil_version()
  450. {
  451.    struct _fossil_info finfo;
  452.  
  453.    fossil_inf(&finfo);
  454.    m_print(msgtxt[M_FOSSIL_TYPE], finfo.id);
  455. }
  456.  
  457. void fossil_version2 (void)
  458. {
  459.    struct _fossil_info finfo;
  460.  
  461.    if (local_mode)
  462.       m_print(bbstxt[B_FOSSIL_INFO], (char far *)"<< Local mode >>");
  463.    else {
  464.       fossil_inf(&finfo);
  465.       m_print(bbstxt[B_FOSSIL_INFO], finfo.id);
  466.    }
  467. }
  468.  
  469. void terminating_call (void)
  470. {
  471.    int wh;
  472.  
  473.    if (caller) {
  474.       if (local_mode != 2) {
  475.          if (config->snooping) {
  476.             hidecur ();
  477.             wh = wopen(11,24,15,54,1,LCYAN|_BLUE,LCYAN|_BLUE);
  478.             wactiv(wh);
  479.  
  480.             wcenters(1,LCYAN|_BLUE,"Terminating call");
  481.          }
  482.          else
  483.                                 prints (5, 65, YELLOW|_BLACK, "Terminating ");
  484.       }
  485.  
  486.       textattr (LGREY|_BLACK);
  487.       update_user ();
  488.    }
  489.  
  490.    if (sq_ptr != NULL) {
  491.       MsgUnlock (sq_ptr);
  492.       MsgCloseArea (sq_ptr);
  493.       sq_ptr = NULL;
  494.    }
  495.  
  496.    modem_hangup ();
  497. }
  498.  
  499. static void virtual_screen()
  500. {
  501. }
  502.  
  503. static void disappear_effect1 (void);
  504. static void disappear_effect2 (void);
  505. static void disappear_effect3 (void);
  506. static void disappear_effect4 (void);
  507. static void disappear_effect5 (void);
  508. static void disappear_effect6 (void);
  509.  
  510. void clown_clear ()
  511. {
  512.    struct time dt;
  513.  
  514.    gettime (&dt);
  515.    srand (dt.ti_sec * 100 + dt.ti_hund);
  516.  
  517.    switch (random (6) + 1) {
  518.       case 1:
  519.          disappear_effect1 ();
  520.          break;
  521.       case 2:
  522.          disappear_effect2 ();
  523.          break;
  524.       case 3:
  525.          disappear_effect3 ();
  526.          break;
  527.       case 4:
  528.          disappear_effect4 ();
  529.          break;
  530.       case 5:
  531.          disappear_effect5 ();
  532.          break;
  533.       case 6:
  534.          disappear_effect6 ();
  535.          break;
  536.    }
  537.  
  538.    cclrscrn (LGREY|_BLACK);
  539. }
  540.  
  541. static void disappear_effect1 ()
  542. {
  543.    int i;
  544.  
  545.    for (i = 0; i < 25; i++) {
  546.       scrollbox (0, 0, 24, 39, 1, D_DOWN);
  547.       scrollbox (0, 40, 24, 79, 1, D_UP);
  548.       delay (15);
  549.    }
  550. }
  551.  
  552. static void disappear_effect2 ()
  553. {
  554.    int i;
  555.  
  556.    for (i = 0; i < 25; i++) {
  557.       scrollbox (0, 0, 24, 39, 1, D_UP);
  558.       scrollbox (0, 40, 24, 79, 1, D_DOWN);
  559.       delay (15);
  560.    }
  561. }
  562.  
  563. static void disappear_effect3 ()
  564. {
  565.    int i;
  566.  
  567.    for (i = 0; i < 12; i++) {
  568.       scrollbox (0, 0, 12, 79, 1, D_UP);
  569.       scrollbox (13, 0, 24, 79, 1, D_DOWN);
  570.       delay (15);
  571.    }
  572.  
  573.    scrollbox (0, 0, 12, 79, 1, D_UP);
  574. }
  575.  
  576. static void disappear_effect4 ()
  577. {
  578.    int i;
  579.  
  580.    for (i = 0; i < 12; i++) {
  581.       scrollbox (0, 0, 12, 79, 1, D_DOWN);
  582.       scrollbox (13, 0, 24, 79, 1, D_UP);
  583.       delay (15);
  584.    }
  585.  
  586.    scrollbox (0, 0, 12, 79, 1, D_DOWN);
  587. }
  588.  
  589. static void disappear_effect5 ()
  590. {
  591.    int i;
  592.  
  593.    for (i = 0; i < 12; i++) {
  594.       scrollbox (0, 0, 12, 39, 1, D_DOWN);
  595.       scrollbox (0, 40, 12, 79, 1, D_UP);
  596.       scrollbox (13, 0, 24, 39, 1, D_UP);
  597.       scrollbox (13, 40, 24, 79, 1, D_DOWN);
  598.       delay (15);
  599.    }
  600.  
  601.    scrollbox (0, 0, 12, 39, 1, D_DOWN);
  602.    scrollbox (0, 40, 12, 79, 1, D_UP);
  603. }
  604.  
  605. static void disappear_effect6 ()
  606. {
  607.    int i;
  608.  
  609.    for (i = 0; i < 12; i++) {
  610.       scrollbox (0, 0, 12, 39, 1, D_UP);
  611.       scrollbox (0, 40, 12, 79, 1, D_DOWN);
  612.       scrollbox (13, 0, 24, 39, 1, D_DOWN);
  613.       scrollbox (13, 40, 24, 79, 1, D_UP);
  614.       delay (15);
  615.    }
  616.  
  617.    scrollbox (0, 0, 12, 39, 1, D_UP);
  618.    scrollbox (0, 40, 12, 79, 1, D_DOWN);
  619. }
  620.  
  621. #define MAXDUPES      1000
  622.  
  623. struct _dupecheck {
  624.    char  areatag[48];
  625.    short dupe_pos;
  626.    short max_dupes;
  627.    long  area_pos;
  628.    long  dupes[MAXDUPES];
  629. };
  630.  
  631. struct _dupeindex {
  632.    char  areatag[48];
  633.    long  area_pos;
  634. };
  635.  
  636. static void system_autoupdate ()
  637. {
  638.    int fdm, fdd, fdn, fdi, *varr;
  639.    char filename[80], found, newname[80];
  640.    struct _sys tsys;
  641.    struct _dupecheck *dupecheck;
  642.    struct _dupeindex dupeindex;
  643.  
  644.    if (modem_busy != NULL)
  645.       mdm_sendcmd (modem_busy);
  646.  
  647.    sprintf (filename, "%sDUPES.NEW", config->sys_path);
  648.    fdn = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  649.    if (fdn != -1) {
  650.       close (fdn);
  651.       return;
  652.    }
  653.  
  654.    sprintf (filename, "%sDUPES.NEW", config->sys_path);
  655.    fdn = sh_open (filename, SH_DENYWR, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  656.    if (fdn == -1)
  657.       goto otherprocess;
  658.  
  659.    if (blanked)
  660.       stop_blanking ();
  661.  
  662.    status_line ("-Performing system \"AutoMaint\" routine");
  663.    local_status ("AutoMaint");
  664.  
  665.    sprintf (filename, SYSMSG_PATH, config->sys_path);
  666.    fdm = sh_open (filename, SH_DENYRW, O_RDONLY|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  667.    if (fdm == -1) {
  668.       close (fdn);
  669.       goto otherprocess;
  670.    }
  671.  
  672.    sprintf (filename, "%sDUPES.IDX", config->sys_path);
  673.    fdi = sh_open (filename, SH_DENYRW, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  674.    if (fdi == -1) {
  675.       close (fdm);
  676.       close (fdn);
  677.       goto otherprocess;
  678.    }
  679.  
  680.    sprintf (filename, "%sDUPES.DAT", config->sys_path);
  681.    fdd = sh_open (filename, SH_DENYRW, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  682.    if (fdd == -1) {
  683.       close (fdi);
  684.       close (fdm);
  685.       close (fdn);
  686.       goto otherprocess;
  687.    }
  688.  
  689.    dupecheck = (struct _dupecheck *)malloc (sizeof (struct _dupecheck));
  690.    if (dupecheck == NULL) {
  691.       close (fdi);
  692.       close (fdm);
  693.       close (fdn);
  694.       close (fdd);
  695.       goto otherprocess;
  696.    }
  697.  
  698.    while (read (fdd, (char *)dupecheck, sizeof (struct _dupecheck)) == sizeof (struct _dupecheck)) {
  699.       lseek (fdm, 0L, SEEK_SET);
  700.       found = 0;
  701.  
  702.       while (read (fdm, (char *)&tsys, SIZEOF_MSGAREA) == SIZEOF_MSGAREA)
  703.          if (!stricmp (tsys.echotag, dupecheck->areatag)) {
  704.             found = 1;
  705.             break;
  706.          }
  707.  
  708.       if (found) {
  709.          memset ((char *)&dupeindex, 0, sizeof (struct _dupeindex));
  710.          strcpy (dupeindex.areatag, dupecheck->areatag);
  711.          dupecheck->area_pos = dupeindex.area_pos = tell (fdn);
  712.          write (fdn, (char *)dupecheck, sizeof (struct _dupecheck));
  713.          write (fdi, (char *)&dupeindex, sizeof (struct _dupeindex));
  714.       }
  715.  
  716.       time_release ();
  717.    }
  718.  
  719.    close (fdd);
  720.    close (fdn);
  721.    close (fdi);
  722.    close (fdm);
  723.  
  724.    sprintf (filename, "%sDUPES.NEW", config->sys_path);
  725.    sprintf (newname, "%sDUPES.DAT", config->sys_path);
  726.    unlink (newname);
  727.    rename (filename, newname);
  728.  
  729.    free (dupecheck);
  730.  
  731. otherprocess:
  732.    if (config->automaint[0]) {
  733.       fclose (logf);
  734.       getcwd (filename, 49);
  735.       varr = ssave ();
  736.       cclrscrn (LGREY|_BLACK);
  737.  
  738.       spawn_program (registered, config->automaint);
  739.  
  740.       if (varr != NULL)
  741.          srestore (varr);
  742.       setdisk (filename[0] - 'A');
  743.       chdir (filename);
  744.       open_logfile ();
  745.    }
  746.  
  747.    if (modem_busy != NULL)
  748.       modem_hangup ();
  749.  
  750.    local_status (msgtxt[M_SETTING_BAUD]);
  751. }
  752.  
  753.