home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / files.c < prev    next >
Text File  |  1998-08-01  |  84KB  |  3,262 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 <io.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23. #include <dir.h>
  24. #include <fcntl.h>
  25. #include <time.h>
  26. #include <stdlib.h>
  27. #include <alloc.h>
  28. #include <sys\stat.h>
  29.  
  30. #include <cxl\cxlvid.h>
  31. #include <cxl\cxlwin.h>
  32. #include <cxl\cxlstr.h>
  33.  
  34. #include "lsetup.h"
  35. #include "sched.h"
  36. #include "msgapi.h"
  37. #include "externs.h"
  38. #include "prototyp.h"
  39. #include "zmodem.h"
  40.  
  41. #define DOWN_FILES  0x0020
  42. #define NO_MESSAGE  0x0040
  43. #define COPYBUFFER  8192
  44.  
  45. typedef struct {
  46.     char name[13];
  47.     word area;
  48.     long datpos;
  49. } FILEIDX;
  50.  
  51. extern short tcpip;
  52. char no_external = 0, no_description = 0, no_check = 0, no_precheck = 0;
  53.  
  54. void stripcrlf (char *linea);
  55. int exist_system_file (char *name);
  56. void m_print2(char *format, ...);
  57. char *translate_ansi (char *);
  58. void check_uploads (FILE *xferinfo, char *path);
  59. void update_filestat (char *rqname);
  60. int download_tagged_files (char *fname);
  61. void tag_files (int);
  62. void ask_birthdate (void);
  63. int m_getch (void);
  64. void update_lastread_pointers (void);
  65. void general_external_protocol (char *name, char *path, int id, int global, int dl);
  66. void display_external_protocol (int id);
  67.  
  68. static FILE *Infile;
  69. static int fsize2 = 0;
  70.  
  71. static int prot_read_file (char *);
  72. int file_more_question (int, int);
  73.  
  74. typedef struct _dirent {
  75.     char name[13];
  76.     unsigned date;
  77.     long size;
  78. } DIRENT;
  79.  
  80. DIRENT *scandir (char *dir, int *n)
  81. {
  82.     int ndir = 0;
  83.     char filename[80];
  84.     struct ffblk blk;
  85.     DIRENT *d;
  86.  
  87.     sprintf (filename, "%s*.*", dir);
  88.     if (findfirst (filename, &blk, 0))
  89.         return (NULL);
  90.  
  91.     do {
  92.         ndir++;
  93.     } while (!findnext (&blk));
  94.  
  95.     d = (DIRENT *)calloc (ndir, sizeof (DIRENT));
  96.     if (d == NULL)
  97.         return (NULL);
  98.  
  99.     if (findfirst (filename, &blk, 0))
  100.         return (NULL);
  101.  
  102.     ndir = 0;
  103.  
  104.     do {
  105.         strcpy (d[ndir].name, blk.ff_name);
  106.         d[ndir].date = blk.ff_fdate;
  107.         d[ndir].size = blk.ff_fsize;
  108.         ndir++;
  109.     } while (!findnext (&blk));
  110.  
  111.     *n = ndir;
  112.     return (d);
  113. }
  114.  
  115. void file_list (char *path, char *list)
  116. {
  117.     int fd, m, i, line, z, nnd, yr;
  118.     char filename[80], name[14], desc[70], *fbuf, *p;
  119.     DIRENT *de;
  120.  
  121.     cls ();
  122.  
  123.     m_print(bbstxt[B_CONTROLS]);
  124.     m_print(bbstxt[B_CONTROLS2]);
  125.     change_attr (CYAN|_BLACK);
  126.  
  127.     if (list == NULL || !(*list)) {
  128.         i = strlen(path) - 1;
  129.         while (path[i] == ' ')
  130.             path[i--] = '\0';
  131.         while (*path == ' ' && *path != '\0')
  132.             path++;
  133.  
  134.         sprintf(filename,"%sFILES.BBS",path);
  135.         fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  136.     }
  137.     else {
  138.         status_line(msgtxt[M_READ_FILE_LIST],list);
  139.         fd = sh_open (list, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  140.     }
  141.  
  142.     // Se il file e' di 0 bytes non importa leggere altro
  143.     if (fd == -1 || filelength (fd) == 0L) {
  144.         if (fd != -1)
  145.             close (fd);
  146.         return;
  147.     }
  148.  
  149.     line = 3;
  150.  
  151.     // Alloca il buffer che andra' a contenere l'intero files.bbs per
  152.     // l'area corrente. Se non riesce ad allocarselo scrive una linea
  153.     // nel log con le informazioni utili (spero) per il debugging.
  154.     if ((fbuf = (char *)malloc ((unsigned int)filelength (fd) + 1)) == NULL) {
  155.         status_line ("!MEM: new_file_list (%ld)", filelength (fd));
  156.         close (fd);
  157.         return;
  158.     }
  159.  
  160.     // Lettura di tutto il files.bbs nel buffer allocato.
  161.     read (fd, fbuf, (unsigned int)filelength (fd));
  162.     fbuf[(unsigned int)filelength (fd)] = '\0';
  163.     close (fd);
  164.  
  165.     // Legge tutta la directory in memoria. Se non c'e' spazio sufficiente
  166.     // prosegue (scandir si occupa di segnalare nel log gli errori.
  167.     if ((de = scandir (sys.filepath, &nnd)) == NULL) {
  168.         free (fbuf);
  169.         return;
  170.     }
  171.  
  172.     // La scansione del files.bbs avviene in memoria. Tenendo conto che
  173.     // ogni linea e' separata almeno da un \r (CR, 0x0D) si puo' utilizzare
  174.     // la strtok, trattando l'intero buffer come un insieme di token.
  175.     if ((p = strtok (fbuf, "\r")) != NULL)
  176.         do {
  177.             // Nel caso di \r\n (EOL) e' necessario saltare il \n per evitare
  178.             // problemi nel riconoscimento dei files.
  179.             if (*p == '\n')
  180.                 p++;
  181.  
  182.             if (*p == '\0') {
  183.                 m_print (bbstxt[B_ONE_CR]);
  184.                 if ((line = file_more_question (line, 1)) == 0 || !CARRIER)
  185.                     break;
  186.                 continue;
  187.             }
  188.  
  189.             if (!CARRIER || (!local_mode && RECVD_BREAK())) {
  190.                 line = 0;
  191.                 break;
  192.             }
  193.  
  194.             // Se il primo carattere non e' alfanumerico si tratta di un
  195.             // commento, pertanto non e' necessario visualizzarlo.
  196.             if (*p == '-') {
  197.                 *p = ' ';
  198.                 m_print (bbstxt[B_FILES_DASHLINE], p);
  199.  
  200.                 if ((line = file_more_question (line, 1)) == 0 || !CARRIER)
  201.                     break;
  202.             }
  203.             else if (*p == ' ') {
  204.                 if (p[1] == '>' || p[1] == '|') {
  205.                     if (sys.no_filedate)
  206.                         m_print (bbstxt[B_FILES_XNODATE], &p[2]);
  207.                     else
  208.                         m_print (bbstxt[B_FILES_XDATE], &p[2]);
  209.                 }
  210.                 else
  211.                     m_print (bbstxt[B_FILES_SPACELINE], &p[1]);
  212.  
  213.                 if ((line = file_more_question (line, 1)) == 0 || !CARRIER)
  214.                     break;
  215.             }
  216.             else {
  217.                 // Estrae il nome del file dalla stringa puntata da p
  218.                 m = 0;
  219.                 while (p[m] && p[m] != ' ' && m < 12)
  220.                     name[m] = p[m++];
  221.                 name[m] = '\0';
  222.  
  223.                 if (m == 0) {
  224.                     m_print (bbstxt[B_ONE_CR]);
  225.                     if ((line = file_more_question (line, 1)) == 0 || !CARRIER)
  226.                         break;
  227.                     continue;
  228.                 }
  229.  
  230.                 // Cerca il file nella lista in memoria puntata da de.
  231.                 for (i = 0; i < nnd; i++) {
  232.                     if (!stricmp (de[i].name, name))
  233.                         break;
  234.                 }
  235.  
  236.                 // Se trova il file nella directory prosegue le verifiche
  237.                 // altrimenti salta alla linea sucessiva.
  238.                 yr = (i >= nnd) ? -1 : 0;
  239.  
  240.                 z = 0;
  241.                 while (p[m] == ' ')
  242.                     m++;
  243.                 while (p[m] && z < (sys.no_filedate ? 56 : 48))
  244.                     desc[z++] = p[m++];
  245.                 if (p[m] != '\0')
  246.                     while (p[m] != ' ' && z > 0) {
  247.                         m--;
  248.                         z--;
  249.                     }
  250.                 desc[z] = '\0';
  251.  
  252.                 if (sys.no_filedate) {
  253.                     if (yr == -1) {
  254.                         if (config->show_missing)
  255.                             m_print (bbstxt[B_FILES_NODATE_MISSING], strupr (name), bbstxt[B_FILES_MISSING], desc);
  256.                     }
  257.                     else
  258.                         m_print (bbstxt[B_FILES_NODATE], strupr (name), de[i].size, desc);
  259.                 }
  260.                 else {
  261.                     if (yr == -1) {
  262.                         if (config->show_missing)
  263.                             m_print (bbstxt[B_FILES_FORMAT_MISSING], strupr (name), bbstxt[B_FILES_MISSING], desc);
  264.                     }
  265.                     else
  266.                         m_print (bbstxt[B_FILES_FORMAT], strupr (name), de[i].size, show_date (config->dateformat, e_input, de[i].date, 0), desc);
  267.                 }
  268.                 if (!(line = file_more_question (line, 1)) || !CARRIER)
  269.                     break;
  270.  
  271.                 while (p[m] != '\0') {
  272.                     z = 0;
  273.                     while (p[m] != '\0' && z < (sys.no_filedate ? 56 : 48))
  274.                         desc[z++] = p[m++];
  275.                     if (p[m] != '\0')
  276.                         while (p[m] != ' ' && z > 0) {
  277.                             m--;
  278.                             z--;
  279.                         }
  280.                     desc[z]='\0';
  281.  
  282.                     if (sys.no_filedate)
  283.                         m_print (bbstxt[B_FILES_XNODATE], desc);
  284.                     else
  285.                         m_print (bbstxt[B_FILES_XDATE], desc);
  286.  
  287.                     if ((line=file_more_question(line, 1)) == 0 || !CARRIER)
  288.                         break;
  289.                 }
  290.  
  291.                 if (line == 0)
  292.                     break;
  293.             }
  294.         } while ((p = strtok (NULL, "\r")) != NULL);
  295.  
  296.     free (de);
  297.     free (fbuf);
  298.  
  299.     m_print (bbstxt[B_ONE_CR]);
  300.     if (line && CARRIER)
  301.         file_more_question (usr.len, 1);
  302. }
  303.  
  304. void file_display()
  305. {
  306.     char filename[80], stringa[20];
  307.  
  308.     if (!get_command_word (stringa, 14)) {
  309.         m_print(bbstxt[B_WHICH_FILE]);
  310.         input(stringa,14);
  311.         if(!strlen(stringa))
  312.             return;
  313.     }
  314.  
  315.     status_line("+Display '%s'",strupr(stringa));
  316.     sprintf(filename,"%s%s",sys.filepath,stringa);
  317.  
  318.     cls();
  319.  
  320.     if (prot_read_file(filename) > 1 && CARRIER)
  321.         press_enter();
  322. }
  323.  
  324. void override_path()
  325. {
  326.     char stringa[80];
  327.  
  328.     if (!get_command_word (stringa, 78)) {
  329.         m_print(bbstxt[B_FULL_OVERRIDE]);
  330.         input(stringa, 78);
  331.         if(!strlen(stringa))
  332.             return;
  333.     }
  334.  
  335.     append_backslash (stringa);
  336.     status_line("*Path override '%s'",strupr(stringa));
  337.  
  338.     strcpy (sys.filepath, stringa);
  339.     strcpy (sys.uppath, stringa);
  340.     fancy_str (stringa);
  341.     strcpy (sys.file_name, stringa);
  342. }
  343.  
  344. static int prot_read_file(name)
  345. char *name;
  346. {
  347.     FILE *fp;
  348.     char linea[130], *p;
  349.     int line;
  350.  
  351.     XON_ENABLE();
  352.     _BRK_ENABLE();
  353.  
  354.     if(!name || !(*name))
  355.         return(0);
  356.  
  357.     fp = fopen(name,"rb");
  358.     if (fp == NULL)
  359.         return(0);
  360.  
  361.     line = 1;
  362.     nopause = 0;
  363.  
  364. loop:
  365.     change_attr(LGREY|_BLACK);
  366.  
  367.     while (fgets(linea,128,fp) != NULL) {
  368.         linea[strlen(linea) - 2] = '\0';
  369.  
  370.         for (p=linea;(*p);p++) {
  371.             if (!CARRIER || (!local_mode && RECVD_BREAK ())) {
  372.                 CLEAR_OUTBOUND();
  373.                 fclose(fp);
  374.                 return (0);
  375.             }
  376.  
  377.             if (*p == 0x1B)
  378.                 p = translate_ansi (p);
  379.             else {
  380.                 if (!local_mode)
  381.                     BUFFER_BYTE(*p);
  382.                 if (snooping)
  383.                     wputc(*p);
  384.             }
  385.         }
  386.  
  387.         if (!local_mode) {
  388.             BUFFER_BYTE('\r');
  389.             BUFFER_BYTE('\n');
  390.         }
  391.         if (snooping)
  392.             wputs("\n");
  393.  
  394.         if(!(line++ < (usr.len-1)) && usr.len != 0) {
  395.             line = 1;
  396.             if(!continua()) {
  397.                 fclose(fp);
  398.                 break;
  399.             }
  400.         }
  401.  
  402.         if (*p == CTRLZ) {
  403.             fclose(fp);
  404.             UNBUFFER_BYTES ();
  405.             FLUSH_OUTPUT ();
  406.             break;
  407.         }
  408.     }
  409.  
  410.     fclose(fp);
  411.  
  412.     UNBUFFER_BYTES ();
  413.     FLUSH_OUTPUT();
  414.  
  415.     return(line);
  416. }
  417.  
  418. void raw_dir()
  419. {
  420.     int yr, mo, dy, line, nfiles;
  421.     char stringa[30], filename[80];
  422.     long fsize;
  423.     struct ffblk blk;
  424.  
  425.     nopause = 0;
  426.  
  427.     if (!get_command_word (stringa, 14)) {
  428.         m_print(bbstxt[B_DIRMASK]);
  429.         input(stringa,14);
  430.         if(!CARRIER)
  431.             return;
  432.     }
  433.  
  434.    if (!strlen (stringa))
  435.       strcpy (stringa, "*.*");
  436.  
  437.    sprintf(filename,"%s%s",sys.filepath, stringa);
  438.  
  439.    line = 1;
  440.    nfiles = 0;
  441.    fsize = 0L;
  442.  
  443.    if (!findfirst(filename,&blk,0)) {
  444.       cls ();
  445.       m_print (bbstxt[B_RAW_HEADER]);
  446.  
  447.       do {
  448.          yr = (blk.ff_fdate >> 9) & 0x7F;
  449.          mo = (blk.ff_fdate >> 5) & 0x0F;
  450.          dy = blk.ff_fdate & 0x1F;
  451.  
  452.          m_print(bbstxt[B_RAW_FORMAT], blk.ff_name, blk.ff_fsize, dy, mesi[mo-1], (yr+80)%100);
  453.  
  454.          nfiles++;
  455.          fsize += blk.ff_fsize;
  456.  
  457.          if (!(line=file_more_question(line, 1)) || !CARRIER)
  458.             break;
  459.          if (!local_mode && RECVD_BREAK ())
  460.             break;
  461.       } while(!findnext(&blk));
  462.    }
  463.  
  464.    if (CARRIER && line) {
  465.       sprintf (stringa, "%d files", nfiles);
  466.         m_print (bbstxt[B_RAW_FOOTER], stringa, fsize);
  467.       press_enter();
  468.    }
  469. }
  470.  
  471. void new_file_list (only_one)
  472. int only_one;
  473. {
  474.    int fpd, day, mont, year, line, m, z, fd, nnd, i, len, oldlen = 0;
  475.    word search;
  476.    long totfile, totsize;
  477.    char month[4], name[13], desc[70], *fbuf, header[90];
  478.    char stringa[30], filename[80], *p, sameline, areadone;
  479.    struct _sys tsys, vsys;
  480.    DIRENT *de;
  481.  
  482.    sameline = (bbstxt[B_AREALIST_HEADER][strlen (bbstxt[B_AREALIST_HEADER]) - 1] == '\n') ? 0 : 1;
  483.    strcpy (header, bbstxt[B_AREALIST_HEADER]);
  484.    header[strlen (header) - 1] = '\0';
  485.  
  486.    totfile = totsize = 0L;
  487.     areadone = 0;
  488.  
  489.     if (only_one != 2)
  490.         m_print (bbstxt[B_NEW_SINCE_LAST]);
  491.  
  492.     if (only_one != 2 && yesno_question(DEF_YES) == DEF_NO) {
  493.         if (!get_command_word (stringa, 8)) {
  494.             m_print (bbstxt[B_NEW_DATE], bbstxt[B_DATEFORMAT + config->inp_dateformat]);
  495.             input (stringa, 8);
  496.             if (stringa[0] == '\0' || !CARRIER)
  497.                 return;
  498.         }
  499.  
  500.         sscanf (stringa, "%2d-%2d-%2d", &day, &mont, &year);
  501.         mont--;
  502.  
  503.         if (config->inp_dateformat == 1) {
  504.             i = day;
  505.             day = mont;
  506.             mont = i;
  507.         }
  508.         else if (config->inp_dateformat == 2) {
  509.             i = year;
  510.             year = day;
  511.             day = i;
  512.         }
  513.     }
  514.     else {
  515.         sscanf (usr.ldate, "%2d %3s %2d", &day, month, &year);
  516.         month[3] = '\0';
  517.         for (mont = 0; mont < 12; mont++) {
  518.             if ((!stricmp(mtext[mont], month)) || (!stricmp(mesi[mont], month)))
  519.                 break;
  520.         }
  521.     }
  522.  
  523.     if (only_one == 2)
  524.         only_one = 0;
  525.  
  526.     if ((mont == 12) || (day>31) || (day<1) || (year>99) || (year<80) || !CARRIER)
  527.         return;
  528.  
  529.     search = ((year - 80) << 9) | ((mont + 1) << 5) | day;
  530.  
  531.     cls ();
  532.     m_print (bbstxt[B_DATE_SEARCH]);
  533.     m_print (bbstxt[B_DATE_UNDERLINE]);
  534.  
  535.     line = 4;
  536.  
  537.     sprintf (filename, "%sSYSFILE.DAT", config->sys_path);
  538.     if ((fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE)) == -1) {
  539.         status_line (msgtxt[M_NO_SYSTEM_FILE]);
  540.         return;
  541.     }
  542.  
  543.     memcpy ((char *)&vsys.file_name, (char *)&sys.file_name, SIZEOF_FILEAREA);
  544.  
  545.     while (read (fd, (char *)&tsys.file_name,SIZEOF_FILEAREA) == SIZEOF_FILEAREA && line) {
  546.         if (only_one)
  547.             memcpy ((char *)&tsys.file_name, (char *)&sys.file_name, SIZEOF_FILEAREA);
  548.         else {
  549.             if (usr.priv < tsys.file_priv || tsys.no_global_search)
  550.                 continue;
  551.             if((usr.flags & tsys.file_flags) != tsys.file_flags)
  552.                 continue;
  553.         }
  554.  
  555.         if (tsys.cdrom) {
  556.             if (only_one || !CARRIER)
  557.                 break;
  558.  
  559.             continue;
  560.         }
  561.  
  562.         memcpy ((char *)&sys.file_name, (char *)&tsys.file_name, SIZEOF_FILEAREA);
  563.  
  564.         if (sameline && (usr.ansi || usr.avatar))
  565.             del_line ();
  566.  
  567.         m_print (header, tsys.file_num, tsys.file_name);
  568.         if (!sameline) {
  569.             m_print2 ("\n");
  570.             if ((line = file_more_question(line,only_one)) == 0)
  571.                 break;
  572.         }
  573.         else {
  574.             areadone = 0;
  575.             if (!usr.ansi && !usr.avatar) {
  576.                 len = strlen (tsys.file_name);
  577.                 if (oldlen != 0 && len < oldlen)
  578.                     space (oldlen - len);
  579.                 oldlen = len;
  580.             }
  581.             m_print2 ("\r");
  582.         }
  583.  
  584.         // Apertura del FILES.BBS utilizzando il path dell'area letta nella
  585.         // struttura locale tsys
  586.         if (!tsys.filelist[0])
  587.             sprintf (filename, "%sFILES.BBS", tsys.filepath);
  588.         else
  589.             strcpy (filename, tsys.filelist);
  590.         if ((fpd = open (filename, O_RDONLY|O_BINARY)) == -1)
  591.             continue;
  592.  
  593.         // Se il file e' di 0 bytes non importa leggere altro
  594.         if (filelength (fpd) == 0L) {
  595.             close (fpd);
  596.             continue;
  597.         }
  598.  
  599.         // Alloca il buffer che andra' a contenere l'intero files.bbs per
  600.         // l'area corrente. Se non riesce ad allocarselo scrive una linea
  601.         // nel log con le informazioni utili (spero) per il debugging.
  602.         if ((fbuf = (char *)malloc ((unsigned int)filelength (fpd) + 1)) == NULL) {
  603.             status_line ("!MEM: new_file_list (%ld)", filelength (fpd));
  604.             close (fpd);
  605.             continue;
  606.         }
  607.  
  608.         // Lettura di tutto il files.bbs nel buffer allocato.
  609.         read (fpd, fbuf, (unsigned int)filelength (fpd));
  610.         fbuf[(unsigned int)filelength (fpd)] = '\0';
  611.         close (fpd);
  612.  
  613.         // Legge tutta la directory in memoria. Se non c'e' spazio sufficiente
  614.         // prosegue (scandir si occupa di segnalare nel log gli errori.
  615.         if ((de = scandir (tsys.filepath, &nnd)) == NULL) {
  616.             free (fbuf);
  617.             continue;
  618.         }
  619.  
  620.         // La scansione del files.bbs avviene in memoria. Tenendo conto che
  621.         // ogni linea e' separata almeno da un \r (CR, 0x0D) si puo' utilizzare
  622.         // la strtok, trattando l'intero buffer come un insieme di token.
  623.         if ((p = strtok (fbuf, "\r\n")) != NULL)
  624.          do {
  625.             // Nel caso di \r\n (EOL) e' necessario saltare il \n per evitare
  626.             // problemi nel riconoscimento dei files.
  627.             if (p[0] == '\0')
  628.                continue;
  629.             if (p[0] == '\n')
  630.                p++;
  631.  
  632.             if (!CARRIER || (!local_mode && RECVD_BREAK())) {
  633.                line = 0;
  634.                break;
  635.             }
  636.  
  637.             // Se il primo carattere non e' alfanumerico si tratta di un
  638.             // commento, pertanto non e' necessario visualizzarlo.
  639.             if (!isalnum (p[0]))
  640.                continue;
  641.  
  642.             // Estrae il nome del file dalla stringa puntata da p
  643.             m = 0;
  644.             while (p[m] != ' ' && m < 12)
  645.                name[m] = p[m++];
  646.             name[m] = '\0';
  647.  
  648.             // Cerca il file nella lista in memoria puntata da de.
  649.             for (i = 0; i < nnd; i++) {
  650.                if (!stricmp (de[i].name, name))
  651.                   break;
  652.             }
  653.  
  654.             // Se trova il file nella directory prosegue le verifiche
  655.             // altrimenti salta alla linea sucessiva.
  656.             if (i < nnd && de[i].date >= search) {
  657.                     z = 0;
  658.                while (p[m] == ' ')
  659.                   m++;
  660.                while (p[m] && z < (tsys.no_filedate ? 56 : 48))
  661.                   desc[z++] = p[m++];
  662.                desc[z] = '\0';
  663.  
  664.                     totsize += de[i].size;
  665.                totfile++;
  666.  
  667.                if (sameline && !areadone) {
  668.                   areadone = 1;
  669.                         m_print (bbstxt[B_ONE_CR]);
  670.                   if ((line = file_more_question(line,only_one)) == 0)
  671.                      break;
  672.                }
  673.  
  674.                if (sys.no_filedate)
  675.                   m_print (bbstxt[B_FILES_NODATE], strupr (name), de[i].size, desc);
  676.                else
  677.                   m_print (bbstxt[B_FILES_FORMAT], strupr (name), de[i].size, show_date (config->dateformat, e_input, de[i].date, 0), desc);
  678.  
  679.                if (!(line = file_more_question (line, only_one)) || !CARRIER)
  680.                   break;
  681.             }
  682.          } while ((p = strtok (NULL, "\r\n")) != NULL);
  683.  
  684.       free (de);
  685.       free (fbuf);
  686.  
  687.       if (only_one || !CARRIER)
  688.          break;
  689.     }
  690.  
  691.     close(fd);
  692.  
  693.     memcpy ((char *)&sys.file_name, (char *)&vsys.file_name, SIZEOF_FILEAREA);
  694.  
  695.     if (sameline && !areadone)
  696.         m_print (bbstxt[B_ONE_CR]);
  697.  
  698.     m_print (bbstxt[B_LOCATED_MATCH], totfile, totsize);
  699.  
  700.     if (line && CARRIER)
  701.         file_more_question (usr.len, only_one);
  702. }
  703.  
  704. void download_report (char *rqname, int id, char *filelist)
  705. {
  706.     FILE *fp, *fp2;
  707.     char string[128];
  708.     char drive[80], path[80], name[16], ext[6];
  709.     struct ffblk blk;
  710.  
  711.     if (rqname != NULL) {
  712.         strupr (rqname);
  713.         fnsplit (rqname, drive, path, name, ext);
  714.         strcat (drive, path);
  715.         strcat (name, ext);
  716.         strupr (name);
  717.     }
  718.  
  719.     sprintf (string,"DL-REP%d.BBS", line_offset);
  720.     fp = fopen (string, (id == 1) ? "wt" : "at");
  721.     if (fp == NULL)
  722.         return;
  723.  
  724.     if (id == 2) {
  725.         strcat (drive, "FILES.BBS");
  726.  
  727.         if (findfirst (rqname, &blk, 0))
  728.             sprintf (string, bbstxt[B_REPORT_SUCCESFUL], name, cps, "* Not found *");
  729.  
  730.         else {
  731.             if ((fp2 = fopen (drive, "rt")) == NULL && filelist != NULL && *filelist)
  732.                 fp2 = fopen (filelist, "rt");
  733.  
  734.                 if(tagged_dnl){
  735.                     tagged_kb -= (blk.ff_fsize / 1024);
  736.                     if(tagged_kb<0) tagged_kb=0;
  737.                 }
  738.  
  739.             sprintf (string, bbstxt[B_REPORT_SUCCESFUL], name, cps, "* No description *");
  740.  
  741.             if (fp2 != NULL) {
  742.                 while (!feof (fp2)) {
  743.                     path[0] = 0;
  744.                     if (fgets (path, 70, fp2) == NULL)
  745.                         break;
  746.                     if (!strnicmp (path, name, strlen (name))) {
  747.                         path[strlen(path)-1] = 0;
  748.                         sprintf (string, bbstxt[B_REPORT_SUCCESFUL], name, cps, &path[13]);
  749.                         break;
  750.                     }
  751.                 }
  752.  
  753.                 fclose (fp2);
  754.             }
  755.         }
  756.  
  757.         fwrite (string, strlen (string), 1, fp);
  758.     }
  759.     else if (id == 3)
  760.         fprintf (fp, bbstxt[B_REPORT_NOT_SENT], name, cps);
  761.  
  762.     else if (id == 4)
  763.         fprintf (fp, "\n");
  764.  
  765.     fclose (fp);
  766.  
  767.     if (id == 4) {
  768.         sprintf (string,"DL-REP%d.BBS", line_offset);
  769.         read_file (string);
  770.         unlink (string);
  771.         timer (30);
  772.     }
  773. }
  774.  
  775. void download_file (st, global)
  776. char *st;
  777. int global;
  778. {
  779.     FILE *fp1,*fp2;
  780.  
  781.     int fd, i, m, protocol, killafter = 0;
  782.     char filename[80], path[80], dir[80], name[80], ext[5], logoffafter;
  783.     char old_filename[80], old_path[80],*copybuf;
  784.     long rp, t,length,blocks,j;
  785.     struct ffblk blk;
  786.     struct _sys tsys;
  787.     tagged_dnl=0;
  788.  
  789. #if defined (__OCC__) || defined (__TCPIP__)
  790.     if (tcpip && usr.priv < SYSOP) {
  791.         m_print ("\n Sorry, file transfer not available on TCP/IP\n");
  792.         press_enter ();
  793.         return;
  794.     }
  795. #endif
  796.  
  797.     fnsplit (st, path, dir, name, ext);
  798.     strcat (path, dir);
  799.     strcat (name, ext);
  800.  
  801.     if(!offline_reader && !sys.freearea && !usr.xfer_prior && config->class[usr_class].ratio && !name[0] && usr.n_dnld >= config->class[usr_class].start_ratio) {
  802.         rp = usr.upld ? (usr.dnld/usr.upld) : usr.dnld;
  803.         if (rp > (long)config->class[usr_class].ratio) {
  804.             cmd_string[0] = '\0';
  805.             status_line (":Dnld req. would exceed ratio");
  806.             read_system_file ("RATIO");
  807.             return;
  808.         }
  809.     }
  810.  
  811.     killafter = 0;
  812.  
  813.     if (global == -1) {
  814.         global = 0;
  815.         killafter = 1;
  816.     }
  817.     else if (global != -2 && global != -3) {
  818.         if (download_tagged_files (st))
  819.             return;
  820.     }
  821.     else
  822.         global = (global == -2) ? 0 : 1;
  823.  
  824.     if (user_status != UPLDNLD && user_status != 7)
  825.         set_useron_record(UPLDNLD, 0, 0);
  826.  
  827.     if (user_status != 7)
  828.         read_system_file ("PREDNLD");
  829.  
  830.     if (st == NULL)
  831.         cls ();
  832.     if ((protocol = selprot ()) == 0)
  833.         return;
  834.  
  835.     if (!dir[0] && st != NULL)
  836.         strcpy (path, sys.filepath);
  837.  
  838.     if (!name[0]) {
  839.         if (!cmd_string[0]) {
  840.             ask_for_filename (name, 0);
  841.             if (!name[0] || !CARRIER)
  842.                 return;
  843.         }
  844.         else {
  845.             strcpy (name, cmd_string);
  846.             cmd_string[0] = '\0';
  847.         }
  848.     }
  849.  
  850.     if (!display_transfer (protocol, path, name, global))
  851.         return;
  852.  
  853.     m_print (bbstxt[B_DL_CONFIRM]);
  854.     if (usr.hotkey)
  855.         cmd_input (filename, 1);
  856.     else
  857.         chars_input (filename, 1, 0);
  858.  
  859.     if (toupper (filename[0]) == '!')
  860.         logoffafter = 1;
  861.     else
  862.         logoffafter = 0;
  863.  
  864.     if (toupper (filename[0]) == 'A') {
  865.         m = 0;
  866.         logoffafter = 0;
  867.         goto abort_xfer;
  868.     }
  869.  
  870.     m_print(bbstxt[B_READY_TO_SEND]);
  871.     m_print(bbstxt[B_CTRLX_ABORT]);
  872.  
  873.     if (local_mode) {
  874.         sysop_error();
  875.         m = 0;
  876.         goto abort_xfer;
  877.     }
  878.  
  879.  
  880.     download_report (NULL, 1, NULL);
  881.  
  882.     if (protocol == 1 || protocol == 2 || protocol == 3 || protocol == 6) {
  883.         timer (10);
  884.         m = i = 0;
  885.  
  886.         while (get_string (name, dir) != NULL) {
  887.             sprintf (filename, "%s%s", path, dir);
  888.  
  889.             if (findfirst (filename, &blk, 0)) {
  890.                 sprintf (filename, "%sSYSFILE.DAT", config->sys_path);
  891.                 fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  892.  
  893.                 if (global) {
  894.                     while (read (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  895.                         if (usr.priv < tsys.file_priv)
  896.                             continue;
  897.                         if ((usr.flags & tsys.file_flags) != tsys.file_flags)
  898.                             continue;
  899.                         if (usr.priv < tsys.download_priv)
  900.                             continue;
  901.                         if ((usr.flags & tsys.download_flags) != tsys.download_flags)
  902.                             continue;
  903.  
  904.                         sprintf (filename, "%s%s", tsys.filepath, dir);
  905.  
  906.                         if (!findfirst (filename, &blk, 0))
  907.                             break;
  908.                     }
  909.                 }
  910.  
  911.                 close (fd);
  912.             }
  913.             else
  914.                 memcpy (&tsys.file_name, &sys.file_name, SIZEOF_FILEAREA);
  915.             if(tsys.cdrom&&config->cdrom_swap&&!offline_reader){
  916.  
  917.                 char t_name[20];
  918.                 struct ftime ft;
  919.                 int c;
  920.  
  921.                 strcpy (old_filename,filename);
  922.                 fp1 = fopen(old_filename,"rb");
  923.                 if(!fp1) {
  924.                     status_line("!Unable to open %s",old_filename);
  925.                     return;
  926.                 }
  927.                 sprintf (filename, "%scdrom%d", config->sys_path,line_offset);
  928.                 mkdir (filename);
  929.                 fnsplit (old_filename, NULL, NULL, t_name, ext);
  930.                      strcat(t_name,ext);
  931.                 sprintf (filename, "%scdrom%d\\%s", config->sys_path,line_offset,t_name);
  932.                 fp2 = fopen(filename,"wb");
  933.                 if(!fp2) {
  934.                     status_line("!Unable to open %s",filename);
  935.                     return;
  936.                 }
  937.                 length=filelength(fileno(fp1));
  938.                 blocks=length/(COPYBUFFER);
  939.                 copybuf=malloc(COPYBUFFER);
  940.                 for(j=0;j<blocks;j++){
  941.                     fread(copybuf,COPYBUFFER,1,fp1);
  942.                     fwrite(copybuf,COPYBUFFER,1,fp2);
  943.                 }
  944.                 fread(copybuf,length%COPYBUFFER,1,fp1);
  945.                 fwrite(copybuf,length%COPYBUFFER,1,fp2);
  946. /*                while((c=fgetc(fp1))!=EOF)
  947.                     fputc((char)c,fp2);
  948. */
  949.                 getftime(fileno(fp1),&ft);
  950.                 setftime(fileno(fp2),&ft);
  951.                 free (copybuf);
  952.                 fclose(fp1);
  953.                 fclose(fp2);
  954.                 status_line("+Copied %s -> %s",old_filename,filename);
  955.             }
  956.  
  957.             switch (protocol) {
  958.                 case 1:
  959.                     m = fsend (filename, 'X');
  960.                     break;
  961.                 case 2:
  962.                     m = fsend (filename, 'Y');
  963.                     break;
  964.                 case 3:
  965.                     m = send_Zmodem (filename, dir, i, 0);
  966.                     break;
  967.                 case 6:
  968.                     m = fsend (filename, 'S');
  969.                     break;
  970.             }
  971.  
  972.             if(tsys.cdrom&&config->cdrom_swap&&!offline_reader){
  973.                 unlink(filename);
  974.                      status_line("+Removed %s",filename);
  975.                 strcpy(filename,old_filename);
  976.             }
  977.  
  978.             if (!m) {
  979.                 download_report (filename, 3, tsys.filelist);
  980.                 break;
  981.             }
  982.  
  983.             if (config->keep_dl_count)
  984.                 update_filestat (filename);
  985.             download_report (filename, 2, tsys.filelist);
  986.             i++;
  987.  
  988.             if (!tsys.freearea || st == NULL) {
  989.                 usr.dnld += (int)(blk.ff_fsize / 1024L) + 1;
  990.                 usr.dnldl += (int)(blk.ff_fsize / 1024L) + 1;
  991.                 usr.n_dnld++;
  992.  
  993.                 if (function_active == 3)
  994.                     f3_status ();
  995.             }
  996.  
  997.             if (killafter)
  998.                 file_kill (1, dir);
  999.         }
  1000.  
  1001.         if (protocol == 3)
  1002.             send_Zmodem (NULL, NULL, ((i) ? END_BATCH : NOTHING_TO_DO), 0);
  1003.         else if (protocol == 6)
  1004.             fsend (NULL, 'S');
  1005.  
  1006. abort_xfer:
  1007.         wactiv (mainview);
  1008.  
  1009.         m_print (bbstxt[B_TWO_CR]);
  1010.  
  1011.         if (m)
  1012.             m_print(bbstxt[B_TRANSFER_OK]);
  1013.         else
  1014.             m_print(bbstxt[B_TRANSFER_ABORT]);
  1015.     }
  1016.  
  1017.     else if (protocol >= 10){
  1018.  
  1019.             if(sys.cdrom && (global!=1)&&config->cdrom_swap&&!offline_reader ) {
  1020.  
  1021.                 int c;
  1022.                 struct ftime ft;
  1023.  
  1024.                 strcpy(old_path,path);
  1025.                 sprintf(old_filename,"%s%s",path,name);
  1026.                 fp1 = fopen(old_filename,"rb");
  1027.                 if(!fp1) {
  1028.                     status_line("!Unable to open %s",old_filename);
  1029.                     return;
  1030.                 }
  1031.  
  1032.                 sprintf (filename, "%scdrom%d", config->sys_path, line_offset);
  1033.                 mkdir (filename);
  1034.                 sprintf (filename, "%scdrom%d\\%s", config->sys_path, line_offset, name);
  1035.                 fp2 = fopen(filename,"wb");
  1036.                 if(!fp2) {
  1037.                     status_line("!Unable to open %s",filename);
  1038.                     return;
  1039.                 }
  1040.                 length=filelength(fileno(fp1));
  1041.                 blocks=length/(COPYBUFFER);
  1042.                 copybuf=malloc(COPYBUFFER);
  1043.                 for(j=0;j<blocks;j++){
  1044.                     fread(copybuf,COPYBUFFER,1,fp1);
  1045.                     fwrite(copybuf,COPYBUFFER,1,fp2);
  1046.                 }
  1047.                 fread(copybuf,length%COPYBUFFER,1,fp1);
  1048.                 fwrite(copybuf,length%COPYBUFFER,1,fp2);/*                while((c=fgetc(fp1))!=EOF)
  1049.                 fputc((char)c,fp2);
  1050. */                
  1051.                 getftime(fileno(fp1),&ft);
  1052.                 setftime(fileno(fp2),&ft);
  1053.                 free (copybuf);
  1054.                 fclose(fp1);
  1055.                 fclose(fp2);
  1056.                 status_line("+Copied %s -> %s",old_filename,filename);
  1057.                 sprintf (path, "%scdrom%d\\", config->sys_path, line_offset);
  1058.             }
  1059.  
  1060.             general_external_protocol (name, path, protocol, killafter ? -1 : global, 1);
  1061.  
  1062.             if (sys.cdrom&&config->cdrom_swap&&!offline_reader){
  1063.                 unlink(filename);
  1064.                 status_line("+Removed %s",filename);
  1065.                 strcpy(path,old_path);
  1066.             }
  1067.       }
  1068.  
  1069.     download_report (NULL, 4, NULL);
  1070.  
  1071.     if (logoffafter) {
  1072.         if (user_status == 7)
  1073.             update_lastread_pointers ();
  1074.  
  1075.         rp = time (NULL) + 10L;
  1076.         do {
  1077.             m = -1;
  1078.             m_print (bbstxt[B_DL_LOGOFF], (int)(rp - time (NULL)));
  1079.             t = time (NULL);
  1080.             while (time (NULL) == t && CARRIER) {
  1081.                 release_timeslice ();
  1082.                 if ((m = toupper (m_getch ())) == 'A')
  1083.                     break;
  1084.             }
  1085.             if (m == 'A')
  1086.                 break;
  1087.         } while (time (NULL) < rp && CARRIER);
  1088.  
  1089.         if (m != 'A') {
  1090.             read_system_file ("FGOODBYE");
  1091.  
  1092.             hidecur();
  1093.             terminating_call();
  1094.             get_down(aftercaller_exit, 2);
  1095.         }
  1096.     }
  1097. }
  1098.  
  1099. int display_transfer(protocol, path, name, flag)
  1100. int protocol;
  1101. char *path, *name;
  1102. int flag;
  1103. {
  1104.     int fd, i, byte_sec, min, sec, nfiles, errfl;
  1105.     char filename[80], root[14], back[80];
  1106.     long fl;
  1107.     struct ffblk blk;
  1108.     struct _sys tsys;
  1109.  
  1110.     back[0] = '\0';
  1111.     fl = 0L;
  1112.     nfiles = 0;
  1113.     errfl = 0;
  1114.  
  1115.     while (get_string (name, root) != NULL) {
  1116.         sprintf (filename, "%s%s", path, root);
  1117.  
  1118.         if (findfirst (filename, &blk, 0)) {
  1119.             sprintf (filename, "%sSYSFILE.DAT", config->sys_path);
  1120.             fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  1121.  
  1122.             if (flag) {
  1123.                 i = 0;
  1124.  
  1125.                 while (read(fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  1126.                     if (usr.priv < tsys.file_priv)
  1127.                         continue;
  1128.                     if ((usr.flags & tsys.file_flags) != tsys.file_flags)
  1129.                         continue;
  1130.                     if (usr.priv < tsys.download_priv)
  1131.                         continue;
  1132.                     if((usr.flags & tsys.download_flags) != tsys.download_flags)
  1133.                         continue;
  1134.  
  1135.                     sprintf (filename, "%s%s", tsys.filepath, root);
  1136.  
  1137.                     if (findfirst(filename, &blk, 0))
  1138.                         continue;
  1139.  
  1140.                     do {
  1141.                         if ((((fl + blk.ff_fsize) / 1024) + usr.dnldl) > config->class[usr_class].max_dl && !tsys.freearea && !usr.xfer_prior) {
  1142.                             status_line (":Dnld req. would exceed limit (%s)", blk.ff_name);
  1143.                             errfl = 1;
  1144.                             read_system_file ("TODAYK");
  1145.                             break;
  1146.                         }
  1147.  
  1148.                         if (strlen (back) + strlen (blk.ff_name) + 1 < 79) {
  1149.                             if (nfiles)
  1150.                                 strcat (back, " ");
  1151.                             strcat (back, blk.ff_name);
  1152.                             fl += blk.ff_fsize;
  1153.                             nfiles++;
  1154.                             i = 1;
  1155.                         }
  1156.                     } while (!findnext (&blk));
  1157.                 }
  1158.  
  1159.                 if (!i)
  1160.                     m_print (bbstxt[B_FILE_NOT_FOUND], strupr (root));
  1161.             }
  1162.             else
  1163.                 m_print (bbstxt[B_FILE_NOT_FOUND], strupr (root));
  1164.  
  1165.             close (fd);
  1166.         }
  1167.         else
  1168.             do {
  1169.                 if ((((fl + blk.ff_fsize) / 1024) + usr.dnldl) > config->class[usr_class].max_dl && !offline_reader && !sys.freearea && !usr.xfer_prior) {
  1170.                     status_line (":Dnld req. would exceed limit (%s)", blk.ff_name);
  1171.                     errfl = 1;
  1172.                     read_system_file ("TODAYK");
  1173.                     break;
  1174.                 }
  1175.  
  1176.                 if (strlen (back) + strlen (blk.ff_name) + 1 < 79) {
  1177.                     if (nfiles)
  1178.                         strcat (back, " ");
  1179.                     strcat (back, blk.ff_name);
  1180.                     fl += blk.ff_fsize;
  1181.                     nfiles++;
  1182.                 }
  1183.             } while (!findnext (&blk));
  1184.     }
  1185.  
  1186.     if (!back[0])
  1187.         return (0);
  1188.  
  1189.     cls();
  1190.  
  1191.     m_print (bbstxt[B_FILE_MASK], strupr (back));
  1192.     m_print (bbstxt[B_LEN_MASK], fl);
  1193.  
  1194.     byte_sec = (int)(rate / 11);
  1195.     i = (int)((fl + (fl / 1024)) / byte_sec);
  1196.     min = i / 60;
  1197.     sec = i - min * 60;
  1198.  
  1199.     m_print (bbstxt[B_TOTAL_TIME], min, sec);
  1200.     if (protocol >= 10)
  1201.         display_external_protocol (protocol);
  1202.     else
  1203.         m_print (bbstxt[B_PROTOCOL], &protocols[protocol - 1][1]);
  1204.  
  1205.     if(((fl/1024) + usr.dnldl) > config->class[usr_class].max_dl && !offline_reader && !sys.freearea && !usr.xfer_prior) {
  1206.         status_line (":Dnld req. would exceed limit");
  1207.         read_system_file ("TODAYK");
  1208.         return(0);
  1209.     }
  1210.     else if (errfl && nfiles == 1) {
  1211.         read_system_file ("TODAYK");
  1212.         return(0);
  1213.     }
  1214.  
  1215.     if (min > time_remain() && !sys.freearea && !usr.xfer_prior) {
  1216.         status_line (":Dnld req. would exceed limit");
  1217.         read_system_file ("NOTIME");
  1218.         return (0);
  1219.     }
  1220.  
  1221.     strcpy (name, back);
  1222.     return (1);
  1223. }
  1224.  
  1225. void ask_for_filename(name, dotag)
  1226. char *name;
  1227. int dotag;
  1228. {
  1229.     char stringa[80];
  1230.  
  1231.     name[0] = '\0';
  1232.  
  1233.     for (;;) {
  1234.         if (dotag)
  1235.             m_print (bbstxt[B_TAG_FILE_NAME]);
  1236.         else
  1237.             m_print (bbstxt[B_DOWNLOAD_NAME]);
  1238.         input (stringa, 79);
  1239.         if (!stringa[0] || !CARRIER)
  1240.             return;
  1241.  
  1242.         if (invalid_filename(stringa) && usr.priv < SYSOP) {
  1243.             m_print (bbstxt[B_INVALID_FILENAME]);
  1244.             status_line (msgtxt[M_DL_PATH], stringa);
  1245.         }
  1246.         else
  1247.             break;
  1248.     }
  1249.  
  1250.     strcpy (name, stringa);
  1251. }
  1252.  
  1253. int invalid_filename(f)
  1254. char *f;
  1255. {
  1256.     if (strchr(f,'\\') != NULL)
  1257.         return(1);
  1258.     if (strchr(f,':') != NULL)
  1259.         return(1);
  1260.  
  1261.     return(0);
  1262. }
  1263.  
  1264. int check_upload_names (char *origname, char *path)
  1265. {
  1266.     FILE *fp;
  1267.     int found;
  1268.     char filename[80], stringa[80], *p, name[14], our_wildcard[14], their_wildcard[14];
  1269.     struct ffblk blk;
  1270.     struct _sys tsys;
  1271.     FILEIDX fidx;
  1272.  
  1273.     strcpy (name, origname);
  1274.     sprintf (filename, "%sNOCHECK.CFG", config->sys_path);
  1275.     if ((fp = fopen (filename, "rt")) != NULL) {
  1276.         while (fgets (stringa, 78, fp) != NULL) {
  1277.             stripcrlf (stringa);
  1278.             if (!stricmp (stringa, name)) {
  1279.                 fclose (fp);
  1280.                 return (0);
  1281.             }
  1282.         }
  1283.         fclose (fp);
  1284.     }
  1285.  
  1286.     if ((p = strchr (name, '.')) != NULL) {
  1287.         if (!stricmp (p, ".ZIP") || !stricmp (p, ".ARJ") || !stricmp (p, ".LZH") || !stricmp (p, ".LHA") || !stricmp (p, ".ARC"))
  1288.             strcpy (p, ".*");
  1289.         else if (!stricmp (p, ".GIF") || !stricmp (p, ".JPG") || !stricmp (p, ".ZOO"))
  1290.             strcpy (p, ".*");
  1291.     }
  1292.  
  1293.     sprintf (filename, "%s%s", sys.uppath, name);
  1294.     if (!findfirst (filename, &blk, 0)) {
  1295.         m_print (bbstxt[B_ALREADY_HAVE], strupr (origname), sys.file_num, sys.file_name);
  1296.         return (-1);
  1297.     }
  1298.  
  1299. //   sprintf (filename, "%sSYSFILE.DAT", config->sys_path);
  1300. //   if ((fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE)) == -1)
  1301. //      return (0);
  1302.  
  1303.     found = 0;
  1304.     prep_match (name, their_wildcard);
  1305.     if ((fp = sh_fopen ("FILES.IDX", "rb", SH_DENYNONE)) != NULL) {
  1306.         while (fread (&fidx, sizeof (FILEIDX), 1, fp) == 1) {
  1307.             prep_match (fidx.name, our_wildcard);
  1308.             if (!match (our_wildcard, their_wildcard)) {
  1309.                 found = 1;
  1310.                 if (read_system2 (fidx.area, 2, &tsys))
  1311.                     m_print (bbstxt[B_ALREADY_HAVE], name, tsys.file_num, tsys.file_name);
  1312.                 break;
  1313.             }
  1314.         }
  1315.         fclose (fp);
  1316.     }
  1317.  
  1318.     if (!found) {
  1319.         prep_match (name, their_wildcard);
  1320.         if ((fp = sh_fopen ("CDROM.IDX", "rb", SH_DENYNONE)) != NULL) {
  1321.             while (fread (&fidx, sizeof (FILEIDX), 1, fp) == 1) {
  1322.                 prep_match (fidx.name, our_wildcard);
  1323.                 if (!match (our_wildcard, their_wildcard)) {
  1324.                     found = 1;
  1325.                     if (read_system2 (fidx.area, 2, &tsys))
  1326.                         m_print (bbstxt[B_ALREADY_HAVE], name, tsys.file_num, tsys.file_name);
  1327.                     break;
  1328.                 }
  1329.             }
  1330.             fclose (fp);
  1331.         }
  1332.     }
  1333. /*
  1334.     while (read (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  1335.         if (!stricmp (tsys.filepath, path))
  1336.             continue;
  1337.         sprintf (filename, "%s%s", tsys.filepath, name);
  1338.         if (!findfirst (filename, &blk, 0)) {
  1339.             m_print (bbstxt[B_ALREADY_HAVE], name, tsys.file_num, tsys.file_name);
  1340.             close (fd);
  1341.             return (-1);
  1342.         }
  1343.     }
  1344. */
  1345.  
  1346. //   close (fd);
  1347.     return (0);
  1348. }
  1349.  
  1350. void ask_file_description (char *name)
  1351. {
  1352.    FILE *fp;
  1353.    char stringa[80], filename[80];
  1354.  
  1355.    m_print (bbstxt[B_DESCRIBE], strupr (name));
  1356.    input (stringa,54);
  1357.    if (!CARRIER || !stringa[0])
  1358.       return;
  1359.  
  1360.     sprintf (filename, "DESC%d.TMP", config->line_offset);
  1361.    fp = fopen (filename, "at");
  1362.    fprintf (fp, "%-12s %s\n", name, stringa);
  1363.    fclose (fp);
  1364. }
  1365.  
  1366. int check_file_description (char *name, char *uppath)
  1367. {
  1368.    FILE *fp;
  1369.    char *p, stringa[80], filename[80];
  1370.  
  1371.     sprintf (filename, "DESC%d.TMP", config->line_offset);
  1372.    if ((fp = fopen (filename, "rt")) == NULL)
  1373.         return (0);
  1374.  
  1375.    while (fgets (stringa, 78, fp) != NULL) {
  1376.       stripcrlf (stringa);
  1377.       p = strchr (stringa, ' ');
  1378.       *p++ = '\0';
  1379.  
  1380.       if (!stricmp (stringa, name)) {
  1381.             p = strbtrim (p);
  1382.          sprintf (filename, "%sFILES.BBS", uppath);
  1383.  
  1384.          fp = fopen (filename, "at");
  1385.          sprintf (filename, "%c  0%c ", config->dl_counter_limits[0], config->dl_counter_limits[1]);
  1386.          fprintf (fp,"%-12s %s%s\n", strupr (name), config->keep_dl_count ? filename : "", p);
  1387.          if (config->put_uploader)
  1388.             fprintf (fp, bbstxt[B_UPLOADER_NAME], usr.name);
  1389.          fclose(fp);
  1390.  
  1391.          return (-1);
  1392.       }
  1393.    }
  1394.  
  1395.    fclose (fp);
  1396.    return (0);
  1397. }
  1398.  
  1399. void upload_file (char *st, char pr)
  1400. {
  1401.    FILE *xferinfo, *fp;
  1402.    int i, protocol;
  1403.    char filename[80], path[80], stringa[80], name[20], ext[5], *file, doupload;
  1404.    long fpos, start_upload;
  1405.    struct ffblk blk;
  1406.    PROTOCOL prot;
  1407.  
  1408. #if defined (__OCC__) || defined (__TCPIP__)
  1409.    if (tcpip && usr.priv < SYSOP) {
  1410.       m_print ("\n Sorry, file transfer not available on TCP/IP\n");
  1411.       press_enter ();
  1412.       return;
  1413.    }
  1414. #endif
  1415.  
  1416.     if (pr == 0 || pr == -1) {
  1417.       if (pr == 0)
  1418.          read_system_file ("PREUPLD");
  1419.  
  1420.       if ((protocol = selprot ()) == 0)
  1421.          return;
  1422.    }
  1423.    else
  1424.       protocol = pr;
  1425.  
  1426.    name[0] = '\0';
  1427.  
  1428.    if (st == NULL || !st[0])
  1429.       strcpy (path, sys.uppath);
  1430.    else {
  1431.       fnsplit (st, filename, stringa, name, ext);
  1432.       strcat (filename, stringa);
  1433.       strcat (name, ext);
  1434.  
  1435.       if (filename[0])
  1436.          strcpy (path, filename);
  1437.       else
  1438.          strcpy (path, sys.uppath);
  1439.    }
  1440.  
  1441.    if (zfree (path) <= config->ul_free_space) {
  1442.       read_system_file ("ULSPACE");
  1443.         return;
  1444.    }
  1445.  
  1446.    if (protocol >= 10) {
  1447.       sprintf (filename, "%sPROTOCOL.DAT", config->sys_path);
  1448.       i = sh_open (filename, O_RDONLY|O_BINARY, SH_DENYWR, S_IREAD|S_IWRITE);
  1449.       lseek (i, (long)(protocol - 10) * sizeof (PROTOCOL), SEEK_SET);
  1450.       read (i, &prot, sizeof (PROTOCOL));
  1451.         close (i);
  1452.    }
  1453.  
  1454.    if (!no_precheck && !name[0]) {
  1455.       if (!get_command_word (name, 14)) {
  1456.          m_print (bbstxt[B_UPLOAD_NAME]);
  1457.          input (name, 14);
  1458.          if (!name[0] || !CARRIER)
  1459.             return;
  1460.       }
  1461.  
  1462.       if ((i = check_upload_names (name, "")) == 0)
  1463.          ask_file_description (name);
  1464.       doupload = i ? 0 : 1;
  1465.  
  1466.       if ((protocol >= 10 && prot.batch) || (protocol != 1 && protocol != 2))
  1467.          for (;;) {
  1468.             m_print (bbstxt[B_UPLOAD_NAME]);
  1469.             input (name, 14);
  1470.             if (!name[0] || !CARRIER)
  1471.                break;
  1472.  
  1473.             if ((i = check_upload_names (name, "")) == 0)
  1474.                ask_file_description (name);
  1475.             doupload += i ? 0 : 1;
  1476.          }
  1477.  
  1478.         if (!doupload || !CARRIER)
  1479.          return;
  1480.    }
  1481.    else if (!name[0]) {
  1482.       if ((protocol >= 10 && !prot.batch) || protocol == 1 || protocol == 2) {
  1483.          if (!get_command_word (name, 14)) {
  1484.             m_print (bbstxt[B_UPLOAD_NAME]);
  1485.                 input (name, 14);
  1486.                 if (!name[0] || !CARRIER)
  1487.                     return;
  1488.             }
  1489.         }
  1490.     }
  1491.  
  1492.     if (pr == 0 || pr == -1) {
  1493.         if (protocol >= 10)
  1494.             m_print (bbstxt[B_READY_TO_RECEIVE], prot.name);
  1495.         else
  1496.             m_print (bbstxt[B_READY_TO_RECEIVE], &protocols[protocol-1][1]);
  1497.         m_print2 (bbstxt[B_CTRLX_ABORT]);
  1498.     }
  1499.  
  1500.     start_upload = time (NULL);
  1501.  
  1502.     if (local_mode) {
  1503.         sysop_error ();
  1504.         i = 0;
  1505.         file = NULL;
  1506.         goto abort_xfer;
  1507.     }
  1508.  
  1509.  
  1510.     if (protocol == 1 || protocol == 2 || protocol == 3 || protocol == 6) {
  1511.         timer (50);
  1512.  
  1513.         sprintf (filename, "XFER%d", line_offset);
  1514.         xferinfo = fopen (filename, "w+t");
  1515.  
  1516.         i = 0;
  1517.         file = NULL;
  1518.  
  1519.         switch (protocol) {
  1520.             case 1:
  1521.                 who_is_he = 0;
  1522.                 overwrite = 0;
  1523.                 file = receive (path, name, 'X');
  1524.                 if (file != NULL)
  1525.                     fprintf (xferinfo, "%s\n", file);
  1526.                 break;
  1527.  
  1528.             case 2:
  1529.                 who_is_he = 0;
  1530.                 overwrite = 0;
  1531.                 file = receive (path, name, 'Y');
  1532.                 if (file != NULL)
  1533.                     fprintf (xferinfo, "%s\n", file);
  1534.                 break;
  1535.  
  1536.             case 3:
  1537.                 i = get_Zmodem (path, xferinfo);
  1538.                 break;
  1539.  
  1540.             case 6:
  1541.                 i = 0;
  1542.                 do {
  1543.                     who_is_he = 0;
  1544.                     overwrite = 0;
  1545.                     file = receive (path, NULL, 'S');
  1546.                     if (file != NULL) {
  1547.                         fprintf (xferinfo, "%s\n", file);
  1548.                         i++;
  1549.                     }
  1550.                 } while (file != NULL);
  1551.                 break;
  1552.  
  1553.         }
  1554.  
  1555. abort_xfer:
  1556.         if (!CARRIER) {
  1557.             fclose(xferinfo);
  1558.             sprintf (filename, "XFER%d", line_offset);
  1559.             unlink (filename);
  1560.             sprintf (filename, "DESC%d.TMP", config->line_offset);
  1561.             unlink (filename);
  1562.             return;
  1563.         }
  1564.  
  1565.         wactiv (mainview);
  1566.  
  1567.         allowed += (int)((time(NULL) - start_upload) / 60);
  1568.  
  1569.         CLEAR_INBOUND();
  1570.         if (i || file != NULL) {
  1571.             m_print(bbstxt[B_TRANSFER_OK]);
  1572.             timer (10);
  1573.         }
  1574.         else {
  1575.             m_print(bbstxt[B_TRANSFER_ABORT]);
  1576.             fclose(xferinfo);
  1577.             sprintf (filename, "XFER%d", line_offset);
  1578.             unlink (filename);
  1579.             sprintf (filename, "DESC%d.TMP", config->line_offset);
  1580.             unlink (filename);
  1581.             press_enter();
  1582.             return;
  1583.         }
  1584.  
  1585.         // Chiede le descrizioni dei files mandati
  1586.         if (!no_description) {
  1587.             rewind (xferinfo);
  1588.             fpos = filelength(fileno (xferinfo));
  1589.  
  1590.             while (ftell(xferinfo) < fpos) {
  1591.                 fgets(filename,78,xferinfo);
  1592.                 filename[strlen(filename) - 1] = '\0';
  1593.  
  1594.                 fnsplit(filename,NULL,NULL,name,ext);
  1595.                 strcat(name,ext);
  1596.  
  1597.                 sprintf (filename, "%s%s", path, name);
  1598.                 if (!dexists (filename))
  1599.                     continue;
  1600.  
  1601.                 if (!check_file_description (name, path)) {
  1602.                     do {
  1603.                         m_print(bbstxt[B_DESCRIBE],strupr(name));
  1604.                         input(stringa,54);
  1605.                         if (!CARRIER) {
  1606.                             fclose(xferinfo);
  1607.                             sprintf (filename, "XFER%d", line_offset);
  1608.                             unlink (filename);
  1609.                             sprintf (filename, "DESC%d.TMP", config->line_offset);
  1610.                             unlink (filename);
  1611.                             return;
  1612.                         }
  1613.                     } while (strlen(stringa) < 5);
  1614.  
  1615.                     sprintf(filename,"%sFILES.BBS",path);
  1616.                     fp = fopen(filename,"at");
  1617.                     sprintf (filename, "%c  0%c ", config->dl_counter_limits[0], config->dl_counter_limits[1]);
  1618.                     fprintf(fp,"%-12s %s%s\n", name, config->keep_dl_count ? filename : "", stringa);
  1619.                     if (config->put_uploader)
  1620.                         fprintf (fp, bbstxt[B_UPLOADER_NAME], usr.name);
  1621.                     fclose(fp);
  1622.                 }
  1623.             }
  1624.         }
  1625.  
  1626.         // Effettua il controllo dei files ed eventualmente cambia le
  1627.         // descrizioni inviate dall'uploader
  1628.         if (!no_check) {
  1629.             check_uploads (xferinfo, path);
  1630.             m_print(bbstxt[B_THANKS],usr.name);
  1631.         }
  1632.  
  1633.         // Aggiorna i contatori dell'utente con i kbytes mandati e il numero
  1634.         // di files totali.
  1635.         rewind (xferinfo);
  1636.         fpos = filelength (fileno (xferinfo));
  1637.  
  1638.         while (ftell (xferinfo) < fpos) {
  1639.             fgets(filename,78,xferinfo);
  1640.             filename[strlen(filename) - 1] = '\0';
  1641.  
  1642.             fnsplit(filename,NULL,NULL,name,ext);
  1643.             strcat(name,ext);
  1644.  
  1645.             sprintf (filename,"%s\\%s",path,name);
  1646.             if (!findfirst (filename, &blk, 0)) {
  1647.                 usr.upld += (int)(blk.ff_fsize / 1024L) + 1;
  1648.                 usr.n_upld++;
  1649.  
  1650.                 if (function_active == 3)
  1651.                     f3_status ();
  1652.             }
  1653.         }
  1654.  
  1655.         fclose(xferinfo);
  1656.     }
  1657.  
  1658.     else if (protocol >= 10)
  1659.         general_external_protocol (prot.batch ? NULL : name, path, protocol, 0, 0);
  1660.  
  1661.     sprintf (filename, "XFER%d", line_offset);
  1662.     unlink (filename);
  1663.     sprintf (filename, "DESC%d.TMP", config->line_offset);
  1664.    unlink (filename);
  1665. }
  1666.  
  1667. int selprot (void)
  1668. {
  1669.    int fd, i, cmdpos = 0;
  1670.    char c, stringa[4], extcmd[50], filename[50];
  1671.    PROTOCOL prot;
  1672.  
  1673.    cmdpos = 0;
  1674.    sprintf (filename, "%sPROTOCOL.DAT", config->sys_path);
  1675.    fd = sh_open (filename, O_RDONLY|O_BINARY, SH_DENYNONE, S_IREAD|S_IWRITE);
  1676.    if (fd != -1) {
  1677.       while (read (fd, &prot, sizeof (PROTOCOL)) == sizeof (PROTOCOL)) {
  1678.          if (prot.active)
  1679.             extcmd[cmdpos++] = prot.hotkey;
  1680.          else
  1681.             extcmd[cmdpos++] = ' ';
  1682.       }
  1683.       close (fd);
  1684.    }
  1685.    extcmd[cmdpos] = '\0';
  1686.  
  1687.    for (;;) {
  1688.         if ((c=get_command_letter ()) == '\0') {
  1689.          if (!usr.protocol) {
  1690.             if (!read_system_file ("XFERPROT")) {
  1691.                m_print (bbstxt[B_PROTOCOLS]);
  1692.                if (config->prot_xmodem || no_external)
  1693.                   m_print (bbstxt[B_PROTOCOL_FORMAT], protocols[0][0], &protocols[0][1]);
  1694.                if (config->prot_1kxmodem || no_external)
  1695.                   m_print (bbstxt[B_PROTOCOL_FORMAT], protocols[1][0], &protocols[1][1]);
  1696.                if (config->prot_zmodem || no_external)
  1697.                         m_print (bbstxt[B_PROTOCOL_FORMAT], protocols[2][0], &protocols[2][1]);
  1698.                if (config->prot_sealink || no_external)
  1699.                   m_print (bbstxt[B_PROTOCOL_FORMAT], protocols[5][0], &protocols[5][1]);
  1700.  
  1701.                if (!no_external) {
  1702.                   sprintf (filename, "%sPROTOCOL.DAT", config->sys_path);
  1703.                   fd = sh_open (filename, O_RDONLY|O_BINARY, SH_DENYWR, S_IREAD|S_IWRITE);
  1704.                   if (fd != -1) {
  1705.                      while (read (fd, &prot, sizeof (PROTOCOL)) == sizeof (PROTOCOL)) {
  1706.                         if (prot.active)
  1707.                            m_print (bbstxt[B_PROTOCOL_FORMAT], prot.hotkey, prot.name);
  1708.                      }
  1709.                      close (fd);
  1710.                   }
  1711.                }
  1712.  
  1713.                if (exist_system_file ("XFERHELP"))
  1714.                   m_print (bbstxt[B_PROTOCOL_FORMAT], bbstxt[B_HELP][0], &bbstxt[B_HELP][1]);
  1715.                m_print (bbstxt[B_SELECT_PROT]);
  1716.             }
  1717.  
  1718.             if (usr.hotkey) {
  1719.                cmd_input (stringa, 1);
  1720.                m_print (bbstxt[B_ONE_CR]);
  1721.             }
  1722.             else
  1723.                     input (stringa, 1);
  1724.             c = stringa[0];
  1725.             if (c == '\0' || c == '\r' || !CARRIER)
  1726.                return (0);
  1727.          }
  1728.          else
  1729.             c = usr.protocol;
  1730.       }
  1731.  
  1732.         if (!no_external) {
  1733.          for (i = 0; i < cmdpos; i++)
  1734.             if (toupper (c) == toupper (extcmd[i]))
  1735.                break;
  1736.          if (i < cmdpos)
  1737.             return (10 + i);
  1738.       }
  1739.  
  1740.       switch (toupper (c)) {
  1741.          case 'X':
  1742.             if (config->prot_xmodem || no_external)
  1743.                return (1);
  1744.             break;
  1745.          case '1':
  1746.             if (config->prot_1kxmodem || no_external)
  1747.                return (2);
  1748.             break;
  1749.          case 'Z':
  1750.             if (config->prot_zmodem || no_external)
  1751.                return (3);
  1752.             break;
  1753.          case 'S':
  1754.             if (config->prot_sealink || no_external)
  1755.                return (6);
  1756.             break;
  1757.          case '?':
  1758.                 read_system_file ("XFERHELP");
  1759.             break;
  1760.          default:
  1761.             if (c == '\0')
  1762.                return (0);
  1763.             usr.protocol = '\0';
  1764.             break;
  1765.       }
  1766.    }
  1767. }
  1768.  
  1769. void SendACK()
  1770. {
  1771.    char temp[20];
  1772.  
  1773.    if ((!recv_ackless) || (block_number == 0)) {
  1774.       SENDBYTE(ACK);
  1775.       if (sliding)
  1776.       {
  1777.          SENDBYTE((unsigned char )block_number);
  1778.          SENDBYTE((unsigned char )(~(block_number)));
  1779.       }
  1780.    }
  1781.  
  1782.    sprintf (temp, "%5d", block_number);
  1783.    if (caller || emulator)
  1784.       wgotoxy (1, 1);
  1785.    else
  1786.       wgotoxy (10, 1);
  1787.    wputs (temp);
  1788.  
  1789.    errs = 0;
  1790. }
  1791.  
  1792. void SendNAK()
  1793. {
  1794.    int i;
  1795.    long t1;
  1796.  
  1797.    errs++;
  1798.    real_errs++;
  1799.    if (errs > 6)
  1800.       return;
  1801.  
  1802.     if(++did_nak > 8)
  1803.       recv_ackless = 0;
  1804.  
  1805.    CLEAR_INBOUND();
  1806.  
  1807.    if(!recv_ackless) {
  1808.       t1 = timerset(3000);
  1809.       if((base_block != block_number) || (errs > 1))
  1810.          do {
  1811.             i = TIMED_READ(1);
  1812.             if (!CARRIER)
  1813.                return;
  1814.             if(timeup(t1))
  1815.                break;
  1816.             time_release();
  1817.          } while(i >= 0);
  1818.    }
  1819.  
  1820.    if(block_number > base_block)
  1821.       SENDBYTE(NAK);
  1822.    else {
  1823.       if ((errs < 5) && (!do_chksum))
  1824.          SENDBYTE('C');
  1825.       else {
  1826.          do_chksum = 1;
  1827.          SENDBYTE(NAK);
  1828.         }
  1829.    }
  1830.  
  1831.    if(sliding) {
  1832.       SENDBYTE((unsigned char )block_number);
  1833.       SENDBYTE((unsigned char )(~(block_number)));
  1834.    }
  1835. }
  1836.  
  1837. void getblock()
  1838. {
  1839.         register int i;
  1840.         char *sptr, rbuffer[1024];
  1841.         unsigned int crc;
  1842.         int in_char, is_resend, blockerr;
  1843.         unsigned char chksum;
  1844.         struct zero_block *testa;
  1845.  
  1846.         blockerr=0;
  1847.         is_resend=0;
  1848.         chksum='\0';
  1849.         testa = (struct zero_block *)&rbuffer[0];
  1850.  
  1851.         in_char = TIMED_READ(5);
  1852.         if(in_char != (block_number & 0xff)) {
  1853.                 if(in_char < (int)block_number)
  1854.                         is_resend = 1;
  1855.                 else if((block_number) || (in_char != 1))
  1856.                         blockerr++;
  1857.                 else
  1858.                         block_number = 1;
  1859.         }
  1860.  
  1861.         i = TIMED_READ(5);
  1862.         if((i & 0xff) != ((~in_char) & 0xff))
  1863.                      blockerr++;
  1864.  
  1865.         for(sptr = rbuffer,i=0;i<block_size;i++,sptr++) {
  1866.                 in_char = TIMED_READ(5);
  1867.                 if(in_char < 0) {
  1868.                         if(CARRIER) {
  1869.                                 SendNAK();
  1870.                         }
  1871.                         return;
  1872.                      }
  1873.                 sptr[0] = (char )in_char;
  1874.         }
  1875.  
  1876.         if(do_chksum) {
  1877.                 for(sptr = rbuffer,i=0;i<block_size;i++,sptr++)
  1878.                         chksum += sptr[0];
  1879.  
  1880.                 if(TIMED_READ(5) != chksum) {
  1881.                         blockerr++;
  1882.                 }
  1883.         }
  1884.         else {
  1885.                 int lsb, msb;
  1886.  
  1887.                 for(sptr = rbuffer,i=crc=0;i<block_size;i++,sptr++)
  1888.                         crc = xcrc(crc,(byte )sptr[0]);
  1889.  
  1890.                 msb = TIMED_READ(5);
  1891.                 lsb = TIMED_READ(5);
  1892.                 if((lsb < 0) || (msb < 0)) {
  1893.                         if(!block_number)
  1894.                                 sliding = 0;
  1895.                         blockerr++;
  1896.                 }
  1897.                 else if(((msb << 8) | lsb) != crc) {
  1898.                                 blockerr++;
  1899.                 }
  1900.         }
  1901.  
  1902.         if (blockerr)
  1903.                 SendNAK();
  1904.         else {
  1905.                 SendACK();
  1906.  
  1907.                      if(is_resend)
  1908.                         return;
  1909.  
  1910.                 if(block_number) {
  1911.                         if(block_number < fsize1)
  1912.                                 fwrite(rbuffer,block_size,1,Infile);
  1913.                         else if (block_number == fsize1)
  1914.                                 fwrite(rbuffer,fsize2,1,Infile);
  1915.                 }
  1916.                 else if (first_block && !may_be_seadog)
  1917.                 {
  1918.                         sptr = &(testa->name[0]);
  1919.                         if(sptr[0])
  1920.                         {
  1921.                                 sprintf(final_name,"%s%s",_fpath,sptr);
  1922.                                 sptr = final_name;
  1923.                                 fancy_str(sptr);
  1924.                                 i = strlen(sptr)-1;
  1925.                                 if((isdigit(sptr[i])) && (sptr[i-1]=='o') && (sptr[i-2]=='m') && (sptr[i-3]=='.'))
  1926.                                         got_arcmail=1;
  1927. //                                wgotoxy (0, 13);
  1928. //                                wclreol ();
  1929. //                                wputs (final_name);
  1930.                         }
  1931.                 }
  1932.                 else if (!first_block) {
  1933.                                 sptr = &(testa->name[0]);
  1934.                         if (netmail)
  1935.                                 invent_pkt_name(sptr);
  1936.  
  1937.                         for(i=0;((sptr[i]) && (i < 17));i++)
  1938.                                 if (sptr[i]<=' ')
  1939.                                         sptr[i]='\0';
  1940.  
  1941.                         if(sptr[0])
  1942.                                 {
  1943.                                 sprintf(final_name,"%s%s",_fpath,sptr);
  1944.                                 sptr = final_name;
  1945.                                 fancy_str(sptr);
  1946.                                 i = strlen(sptr)-1;
  1947.                                 if((isdigit(sptr[i])) && (sptr[i-1]=='o') && (sptr[i-2]=='m') && (sptr[i-3]=='.'))
  1948.                                         got_arcmail=1;
  1949. //                                wgotoxy (0, 13);
  1950. //                                wclreol ();
  1951. //                                wputs (final_name);
  1952.                         }
  1953.                         else
  1954.                                 status_line(msgtxt[M_GRUNGED_HEADER]);
  1955.  
  1956.                         if(testa->size)
  1957.                         {
  1958.                                 fsize1 = (int)(testa->size / 128L);
  1959.                                 if((testa->size % 128) != 0) {
  1960.                                         fsize2 = (int)(testa->size % 128);
  1961.                                         ++fsize1;
  1962.                                 }
  1963.                         }
  1964.  
  1965.                         if((rate >= 9600) && testa->noacks && !no_overdrive)
  1966.                                 recv_ackless = 1;
  1967.  
  1968.                                 first_block = 0;
  1969.                 }
  1970.  
  1971.                 block_number++;
  1972.         }
  1973. }
  1974.  
  1975. struct zero_block1 {
  1976.    long size;
  1977.     long time;
  1978.    char name[17];
  1979.    char moi[15];
  1980.    char noacks;
  1981. };
  1982.  
  1983. char *receive (char *fpath, char *fname, char protocol)
  1984. {
  1985.    char tmpname[80], announced;
  1986.    int in_char, i, wh = -1;
  1987.    long t1;
  1988.  
  1989.    announced = 0;
  1990.    did_nak = 0;
  1991.    wh = -1;
  1992.  
  1993.    if (protocol == 'F') {
  1994.       may_be_seadog = 1;
  1995.       netmail = 0;
  1996.       protocol = 'S';
  1997.       first_block = 0;
  1998.    }
  1999.    else if (protocol == 'B') {
  2000.       protocol = 'S';
  2001.       may_be_seadog = 1;
  2002.       netmail = 1;
  2003.         first_block = 1;
  2004.    }
  2005.    else if (protocol == 'T') {
  2006.       protocol = 'S';
  2007.       may_be_seadog = 1;
  2008.       netmail = 0;
  2009.       first_block = 1;
  2010.    }
  2011.    else {
  2012.         may_be_seadog = 0;
  2013.       netmail = 0;
  2014.       first_block = 0;
  2015.    }
  2016.  
  2017.    _BRK_DISABLE ();
  2018.    XON_DISABLE ();
  2019.  
  2020.    fsize1 = 32767;
  2021.    if (fname) {
  2022.       for (in_char = 0; fname[in_char]; in_char++) {
  2023.          if ((fname[in_char] == '*') || (fname[in_char] == '?'))
  2024.             fname[0] = '\0';
  2025.       }
  2026.    }
  2027.  
  2028.    _fpath = fpath;
  2029.    sliding = 1;
  2030.    base_block = 0;
  2031.    do_chksum = 0;
  2032.    errs = 0;
  2033.    block_size = 128;
  2034.    fsize2 = 128;
  2035.  
  2036.    switch (protocol) {
  2037.       case 'X' :
  2038.             base_block = 1;
  2039.          sliding = 0;
  2040.          break;
  2041.       case 'Y' :
  2042.          base_block=1;
  2043.          sliding=0;
  2044.          fsize2=block_size=1024;
  2045.          break;
  2046.       case 'S' :
  2047.             break;
  2048.       case 'T' :
  2049.          break;
  2050.       case 'M' :
  2051.          base_block=1;
  2052.          sliding=0;
  2053.          break;
  2054.       default  :
  2055.          return NULL;
  2056.    }
  2057.  
  2058.    block_number = base_block;
  2059.  
  2060.     sprintf(tmpname,"%s_TMP%d_.$$$",fpath,line_offset);
  2061.    sprintf(final_name,"%s%s",fpath,(fname && fname[0]) ? fname:"UNKNOWN.$$$");
  2062.  
  2063.    if (caller || emulator) {
  2064.       wh = wopen (16, 0, 19, 79, 1, WHITE|_RED, WHITE|_RED);
  2065.       wactiv (wh);
  2066.       wtitle (" Transfer Status ", TLEFT, WHITE|_RED);
  2067.       wgotoxy (0, 1);
  2068.    }
  2069.    else {
  2070.       wfill (9, 1, 10, 77, ' ', WHITE|_BLACK);
  2071.       wgotoxy (9, 1);
  2072.    }
  2073.  
  2074.    Infile = fopen (tmpname, "wb");
  2075.    if (Infile == NULL) {
  2076.       if ((caller || emulator) && wh != -1)
  2077.          wclose ();
  2078.       return (NULL);
  2079.    }
  2080.    if (isatty (fileno (Infile))) {
  2081.       if ((caller || emulator) && wh != -1)
  2082.             wclose ();
  2083.       fclose (Infile);
  2084.       unlink (tmpname);
  2085.       return (NULL);
  2086.    }
  2087.  
  2088.    throughput (0, 0L);
  2089.  
  2090.    SendNAK ();
  2091.  
  2092.    t1 = timerset(300);
  2093.    real_errs = 0;
  2094.  
  2095. loop_top:
  2096.    in_char = TIMED_READ (4);
  2097.  
  2098.    switch (in_char) {
  2099.       case SOH:
  2100.          block_size = 128;
  2101.          getblock ();
  2102.          if (!announced) {
  2103.             status_line (" %s-%c %s", msgtxt[M_RECEIVING], protocol, final_name);
  2104.             if (caller || emulator)
  2105.                wgotoxy (0, 1);
  2106.             else
  2107.                wgotoxy (9, 1);
  2108.                 wputs (msgtxt[M_RECEIVING]);
  2109.             wputc ('-');
  2110.             wputc (protocol);
  2111.             wputc (' ');
  2112.             wputs (final_name);
  2113.             announced = 1;
  2114.          }
  2115.          t1 = timerset(300);
  2116.          break;
  2117.         case STX:
  2118.          block_size=1024;
  2119.          getblock();
  2120.          if (!announced) {
  2121.             status_line(" %s-%c %s",msgtxt[M_RECEIVING],protocol,final_name);
  2122.             if (caller || emulator)
  2123.                wgotoxy (0, 1);
  2124.             else
  2125.                wgotoxy (9, 1);
  2126.             wputs (msgtxt[M_RECEIVING]);
  2127.             wputc ('-');
  2128.             wputc (protocol);
  2129.             wputc (' ');
  2130.             wputs (final_name);
  2131.             announced = 1;
  2132.          }
  2133.          t1 = timerset(300);
  2134.          break;
  2135.       case SYN:
  2136.          do_chksum = 1;
  2137.          getblock();
  2138.          do_chksum = 0;
  2139.          t1 = timerset(300);
  2140.          break;
  2141.       case CAN:
  2142.          if (TIMED_READ (2) == CAN)
  2143.                 goto fubar;
  2144.          t1 = timerset (300);
  2145.          break;
  2146.       case EOT:
  2147.          t1 = timerset (20);
  2148.          while(!timeup (t1)) {
  2149.             TIMED_READ (1);
  2150.             time_release ();
  2151.          }
  2152.             if (block_number || protocol == 'S')
  2153.             goto done;
  2154.          else
  2155.             goto fubar;
  2156.       default:
  2157.          if(!CARRIER) {
  2158.             if ((caller || emulator) && wh != -1) {
  2159.                wactiv (wh);
  2160.                wclose ();
  2161.             }
  2162.             fclose (Infile);
  2163.             unlink (tmpname);
  2164.             return (NULL);
  2165.          }
  2166.  
  2167.          if(timeup(t1)) {
  2168.             SendNAK();
  2169.             t1 = timerset(300);
  2170.          }
  2171.          break;
  2172.    }
  2173.  
  2174.    if (errs > 14)
  2175.       goto fubar;
  2176.  
  2177.    goto loop_top;
  2178.  
  2179. fubar:
  2180.    if (Infile) {
  2181.       fclose (Infile);
  2182.       unlink (tmpname);
  2183.    }
  2184.  
  2185.    CLEAR_OUTBOUND();
  2186.  
  2187.    if ((caller || emulator) && wh != -1) {
  2188.       wactiv(wh);
  2189.       wclose();
  2190.       wh = -1;
  2191.    }
  2192.  
  2193.    send_can ();
  2194.    status_line ("!File not received");
  2195.  
  2196.    CLEAR_INBOUND ();
  2197.    return (NULL);
  2198.  
  2199. done:
  2200.    recv_ackless = 0;
  2201.    SendACK ();
  2202.  
  2203.    if (Infile) {
  2204.       int j, k;
  2205.       struct ffblk dta;
  2206.  
  2207.       fclose (Infile);
  2208.  
  2209.       if (!block_number && protocol == 'S')
  2210.          return (NULL);
  2211.  
  2212.       i = strlen (tmpname) - 1;
  2213.         j = strlen (final_name) - 1;
  2214.  
  2215.       if (tmpname[i] == '.')
  2216.          tmpname[i] = '\0';
  2217.       if (final_name[j] == '.') {
  2218.          final_name[j] = '\0';
  2219.          j--;
  2220.       }
  2221.  
  2222.       i = 0;
  2223.       k = is_arcmail (final_name, j);
  2224.       if ((!overwrite) || k) {
  2225.          while (rename (tmpname, final_name)) {
  2226.             if (isdigit (final_name[j]))
  2227.                final_name[j]++;
  2228.             else
  2229.                final_name[j] = '0';
  2230.             if (!isdigit (final_name[j]))
  2231.                return (final_name);
  2232.             i = 1;
  2233.          }
  2234.       }
  2235.       else {
  2236.          unlink (final_name);
  2237.          rename (tmpname, final_name);
  2238.       }
  2239.       if (i)
  2240.          status_line ("+Dupe file renamed: %s", final_name);
  2241.  
  2242.       if (!findfirst (final_name, &dta, 0)) {
  2243.          if (real_errs > 4)
  2244.             status_line ("+Corrected %d errors in %d blocks", real_errs, fsize1);
  2245.          throughput (1, dta.ff_fsize);
  2246.          status_line ("+UL-%c %s",protocol,strupr(final_name));
  2247.  
  2248.             if ((caller || emulator) && wh != -1) {
  2249.             wactiv (wh);
  2250.             wclose ();
  2251.             wh = -1;
  2252.          }
  2253.  
  2254.          strcpy (final_name, dta.ff_name);
  2255.          return (final_name);
  2256.       }
  2257.    }
  2258.  
  2259.    if ((caller || emulator) && wh != -1) {
  2260.       wactiv (wh);
  2261.       wclose ();
  2262.    }
  2263.  
  2264.    return (NULL);
  2265. }
  2266.  
  2267. int fsend(fname,protocol)
  2268. char *fname, protocol;
  2269. {
  2270.    register int i, j;
  2271.    char *b, rbuffer[1024], temps[80];
  2272.    int in_char, in_char1, base, head;
  2273.    int win_size, full_window, ackerr, wh = -1;
  2274.    FILE *fp;
  2275.    long block_timer, ackblock, blknum, last_block, temp;
  2276.    struct stat st_stat;
  2277.    struct ffblk dta;
  2278.    struct zero_block1 *testa;
  2279.  
  2280.    if(protocol == 'F') {
  2281.       protocol = 'S';
  2282.       may_be_seadog = 1;
  2283.     }
  2284.    else if(protocol == 'B') {
  2285.       protocol = 'S';
  2286.       may_be_seadog = 1;
  2287.    }
  2288.    else
  2289.       may_be_seadog = 0;
  2290.  
  2291.    fp = NULL;
  2292.    sliding = 0;
  2293.    ackblock = -1;
  2294.    do_chksum = 0;
  2295.    errs = 0;
  2296.    ackerr = 0;
  2297.    real_errs = 0;
  2298.    wh = -1;
  2299.  
  2300.    full_window = (int)(rate / 400);
  2301.  
  2302.    if (small_window && full_window > 6)
  2303.       full_window = 6;
  2304.  
  2305.    _BRK_DISABLE ();
  2306.    XON_DISABLE ();
  2307.  
  2308.    if ((!fname) || (!fname[0])) {
  2309.  
  2310.       for (i = 0; i < 5; i++) {
  2311.          switch(in_char = TIMED_READ (5)) {
  2312.             case 'C':
  2313.             case NAK:
  2314.             case CAN:
  2315.                SENDBYTE(EOT);
  2316.                break;
  2317.  
  2318.                 case TSYNC:
  2319.                return(TSYNC);
  2320.  
  2321.             default:
  2322.                if (in_char < ' ')
  2323.                   return(0);
  2324.          }
  2325.       }
  2326.       return(0);
  2327.    }
  2328.  
  2329.    strlwr(fname);
  2330.  
  2331.    if(!findfirst(fname,&dta,0))
  2332.       fp = fopen(fname,"rb");
  2333.    else {
  2334.       send_can();
  2335.       return(0);
  2336.    }
  2337.    if(isatty(fileno(fp))) {
  2338.       fclose(fp);
  2339.       return(0);
  2340.    }
  2341.  
  2342.    testa = (struct zero_block1 *)rbuffer;
  2343.  
  2344.    block_size = 128;
  2345.    head = SOH;
  2346.    switch(protocol) {
  2347.       case 'Y':
  2348.          base = 1;
  2349.          block_size = 1024;
  2350.          head = STX;
  2351.          break;
  2352.  
  2353.         case 'X':
  2354.          base = 1;
  2355.          break;
  2356.  
  2357.       case 'S':
  2358.         base = 0;
  2359.         break;
  2360.  
  2361.       case 'T':
  2362.          base = 0;
  2363.          head = SYN;
  2364.          break;
  2365.  
  2366.       case 'M':
  2367.          base = 1;
  2368.          break;
  2369.  
  2370.       default:
  2371.          fclose (fp);
  2372.          return (0);
  2373.    }
  2374.  
  2375.    blknum = base;
  2376.    last_block = (long )((dta.ff_fsize+((long )block_size-1L))/(long)block_size);
  2377.    status_line(msgtxt[M_SEND_MSG],fname,last_block,protocol);
  2378.    block_timer = timerset(300);
  2379.  
  2380.    if (caller || emulator) {
  2381.       wh = wopen(16,0,19,79,1,WHITE|_RED,WHITE|_RED);
  2382.       wactiv(wh);
  2383.       wtitle(" Transfer Status ", TLEFT, WHITE|_RED);
  2384.       wgotoxy (0, 1);
  2385.    }
  2386.    else {
  2387.       wfill (9, 0, 10, 77, ' ', WHITE|_BLACK);
  2388.         wgotoxy (9, 1);
  2389.    }
  2390.  
  2391.    sprintf (temps, msgtxt[M_SEND_MSG], fname, last_block, protocol);
  2392.    wputs (temps);
  2393.  
  2394.    if (may_be_seadog) {
  2395.       throughput(0,0L);
  2396.       goto sendloop;
  2397.    }
  2398.  
  2399.    do {
  2400.       do_chksum = 0;
  2401.       i = TIMED_READ(9);
  2402.       switch(i) {
  2403.       case NAK:
  2404.          do_chksum = 1;
  2405.       case 'C' :
  2406.          {
  2407.             int send_tmp;
  2408.  
  2409.             if(((send_tmp = TIMED_READ(4)) >= 0) && (TIMED_READ(2) == ((~send_tmp) & 0xff))) {
  2410.                if (send_tmp <= 1)
  2411.                   sliding=1;
  2412.                else {
  2413.                   SENDBYTE(EOT);
  2414.                   continue;
  2415.                }
  2416.             }
  2417.             if(may_be_seadog)
  2418.                     sliding = 1;
  2419.             errs = 0;
  2420.             CLEAR_INBOUND();
  2421.             throughput(0,0L);
  2422.             goto sendloop;
  2423.             }
  2424.       case CAN :
  2425.          goto fubar;
  2426.       default  :
  2427.          if((errs++) > 15) {
  2428.             goto fubar;
  2429.          }
  2430.          block_timer = timerset(50);
  2431.          while(!timeup(block_timer))
  2432.             time_release();
  2433.          CLEAR_INBOUND();
  2434.       }
  2435.    } while(CARRIER);
  2436.  
  2437.    goto fubar;
  2438.  
  2439. sendloop:
  2440.    while(CARRIER) {
  2441.       win_size = (blknum < 2) ? 2 : (send_ackless ? 220 : full_window);
  2442.  
  2443.       if(blknum <= last_block) {
  2444.          memset(rbuffer,0,block_size);
  2445.          if(blknum) {
  2446.             if(fseek(fp,((long)(blknum-1)*(long)block_size),SEEK_SET) == -1) {
  2447.                goto fubar;
  2448.             }
  2449.             fread(rbuffer,block_size,1,fp);
  2450.          }
  2451.          else {
  2452.             block_size = 128;
  2453.             testa->size = dta.ff_fsize;
  2454.             stat(fname,&st_stat);
  2455.             testa->time = st_stat.st_atime;
  2456.  
  2457.             strcpy(testa->name,dta.ff_name);
  2458.  
  2459.             if(protocol=='T') {
  2460.                for(i=0;i<HEADER_NAMESIZE;i++)
  2461.                   if (!(testa->name[i]))
  2462.                      testa->name[i] = ' ';
  2463.                     testa->time = dta.ff_ftime;
  2464.             }
  2465.  
  2466.             strcpy(testa->moi,VERSION);
  2467.             if ((rate >= 9600) && (sliding)) {
  2468.                testa->noacks = 1;
  2469.                send_ackless = 1;
  2470.             }
  2471.             else {
  2472.                testa->noacks = 0;
  2473.                send_ackless = 0;
  2474.             }
  2475.  
  2476.             if(no_overdrive) {
  2477.                     testa->noacks = 0;
  2478.                     send_ackless = 0;
  2479.             }
  2480.  
  2481.             ackless_ok = 0;
  2482.          }
  2483.  
  2484.          SENDBYTE((unsigned char )head);
  2485.          SENDBYTE((unsigned char )(blknum & 0xFF));
  2486.          SENDBYTE((unsigned char )(~(blknum & 0xFF)));
  2487.  
  2488.          for(b=rbuffer,i=0;i<block_size;i++,b++)
  2489.             SENDBYTE(*b);
  2490.  
  2491.          if((do_chksum) || (head==SYN)) {
  2492.             unsigned char chksum = '\0';
  2493.                 for(b=rbuffer,i=0;i<block_size;i++,b++)
  2494.                chksum+=(*b);
  2495.             SENDBYTE(chksum);
  2496.          }
  2497.          else {
  2498.             word crc;
  2499.  
  2500.             for(b=rbuffer,crc=i=0;i<block_size;i++,b++)
  2501.                crc = xcrc(crc,(byte )(*b));
  2502.  
  2503.             SENDBYTE((unsigned char )(crc>>8));
  2504.             SENDBYTE((unsigned char )(crc & 0xff));
  2505.          }
  2506.       }
  2507.  
  2508.       block_timer = timerset(3000);
  2509.  
  2510. slide_reply:
  2511.       if (!sliding) {
  2512.          FLUSH_OUTPUT();
  2513.          block_timer = timerset(3000);
  2514.       }
  2515.       else if((blknum < (ackblock + win_size)) && (blknum < last_block) && (PEEKBYTE() < 0 )) {
  2516.          if((send_ackless) && (blknum > 0)) {
  2517.             ackblock = blknum;
  2518.  
  2519.             if(blknum >= last_block) {
  2520.                if(ackless_ok) {
  2521.                   sprintf (temps, "%5ld", last_block);
  2522.                   if (caller || emulator)
  2523.                      wgotoxy (1, 1);
  2524.                   else
  2525.                      wgotoxy (10, 1);
  2526.                   wputs (temps);
  2527.                   goto done;
  2528.                     }
  2529.  
  2530.                blknum = last_block + 1;
  2531.                goto sendloop;
  2532.             }
  2533.  
  2534.             ++blknum;
  2535.  
  2536.             if (!(blknum & 0x001F)) {
  2537.                sprintf (temps, "%5ld", blknum);
  2538.                if (caller || emulator)
  2539.                   wgotoxy (1, 1);
  2540.                else
  2541.                   wgotoxy (10, 1);
  2542.                wputs (temps);
  2543.             }
  2544.          }
  2545.          else
  2546.             blknum++;
  2547.          goto sendloop;
  2548.       }
  2549.  
  2550.       if (PEEKBYTE() < 0) {
  2551.          if(send_ackless) {
  2552.             ackblock = blknum;
  2553.  
  2554.             if (blknum >= last_block) {
  2555.                if (ackless_ok) {
  2556.                   sprintf (temps, "%5ld", last_block);
  2557.                   if (caller || emulator)
  2558.                      wgotoxy (1, 1);
  2559.                   else
  2560.                      wgotoxy (10, 1);
  2561.                   wputs (temps);
  2562.                   goto done;
  2563.                     }
  2564.  
  2565.                blknum = last_block + 1;
  2566.                goto sendloop;
  2567.             }
  2568.  
  2569.             ++blknum;
  2570.  
  2571.             if ((blknum % 20) == 0) {
  2572.                sprintf (temps, "%5ld", blknum);
  2573.                if (caller || emulator)
  2574.                   wgotoxy (1, 1);
  2575.                else
  2576.                   wgotoxy (10, 1);
  2577.                wputs (temps);
  2578.             }
  2579.  
  2580.             goto sendloop;
  2581.          }
  2582.       }
  2583.  
  2584. reply:
  2585.       while (CARRIER && !OUT_EMPTY() && PEEKBYTE() < 0) {
  2586.          time_release();
  2587.          release_timeslice ();
  2588.       }
  2589.  
  2590.       if ((in_char = TIMED_READ (30)) < 0)
  2591.          goto fubar;
  2592.  
  2593.       if (in_char == 'C') {
  2594.          do_chksum = 0;
  2595.          in_char = NAK;
  2596.       }
  2597.  
  2598.         if (in_char == CAN)
  2599.          goto fubar;
  2600.  
  2601.       if ((in_char > 0) && (sliding)) {
  2602.          if(++ackerr >= 10) {
  2603.             if(send_ackless)
  2604.                send_ackless = 0;
  2605.          }
  2606.  
  2607.          if((in_char == ACK) || (in_char == NAK)) {
  2608.             if((i = TIMED_READ(2)) < 0) {
  2609.                sliding=0;
  2610.                if(send_ackless)
  2611.                   send_ackless = 0;
  2612.             }
  2613.             else {
  2614.                if((j = TIMED_READ(2)) < 0) {
  2615.                   sliding = 0;
  2616.                   if(send_ackless)
  2617.                      send_ackless = 0;
  2618.                }
  2619.                else if(i == (j ^ 0xff)) {
  2620.                   temp = blknum - ((blknum - i) & 0xff);
  2621.                   if ((temp <= blknum) && (temp > (blknum - win_size - 10))) {
  2622.                      if(in_char == ACK) {
  2623.                         if ((head == SYN) && (blknum))
  2624.                            head = SOH;
  2625.                         if (send_ackless) {
  2626.                            ackless_ok = 1;
  2627.                            goto slide_reply;
  2628.                         }
  2629.                         else
  2630.                            ackblock = temp;
  2631.  
  2632.                         blknum++;
  2633.  
  2634.                         if(ackblock >= last_block)
  2635.                            goto done;
  2636.                         errs = 0;
  2637.                      }
  2638.                      else {
  2639.                         blknum = temp;
  2640.                         CLEAR_OUTBOUND();
  2641.                         errs++;
  2642.                         real_errs++;
  2643.                      }
  2644.                   }
  2645.                }
  2646.             }
  2647.          }
  2648.          else {
  2649.             if(timeup(block_timer) && OUT_EMPTY()) {
  2650.                goto fubar;
  2651.             }
  2652.             else if (!OUT_EMPTY())
  2653.                block_timer=timerset(3000);
  2654.             goto slide_reply;
  2655.          }
  2656.       }
  2657.  
  2658.       if(!sliding) {
  2659.          if(in_char == ACK) {
  2660.             if(blknum == 10)
  2661.                timer(3);
  2662.             if (PEEKBYTE() > 0) {
  2663.                int send_tmp;
  2664.  
  2665.                if (((send_tmp = TIMED_READ (1)) >= 0) && (TIMED_READ (1) == ((~send_tmp) & 0xff))) {
  2666.                   sliding = 1;
  2667.                   ackblock = send_tmp;
  2668.                     }
  2669.             }
  2670.  
  2671.             if (blknum >= last_block)
  2672.                goto done;
  2673.             blknum++;
  2674.  
  2675.             if ((head == SYN) && (blknum))
  2676.                head = SOH;
  2677.  
  2678.             errs = 0;
  2679.          }
  2680.          else if (in_char == NAK) {
  2681.             errs++;
  2682.             real_errs++;
  2683.             timer (5);
  2684.             CLEAR_OUTBOUND ();
  2685.          }
  2686.          else if(CARRIER) {
  2687.             if (!timeup(block_timer))
  2688.                goto reply;
  2689.             else {
  2690.                goto fubar;
  2691.             }
  2692.          }
  2693.          else {
  2694.             goto fubar;
  2695.          }
  2696.       }
  2697.  
  2698.       if (errs > 10)
  2699.          goto fubar;
  2700.  
  2701.       temp = (blknum <= last_block) ? blknum : last_block;
  2702.  
  2703.         sprintf (temps, "%5ld", temp);
  2704.       if (caller || emulator)
  2705.          wgotoxy (1, 1);
  2706.       else
  2707.          wgotoxy (10, 1);
  2708.       wputs (temps);
  2709.  
  2710.       if ((sliding) && (ackblock > 0))
  2711.          if (!send_ackless) {
  2712.             sprintf (temps, ":%-5ld", ackblock);
  2713.             wputs (temps);
  2714.          }
  2715.    }
  2716.  
  2717. fubar:
  2718.    CLEAR_OUTBOUND();
  2719.    send_can();
  2720.    status_line("!%s not sent",fname);
  2721.  
  2722.    if(fp)
  2723.       fclose(fp);
  2724.  
  2725.    if ((caller || emulator) && wh != -1) {
  2726.       wactiv(wh);
  2727.       wclose();
  2728.       wh = -1;
  2729.    }
  2730.  
  2731.    return(0);
  2732.  
  2733. done:
  2734.    CLEAR_INBOUND();
  2735.    CLEAR_OUTBOUND();
  2736.  
  2737.    SENDBYTE(EOT);
  2738.  
  2739.    ackerr = 1;
  2740.    blknum = last_block + 1;
  2741.  
  2742.    for(i=0; i<5; i++) {
  2743.       if(!CARRIER) {
  2744.          ackerr = 1;
  2745.          goto gohome;
  2746.       }
  2747.  
  2748.       switch(TIMED_READ(5)) {
  2749.       case 'C':
  2750.       case NAK:
  2751.       case CAN:
  2752.          if (sliding && ((in_char = TIMED_READ(1)) >= 0)) {
  2753.             in_char1 = TIMED_READ(1);
  2754.             if (in_char == (in_char1 ^ 0xff)) {
  2755.                blknum -= ((blknum - in_char) & 0xff);
  2756.                CLEAR_INBOUND();
  2757.                if (blknum <= last_block)
  2758.                   goto sendloop;
  2759.             }
  2760.          }
  2761.          CLEAR_INBOUND();
  2762.          SENDBYTE(EOT);
  2763.          break;
  2764.       case TSYNC:
  2765.          ackerr = TSYNC;
  2766.          goto gohome;
  2767.       case ACK:
  2768.          if (sliding && ((in_char = TIMED_READ(1)) >= 0))
  2769.             in_char1 = TIMED_READ(1);
  2770.          ackerr = 1;
  2771. //         SENDBYTE(EOT);
  2772.          goto gohome;
  2773.         }
  2774.    }
  2775.  
  2776. gohome:
  2777.    if(fp)
  2778.       fclose(fp);
  2779.  
  2780.    throughput(1,dta.ff_fsize);
  2781.  
  2782.    if(real_errs > 4)
  2783.       status_line("+Corrected %d errors in %ld blocks", real_errs, last_block);
  2784.    status_line("+DL-%c %s",protocol,strupr(fname));
  2785.  
  2786.    if ((caller || emulator) && wh != -1) {
  2787.       wactiv(wh);
  2788.       wclose();
  2789.       wh = -1;
  2790.    }
  2791.  
  2792.    return(ackerr);
  2793. }
  2794.  
  2795. void locate_files (only_one)
  2796. int only_one;
  2797. {
  2798.    int fpd, line, m, z, fd, i, nnd, yr, oldlen, len;
  2799.    long totsize, totfile;
  2800.    char name[13], desc[70], *p, *fbuf, sameline, areadone;
  2801.    char filename[80], parola[30], header[90];
  2802.    struct _sys tsys, vsys;
  2803.    DIRENT *de;
  2804.  
  2805.    if (!get_command_word (parola, 29)) {
  2806.       m_print(bbstxt[B_KEY_SEARCH]);
  2807.       input(parola, 29);
  2808.         if(parola[0] == '\0' || !CARRIER)
  2809.          return;
  2810.    }
  2811.  
  2812.    cls();
  2813.    line = 4;
  2814.    totsize = totfile = 0L;
  2815.    oldlen = 0;
  2816.    sameline = (bbstxt[B_AREALIST_HEADER][strlen (bbstxt[B_AREALIST_HEADER]) - 1] == '\n') ? 0 : 1;
  2817.    strcpy (header, bbstxt[B_AREALIST_HEADER]);
  2818.    header[strlen (header) - 1] = '\0';
  2819.  
  2820.    _BRK_ENABLE ();
  2821.  
  2822.    m_print(bbstxt[B_CONTROLS]);
  2823.    m_print(bbstxt[B_CONTROLS2]);
  2824.  
  2825.    sprintf(filename,"%sSYSFILE.DAT", config->sys_path);
  2826.    fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  2827.    if (fd == -1) {
  2828.       status_line(msgtxt[M_NO_SYSTEM_FILE]);
  2829.       return;
  2830.    }
  2831.  
  2832.    memcpy ((char *)&vsys.file_name, (char *)&sys.file_name, SIZEOF_FILEAREA);
  2833.  
  2834.    while (read(fd, (char *)&tsys.file_name,SIZEOF_FILEAREA) == SIZEOF_FILEAREA && line) {
  2835.       if (only_one)
  2836.          memcpy ((char *)&tsys.file_name, (char *)&sys.file_name, SIZEOF_FILEAREA);
  2837.       else {
  2838.          if (usr.priv < tsys.file_priv || tsys.no_global_search)
  2839.             continue;
  2840.             if((usr.flags & tsys.file_flags) != tsys.file_flags)
  2841.             continue;
  2842.       }
  2843.  
  2844.       memcpy ((char *)&sys.file_name, (char *)&tsys.file_name, SIZEOF_FILEAREA);
  2845.  
  2846.       if (sameline && (usr.ansi || usr.avatar))
  2847.          del_line ();
  2848.  
  2849.       m_print (header, tsys.file_num, tsys.file_name);
  2850.       if (!sameline) {
  2851.          m_print2 ("\n");
  2852.          if ((line = file_more_question(line,only_one)) == 0)
  2853.             break;
  2854.       }
  2855.       else {
  2856.          areadone = 0;
  2857.             if (!usr.ansi && !usr.avatar) {
  2858.             len = strlen (tsys.file_name);
  2859.             if (oldlen != 0 && len < oldlen)
  2860.                space (oldlen - len);
  2861.             oldlen = len;
  2862.          }
  2863.          m_print2 ("\r");
  2864.       }
  2865.  
  2866.       // Apertura del FILES.BBS utilizzando il path dell'area letta nella
  2867.       // struttura locale tsys
  2868.       if (!tsys.filelist[0])
  2869.          sprintf (filename, "%sFILES.BBS", tsys.filepath);
  2870.       else
  2871.          strcpy (filename, tsys.filelist);
  2872.       if ((fpd = open (filename, O_RDONLY|O_BINARY)) == -1)
  2873.          continue;
  2874.  
  2875.       // Se il file e' di 0 bytes non importa leggere altro
  2876.       if (filelength (fpd) == 0L) {
  2877.          close (fpd);
  2878.             continue;
  2879.       }
  2880.  
  2881.       // Alloca il buffer che andra' a contenere l'intero files.bbs per
  2882.       // l'area corrente. Se non riesce ad allocarselo scrive una linea
  2883.       // nel log con le informazioni utili (spero) per il debugging.
  2884.       if ((fbuf = (char *)malloc ((unsigned int)filelength (fpd) + 1)) == NULL) {
  2885.      status_line ("!MEM: new_file_list (%ld)", filelength (fpd));
  2886.      close (fpd);
  2887.             continue;
  2888.       }
  2889.  
  2890.       // Lettura di tutto il files.bbs nel buffer allocato.
  2891.       read (fpd, fbuf, (unsigned int)filelength (fpd));
  2892.       fbuf[(unsigned int)filelength (fpd)] = '\0';
  2893.       close (fpd);
  2894.  
  2895.       // Legge tutta la directory in memoria. Se non c'e' spazio sufficiente
  2896.       // prosegue (scandir si occupa di segnalare nel log gli errori.
  2897.       if ((de = scandir (tsys.filepath, &nnd)) == NULL) {
  2898.          free (fbuf);
  2899.          continue;
  2900.       }
  2901.  
  2902.       // La scansione del files.bbs avviene in memoria. Tenendo conto che
  2903.       // ogni linea e' separata almeno da un \r (CR, 0x0D) si puo' utilizzare
  2904.       // la strtok, trattando l'intero buffer come un insieme di token.
  2905.       if ((p = strtok (fbuf, "\r\n")) != NULL)
  2906.          do {
  2907.             // Nel caso di \r\n (EOL) e' necessario saltare il \n per evitare
  2908.             // problemi nel riconoscimento dei files.
  2909.             if (p[0] == '\0')
  2910.                continue;
  2911.             if (p[0] == '\n')
  2912.                p++;
  2913.  
  2914.             if (!CARRIER || (!local_mode && RECVD_BREAK())) {
  2915.                line = 0;
  2916.                break;
  2917.             }
  2918.  
  2919.             // Se il primo carattere non e' alfanumerico si tratta di un
  2920.             // commento, pertanto non e' necessario visualizzarlo.
  2921.                 if (!isalnum (p[0]))
  2922.                continue;
  2923.  
  2924.             // Se la stringa di ricerca viene trovata in un punto qualsiasi
  2925.             // della linea di descrizione si prosegue.
  2926.             if (stristr (p, parola) != NULL) {
  2927.                // Estrae il nome del file dalla stringa puntata da p
  2928.                m = 0;
  2929.                while (p[m] != ' ' && m < 12)
  2930.                   name[m] = p[m++];
  2931.                name[m] = '\0';
  2932.  
  2933.                // Cerca il file nella lista in memoria puntata da de.
  2934.                for (i = 0; i < nnd; i++) {
  2935.                   if (!stricmp (de[i].name, name))
  2936.                      break;
  2937.                }
  2938.  
  2939.                // Il file non e' presente nella directory fisica.
  2940.                if (i >= nnd) {
  2941.                   if (!config->show_missing)
  2942.                      continue;
  2943.                   yr = -1;
  2944.                }
  2945.                else
  2946.                   yr = 0;
  2947.  
  2948.                // Estrae la descrizione del file.
  2949.                z = 0;
  2950.                while (p[m] == ' ')
  2951.                   m++;
  2952.                while (p[m] && z < (tsys.no_filedate ? 56 : 48))
  2953.                   desc[z++] = p[m++];
  2954.                desc[z] = '\0';
  2955.  
  2956.                if (yr != -1)
  2957.                   totsize += de[i].size;
  2958.                totfile++;
  2959.  
  2960.                if (sameline && !areadone) {
  2961.                   areadone = 1;
  2962.                   m_print (bbstxt[B_ONE_CR]);
  2963.                   if ((line = file_more_question(line,only_one)) == 0)
  2964.                      break;
  2965.                }
  2966.  
  2967.                if (sys.no_filedate) {
  2968.                   if (yr == -1) {
  2969.                      if (config->show_missing)
  2970.                         m_print (bbstxt[B_FILES_NODATE_MISSING], strupr (name), bbstxt[B_FILES_MISSING], desc);
  2971.                   }
  2972.                   else
  2973.                      m_print (bbstxt[B_FILES_NODATE], strupr (name), de[i].size, desc);
  2974.                }
  2975.                else {
  2976.                   if (yr == -1) {
  2977.                      if (config->show_missing)
  2978.                         m_print (bbstxt[B_FILES_FORMAT_MISSING], strupr (name), bbstxt[B_FILES_MISSING], desc);
  2979.                   }
  2980.                   else
  2981.                      m_print (bbstxt[B_FILES_FORMAT], strupr (name), de[i].size, show_date (config->dateformat, e_input, de[i].date, 0), desc);
  2982.                }
  2983.  
  2984.                if (!(line = file_more_question (line, only_one)) || !CARRIER)
  2985.                   break;
  2986.             }
  2987.          } while ((p = strtok (NULL, "\r\n")) != NULL);
  2988.  
  2989.         free (de);
  2990.       free (fbuf);
  2991.  
  2992.       if (only_one || !CARRIER)
  2993.          break;
  2994.    }
  2995.  
  2996.    close(fd);
  2997.  
  2998.    memcpy ((char *)&sys.file_name, (char *)&vsys.file_name, SIZEOF_FILEAREA);
  2999.  
  3000.    if (sameline && !areadone)
  3001.       m_print (bbstxt[B_ONE_CR]);
  3002.  
  3003.    m_print (bbstxt[B_LOCATED_MATCH], totfile, totsize);
  3004.  
  3005.    if (line && CARRIER)
  3006.       file_more_question (usr.len, only_one);
  3007. }
  3008.  
  3009. void hurl ()
  3010. {
  3011.    #define MAX_HURL  4096
  3012.    FILE *fps, *fpd;
  3013.    struct _sys tempsys;
  3014.    int fds, fdd, m;
  3015.    char file[16], hurled[128], *b, filename[128];
  3016.     struct ftime ftimep;
  3017.  
  3018.    if (!get_command_word (file, 12)) {
  3019.       m_print (bbstxt[B_HURL_WHAT]);
  3020.       input (file, 12);
  3021.       if (!file[0])
  3022.          return;
  3023.     }
  3024.  
  3025.    sprintf (filename, "%s%s", sys.filepath, file);
  3026.    fds = shopen (filename, O_RDWR|O_BINARY);
  3027.    if(fds == -1)
  3028.       return;
  3029.  
  3030.    if (!get_command_word (hurled, 79)) {
  3031.       m_print (bbstxt[B_HURL_AREA]);
  3032.         input (hurled, 80);
  3033.       if (!hurled[0]) {
  3034.          close (fds);
  3035.          return;
  3036.       }
  3037.    }
  3038.  
  3039.    if ((m = atoi(hurled)) != 0) {
  3040.       if (!read_system2 (2, m, &tempsys)) {
  3041.          close (fds);
  3042.          return;
  3043.       }
  3044.    }
  3045.    else
  3046.       strcpy (tempsys.filepath, hurled);
  3047.  
  3048.    m_print (bbstxt[B_HURLING], sys.filepath, file, tempsys.filepath, file);
  3049.  
  3050.    sprintf (filename, "%s%s", tempsys.filepath, file);
  3051.    fdd = cshopen (filename, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  3052.    if (fdd == -1) {
  3053.       close (fds);
  3054.       return;
  3055.    }
  3056.  
  3057.     b = (char *)malloc(MAX_HURL);
  3058.    if (b == NULL)
  3059.       return;
  3060.  
  3061.    do {
  3062.       m = read (fds, b, MAX_HURL);
  3063.       write (fdd, b, m);
  3064.    } while (m == MAX_HURL);
  3065.  
  3066.     getftime (fds, &ftimep);
  3067.     setftime (fdd, &ftimep);
  3068.  
  3069.    close (fdd);
  3070.    close (fds);
  3071.  
  3072.    free(b);
  3073.  
  3074.    sprintf (filename, "%s%s", sys.filepath, file);
  3075.    unlink (filename);
  3076.  
  3077.    sprintf (filename, "%sFILES.BBS", sys.filepath);
  3078.    sprintf (hurled, "%sFILES.BAK", sys.filepath);
  3079.    unlink (hurled);
  3080.    rename (filename, hurled);
  3081.  
  3082.    fpd = fopen (filename, "wt");
  3083.    fps = fopen (hurled, "rt");
  3084.  
  3085.    strupr (file);
  3086.    strcat (file," ");
  3087.  
  3088.    while (fgets (filename, 128, fps) != NULL) {
  3089.       if (!strncmp (filename, file, strlen (file))) {
  3090.          strcpy (hurled, filename);
  3091.             continue;
  3092.       }
  3093.       fputs (filename, fpd);
  3094.    }
  3095.  
  3096.    fclose(fps);
  3097.    fclose(fpd);
  3098.  
  3099.    sprintf(filename, "%sFILES.BBS", tempsys.filepath);
  3100.    fpd = fopen (filename,"at");
  3101.    fputs (hurled, fpd);
  3102.    fclose (fpd);
  3103. }
  3104.  
  3105. int file_more_question (line, only_one)
  3106. int line, only_one;
  3107. {
  3108.     int i;
  3109.  
  3110.     if (nopause)
  3111.         return (1);
  3112.  
  3113.     if (!(line++ < (usr.len-1)) && usr.more) {
  3114. reask_question:
  3115.         line = 1;
  3116.         cmd_string[0] = '\0';
  3117. //      m_print(bbstxt[B_MORE]);
  3118.  
  3119.         m_print (bbstxt[B_FILE_MOREQUESTION]);
  3120.  
  3121.         if ( (usr.priv < sys.download_priv || sys.download_priv == HIDDEN) || ((usr.flags & sys.download_flags) != sys.download_flags) )
  3122.             i = yesno_question(DEF_YES|EQUAL|NO_LF|NO_MESSAGE);
  3123.         else
  3124.             i = yesno_question(DEF_YES|EQUAL|NO_LF|TAG_FILES|DOWN_FILES|NO_MESSAGE);
  3125.  
  3126.         m_print("\r");
  3127.         space (strlen (bbstxt[B_FILE_MOREQUESTION]) + 2);
  3128.         m_print("\r");
  3129.  
  3130.         if (i == DEF_NO) {
  3131.             nopause = 0;
  3132.             return (0);
  3133.         }
  3134.  
  3135.         line = 1;
  3136.  
  3137.         if (i == EQUAL)
  3138.             nopause = 1;
  3139.  
  3140.         if (i == DOWN_FILES) {
  3141.             nopause = 0;
  3142.             if (usr.priv < sys.download_priv || sys.download_priv == HIDDEN)
  3143.                 return (line);
  3144.             if((usr.flags & sys.download_flags) != sys.download_flags)
  3145.                 return (line);
  3146.             download_file (sys.filepath, only_one ? 0 : 1);
  3147.             if (user_status != BROWSING)
  3148.                 set_useron_record(BROWSING, 0, 0);
  3149.             m_print (bbstxt[B_PAUSED_LIST]);
  3150.             goto reask_question;
  3151.         }
  3152.  
  3153.         if (i == TAG_FILES) {
  3154.             nopause = 0;
  3155.             if (usr.priv < sys.download_priv || sys.download_priv == HIDDEN)
  3156.                 return (line);
  3157.             if((usr.flags & sys.download_flags) != sys.download_flags)
  3158.                 return (line);
  3159.             tag_files (only_one);
  3160.          if (user_status != BROWSING)
  3161.             set_useron_record(BROWSING, 0, 0);
  3162.             m_print (bbstxt[B_PAUSED_LIST]);
  3163.          goto reask_question;
  3164.       }
  3165.    }
  3166.  
  3167.    return (line);
  3168. }
  3169.  
  3170. void file_kill (int fbox, char *n_file)
  3171. {
  3172.    FILE *fps, *fpd;
  3173.    int i, godelete;
  3174.    char filename[80], file[14], *buffer, *p;
  3175.    struct ffblk blk;
  3176.  
  3177.    if (n_file == NULL) {
  3178.       if (!get_command_word (file, 12)) {
  3179.          m_print (bbstxt[B_KILL_FILE]);
  3180.          input (file, 12);
  3181.          if (!file[0])
  3182.             return;
  3183.       }
  3184.    }
  3185.    else
  3186.       strcpy (filename, n_file);
  3187.  
  3188.    if ((buffer = (char *)malloc (2048)) == NULL)
  3189.       return;
  3190.  
  3191.    if (fbox) {
  3192.       if (n_file != NULL) {
  3193.          while ((p = strchr (filename, '\\')) != NULL)
  3194.             strcpy (filename, ++p);
  3195.          strcpy (file, filename);
  3196.       }
  3197.         sprintf (filename, "%s%08lx\\%s", config->boxpath, usr.id, file);
  3198.    }
  3199.    else if (n_file == NULL)
  3200.       sprintf (filename,"%s%s", sys.filepath, file);
  3201.  
  3202.    if (!findfirst (filename, &blk, 0))
  3203.       do {
  3204.          if (fbox)
  3205.                 sprintf (filename, "%s%08lx\\%s", config->boxpath, usr.id, blk.ff_name);
  3206.          else
  3207.             sprintf (filename,"%s%s", sys.filepath, blk.ff_name);
  3208.  
  3209.          if (!fbox) {
  3210.             m_print (bbstxt[B_KILL_REMOVE], blk.ff_name);
  3211.             i = yesno_question (DEF_NO);
  3212.          }
  3213.          else
  3214.             i = DEF_YES;
  3215.  
  3216.          if (i == DEF_YES) {
  3217.             if (unlink (filename))
  3218.                m_print (bbstxt[B_NOTFOUND], blk.ff_name);
  3219.  
  3220.             else {
  3221.                if (fbox) {
  3222.                         sprintf (filename, "%s%08lx\\FILES.BBS", config->boxpath, usr.id);
  3223.                         sprintf (buffer, "%s%08lx\\FILES.BAK", config->boxpath, usr.id);
  3224.                }
  3225.                else {
  3226.                   sprintf (filename, "%sFILES.BBS", sys.filepath);
  3227.                   sprintf (buffer, "%sFILES.BBS", sys.filepath);
  3228.                }
  3229.  
  3230.                rename (filename, buffer);
  3231.                godelete = 0;
  3232.  
  3233.                fpd = fopen (filename, "wt");
  3234.                fps = fopen (buffer, "rt");
  3235.  
  3236.                while (fgets (buffer, 2040, fps) != NULL) {
  3237.                   if (godelete) {
  3238.                      if (buffer[1] == '>')
  3239.                         continue;
  3240.                      else
  3241.                         godelete = 0;
  3242.                   }
  3243.                   if (!strncmp (buffer, blk.ff_name, strlen (blk.ff_name))) {
  3244.                      godelete = 1;
  3245.                      continue;
  3246.                   }
  3247.                   fputs (buffer, fpd);
  3248.                }
  3249.  
  3250.                fclose (fps);
  3251.                fclose (fpd);
  3252.             }
  3253.          }
  3254.       } while (!findnext (&blk));
  3255.  
  3256.    else if (!fbox)
  3257.       m_print (bbstxt[B_NOTFOUND], file);
  3258.  
  3259.    free (buffer);
  3260. }
  3261.  
  3262.