home *** CD-ROM | disk | FTP | other *** search
/ The Arcade BBS / arcadebbs.zip / arcadebbs / bbstools / MODS / FR020C.ZIP / FR020C.MOD < prev   
Encoding:
Text File  |  1995-06-21  |  36.1 KB  |  1,110 lines

  1. ┌───────────────────────────────────────────────────────────────────────────┐
  2. │ Mod Name: FR020B.MOD         Mod Author: Frank Reid 1@8213.WWIVNET        │
  3. │ Difficulty: Intermediate          Date: June 10, 1995                     │
  4. │ WWIV Version: 4.24                                                        │
  5. │ Description: File Attach mod. Allows users to upload a file as an attach  │
  6. │ to Email for another user. SysOp can attach from any DOS drive/path.      │
  7. └───────────────────────────────────────────────────────────────────────────┘
  8.  
  9. 1.  Description:  Overhaul of East Bay Ray's ATTACH.MOD for v4.12 with upward
  10. compatibility and the ability to add local files, which was my main purpose
  11. for rewriting it.
  12.  
  13. 2.  Description:  You can attach files two ways.  An //ATTACH command scans
  14. Email you've sent and prompts to attach a file (good for responding to offline
  15. requests).  The more common method is a prompt when saving E-mail.  Like many
  16. other BBS types, you're asked if you wish to attach a file to the message.
  17. The sysop (or any 255 SL) can attach files from a local drive; regular users
  18. can upload a file as an attachment only.  A remote 255 can either upload or
  19. attach from local.  (If you need to be warned, be careful who you give 255 SL
  20. on your system -- remotes can attach any file they want to Email and download
  21. it!)
  22.  
  23. 3.  Mechanics:  Creates and maintains a data structure in your DATA directory
  24. to store information about attached files.  The directory to store files is
  25. specified in WWIV.INI.  Files are deleted if a user deletes, autoreplies or
  26. downloads, making the process entirely self-maintaining.  (A sysyop has the
  27. option of saving an attached file when autoreplying.)
  28.  
  29. 4.  Limitations:  One file of the same name can exist in the attach directory
  30. at a time (a DOS limitation).  If you want to send the same file to more than
  31. one user, you can rename the target file on the fly.
  32.  
  33. ** Step One **
  34.  
  35. Back up your source code!  This is an extensive mod, and if you have problems 
  36. you'll regret not having a backup!
  37.  
  38. ** Step Two **
  39.  
  40. Open <MMENU.C>
  41.  
  42. Search for "void mainmenu(void)" and add the following:
  43.  
  44. ==  if ((strcmp(s,"NET")==0) || (strncmp(s,"NET=",4)==0))
  45. ==    print_net_listing(0);
  46. ++  if (strcmp(s,"ATTACH")==0)
  47. ++    attach_file(0);
  48. ==  if (strcmp(s,"QSCAN")==0) {
  49.  
  50. Save <MMENU.C>
  51.  
  52. ** Step Three **
  53.  
  54. Open <VARDEC.H>
  55.  
  56. After the conference structure, add the a filestatusrec structure:
  57.  
  58. ==                *subs;            /* "Sub" numbers in this conference */
  59. ==} confrec;
  60.  
  61. ++typedef struct {
  62. ++  int             user;
  63. ++  char            filename[13];
  64. ++  long            id;
  65. ++  unsigned long   numbytes;
  66. ++} filestatusrec;
  67.  
  68. Save <VARDEC.H>
  69.  
  70. ** Step Four **
  71.  
  72. Open <VARS.H>
  73.  
  74. Search for the char declarations and add the following:
  75.  
  76. ==               ver_no2[51],wwiv_net_no[20], xdate[9], *xenviron[50],
  77. ==               dlfn[81],edlfn[81], nete[5], irt_sub[81];
  78. ==
  79. ++__EXTRN__ char attach_dir[81];
  80. ++
  81. ==__EXTRN__ unsigned char actsl, andwith, checksum;
  82.  
  83. Save <VARS.H>
  84.  
  85. *** Step Five ***
  86.  
  87. Open <READMAIL.C>
  88.  
  89. Near the top of the file, add the following #include (prototypes the ffblk
  90. structure):
  91.  
  92. ==#pragma hdrstop
  93.  
  94. ++#include <dir.h>
  95.  
  96. Search for "void readmail(void)" and declare these variables:
  97.  
  98. ==  tmpmailrec *mloc;
  99. ++  filestatusrec fsr;
  100. ++  int f1, found, attach_exists, sentt, abortt;
  101. ++  long l1;
  102. ==
  103. ==  emchg=0;
  104.  
  105. Hop down about 300 lines and add this chunk of code:
  106.  
  107. ==      if (!abort) {
  108. ==        read_message1(&m.msg, (m.anony & 0x0f), i, &next, "EMAIL");
  109. ==        if (!(m.status & status_seen)) {
  110. ==          read_same_email(mloc, mw, curmail, &m, 0, status_seen);
  111. ==        }
  112. ==      }
  113. /* BEGIN BLOCK READ */
  114.       found = 0;
  115.       attach_exists = 0;
  116.       if (m.status & status_file) {
  117.         sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  118.         f1 = sh_open(s, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);  /* B */
  119.         if (f1 > -1) {
  120.           l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  121.           while ((l1 > 0) && (!found)) {
  122.             if (m.daten == fsr.id) {
  123.               found = 1;
  124.               sprintf(s, "%s%s", attach_dir, fsr.filename);
  125.               if (exist(s)) {
  126.                 sprintf(s, "'T' to download attached file \"%s\" (%ld bytes).",
  127.                     fsr.filename, fsr.numbytes);
  128.                 pl(s);
  129.                 attach_exists = 1;
  130.               } else {
  131.                 sprintf(s, "Attached file \"%s\" (%ld bytes) is missing!",
  132.                     fsr.filename, fsr.numbytes);
  133.                 pl(s);
  134.               }
  135.             }
  136.             if (!found)
  137.               l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  138.           }
  139.           if (!found)
  140.             pl("File attached but attachment data missing.  Alert sysop!");
  141.         } else {
  142.           pl("File attached but attachment data missing.  Alert sysop!");
  143.         }
  144.         f1 = sh_close(f1);
  145.       }
  146. /* END BLOCK READ HERE */
  147. ==#ifdef RIPDRIVE
  148. ==      rd_con();
  149. ==#endif
  150.  
  151. A few lines below there, you'll need to make several changes.  These changes
  152. "stack" the user's options for reading mail, allowing you to add a 'T' if a
  153. file attach exists.  Follow the changed lines (=+) carefully -- this is the
  154. one place where most folks made errors in the past.
  155.  
  156. ==      if (so()) {
  157. ==        if (sysinfo.flags & OP_FLAGS_MAIL_PROMPT)
  158. ==          npr(get_string(1365));
  159. =+        strcpy(s,"QSRIDAMF?-+GEZPVUOLCN");
  160. ==      } else {
  161. ==        if (cs()) {
  162. ==          if (sysinfo.flags & OP_FLAGS_MAIL_PROMPT)
  163. ==            npr(get_string(1366));
  164. =+          strcpy(s, "QSRIDAMF?-+GZPVUOC");
  165. ==        } else {
  166. ==          if (!okmail) {
  167. ==            if (sysinfo.flags & OP_FLAGS_MAIL_PROMPT)
  168. ==              npr(get_string(1367));
  169. =+            strcpy(s, "QI?-+G");
  170. ==          } else {
  171. ==            if (sysinfo.flags & OP_FLAGS_MAIL_PROMPT)
  172. ==              npr(get_string(1368));
  173. =+            strcpy(s, "QSRIDAMF?+-G");
  174. ==          }
  175. ==        }
  176. ==      }
  177. ++      if ((m.status & status_file) && (found) && (attach_exists)) {
  178. ++        if (sysinfo.flags & OP_FLAGS_MAIL_PROMPT)
  179. ++          npr("\b\b7{1T7} 2: 0");
  180. ++        strcat(s, "T");
  181. ++      }
  182. ++      ch = onek(s);
  183. ==      if (okmail && !read_same_email(mloc, mw, curmail, &m, 0, 0)) {
  184.  
  185. A few lines below here, add the entire case 'T' to transfer the file:
  186.  
  187. ==      switch (ch) {
  188. /* BEGIN BLOCK READ */
  189.         case 'T':
  190.           nl();
  191.           sprintf(s1, "%s%s", attach_dir, fsr.filename);
  192.           send_file(s1, &sentt, &abortt, 0, fsr.filename, -1, fsr.numbytes);
  193.           if (sentt) {
  194.             nl();
  195.             pl("Attached file sent.");
  196.             sprintf(s1,"Downloaded %ldk of attached file %s.",
  197.               (fsr.numbytes+1023)/1024, fsr.filename);
  198.             sysoplog(s1);
  199.           } else {
  200.             nl();
  201.             pl("Attached file not completely sent.");
  202.             sprintf(s1,"Tried to download attached file %s.", fsr.filename);
  203.             sysoplog(s1);
  204.           }
  205.           nl();
  206.           break;
  207. /* END BLOCK READ */
  208. ==        case 'N':
  209.  
  210. Jump down a hundred lines, and add this to case 'Z':
  211.  
  212. ==        case 'Z':
  213. ==          if (!okmail)
  214. ==            break;
  215. ==          read_same_email(mloc, mw, curmail, &m, 1, 0);
  216. ==          ++curmail;
  217. ==          if (curmail>=mw)
  218. ==            done=1;
  219. /* BEGIN BLOCK READ */
  220.           found = 0;
  221.           if (m.status & status_file) {
  222.             sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  223.             f1 = sh_open1(s, O_RDWR | O_BINARY);
  224.             if (f1 > -1) {
  225.               l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  226.               while ((l1 > 0) && (!found)) {
  227.                 if (m.daten == fsr.id) {
  228.                   found = 1;
  229.                   fsr.id = 0;
  230.                   sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  231.                   sh_write(f1, (void *)(&fsr), sizeof(filestatusrec));
  232.                   sprintf(s1, "%s%s", attach_dir, fsr.filename);
  233.                   unlink(s1);
  234.                 } else
  235.                   l1 = sh_read(f1, (void *)(&fsr), sizeof(filestatusrec));
  236.               }
  237.               f1 = sh_close(f1);
  238.             }
  239.           }
  240. /* END BLOCK READ */
  241. ==          if (!wfc)
  242. ==            topscreen();
  243. ==          break;
  244. ==        case 'P':
  245.  
  246. Just below that, add this to case 'F' so a file is deleted when forwarding
  247. mail:
  248.  
  249. ==        case 'F':
  250. ==          if (!okmail)
  251. ==            break;
  252. ==          if (m.status & status_multimail) {
  253. ==            nl();
  254. ==            pl(get_string(715));
  255. ==            nl();
  256. ==            break;
  257. ==          }
  258. /* BEGIN BLOCK READ */
  259.           if (m.status & status_file) {
  260.             sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  261.             f1 = sh_open1(s, O_RDWR | O_BINARY);
  262.             if (f1 > -1) {
  263.               l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  264.               while ((l1 > 0) && (!found)) {
  265.                 if (m.daten == fsr.id) {
  266.                   found = 1;
  267.                   fsr.id = 0;
  268.                   sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  269.                   sh_write(f1, (void *)(&fsr), sizeof(filestatusrec));
  270.                   if (so()) {
  271.                     prt(5, "Delete attached file? ");
  272.                     if (yn()) {
  273.                       sprintf(s1, "%s%s", attach_dir, fsr.filename);
  274.                       unlink(s1);
  275.                     } else {
  276.                       npr("\r\nOrphaned attach %s remains in %s\r\n",
  277.                           fsr.filename, attach_dir);
  278.                       pausescr();
  279.                     }
  280.                   }
  281.                 } else
  282.                   l1 = sh_read(f1, (void *)(&fsr), sizeof(filestatusrec));
  283.               }
  284.               f1 = sh_close(f1);
  285.             }
  286.           }
  287. /* END BLOCK READ HERE */
  288. ==          nln(2);
  289. ==          prt(2,get_string(716));
  290.  
  291.  
  292. Another hundred or so lines down, add this block:
  293.  
  294. ==          if ((ch=='A') || (ch=='M')) {
  295. ==            if (num_mail!=num_mail1) {
  296. ==              if (m.fromsys!=0)
  297. ==                sprintf(s,"%s: %s",net_name,
  298. ==                    nam1(&thisuser,usernum,net_sysnum));
  299. ==              else
  300. ==                strcpy(s,nam1(&thisuser,usernum,net_sysnum));
  301. ==              if (m.anony & anony_receiver)
  302. ==                strcpy(s,get_string(482));
  303. ==              strcat(s,get_string(713));
  304. ==              strcat(s,date());
  305. ==              if (!(m.status & status_source_verified))
  306. ==                ssm(m.fromuser,m.fromsys,s);
  307. ==              read_same_email(mloc, mw, curmail, &m, 1, 0);
  308. ==              ++curmail;
  309. ==              if (curmail>=mw)
  310. ==                done=1;
  311. /* BEGIN BLOCK READ */
  312.               found = 0;
  313.               if (m.status & status_file) {
  314.                 sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  315.                 f1 = sh_open1(s, O_RDWR | O_BINARY);
  316.                 if (f1 > -1) {
  317.                   l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  318.                   while ((l1 > 0) && (!found)) {
  319.                     if (m.daten == fsr.id) {
  320.                       found = 1;
  321.                       fsr.id = 0;
  322.                       sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  323.                       sh_write(f1, (void *)(&fsr), sizeof(filestatusrec));
  324.                       if (so()) {
  325.                         prt(5, "Delete attached file? ");
  326.                         if (yn()) {
  327.                           sprintf(s1, "%s%s", attach_dir, fsr.filename);
  328.                           unlink(s1);
  329.                         } else {
  330.                           npr("\r\nOrphaned attach %s remains in %s\r\n",
  331.                               fsr.filename,
  332.                               attach_dir);
  333.                           pausescr();
  334.                         }
  335.                       }
  336.                     } else
  337.                       l1 = sh_read(f1, (void *)(&fsr), sizeof(filestatusrec));
  338.                   }
  339.                   f1 = sh_close(f1);
  340.                 }
  341.               }
  342. /* END BLOCK READ */
  343. ==              if (!wfc)
  344. ==                topscreen();
  345.  
  346. Now, the "guts" of the mod!  Go to the very bottom of the file, and add these
  347. two routines:
  348.  
  349. void attach_file(int mode)
  350. {
  351.   int cur, max, i, i1, f, done, done1, done2, done3;
  352.   int forward, f1, remote_upld, newname, found, ok, d1, d2;
  353.   char s[81], s1[81], s2[81], s3[31], ch, ch1, *b;
  354.   long l, l1;
  355.   mailrec m;
  356.   userrec u;
  357.   slrec ss;
  358.   filestatusrec fsr, fsr1;
  359.   unsigned char u_filetype;
  360.   union REGS r;
  361.  
  362.   nl();
  363.   forward = 1;
  364.   ss = syscfg.sl[actsl];
  365.   f = open_email(1);
  366.   if (f == -1) {
  367.     nl();
  368.     pl("No mail.");
  369.     f = sh_close(f);
  370.     return;
  371.   }
  372.   max = (int) (filelength(f) / sizeof(mailrec));
  373.   if (forward)
  374.     cur = max - 1;
  375.   else
  376.     cur = 0;
  377.   done = newname = 0;
  378.   do {
  379.     sh_lseek(f, ((long) cur) * ((long) sizeof(mailrec)), SEEK_SET);
  380.     sh_read(f, (void *) &m, sizeof(mailrec));
  381.     while (((m.fromsys != 0) || (m.fromuser != usernum) ||
  382.       (m.touser == 0)) && (cur < max) && (cur >= 0)) {
  383.       if (forward)
  384.         --cur;
  385.       else
  386.         ++cur;
  387.       if ((cur < max) && (cur >= 0)) {
  388.         sh_lseek(f, ((long) cur) * ((long) sizeof(mailrec)), SEEK_SET);
  389.         sh_read(f, (void *) &m, sizeof(mailrec));
  390.       }
  391.     }
  392.     if ((m.fromsys != 0) || (m.fromuser != usernum) ||
  393.         (m.touser == 0) || (cur >= max) || (cur < 0))
  394.       done = 1;
  395.     else {
  396.       do {
  397.         done1 = 0;
  398.         nl();
  399.         if (m.tosys == 0) {
  400.           read_user(m.touser, &u);
  401.           outstr(get_string(325));
  402.           strcpy(s1, nam(&u, m.touser));
  403.           if ((m.anony &
  404.               (anony_receiver | anony_receiver_pp | anony_receiver_da)) &&
  405.               ((ss.ability & ability_read_email_anony) == 0))
  406.             strcpy(s1, ">UNKNOWN<");
  407.           pl(s1);
  408.         } else {
  409.           itoa(m.touser, s, 10);
  410.           itoa(m.tosys, s1, 10);
  411.           outstr(get_string(325));
  412.           npr("User %s System %s\r\n", s1, s);
  413.         }
  414.         outstr(get_string(326)); pl(m.title);
  415.         time(&l);
  416.         i = (int) ((l - m.daten) / 24.0 / 3600.0);
  417.         itoa(i, s, 10);
  418.         npr("1Sent0........2 %s days ago\r\n", s);
  419.         if (m.status & status_file) {
  420.           sprintf(s2, "%sATTACH.DAT", syscfg.datadir);
  421.           f1 = sh_open(s2, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); /* B */
  422.           if (f1 > -1) {
  423.             found = 0;
  424.             l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  425.             while ((l1 > 0) && (!found)) {
  426.               if (m.daten == fsr.id) {
  427.                 if (E_C)
  428.                   sprintf(s, "%s2%s (%ld bytes)0",
  429.                     get_string(659), fsr.filename, fsr.numbytes);
  430.                 else
  431.                   sprintf(s, "File : %s (%ld bytes)", fsr.filename,
  432.                     fsr.numbytes);
  433.                 pl(s);
  434.                 found = 1;
  435.               }
  436.               if (!found)
  437.                 l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  438.             }
  439.             if (!found)
  440.               if (E_C) {
  441.                 sprintf(s, "%s2Unknown or missing0", get_string(659));
  442.                 pl(s);
  443.               } else
  444.                 pl("File : Unknown or Missing");
  445.             f1 = sh_close(f1);
  446.           } else
  447.             if (E_C) {
  448.               sprintf(s, "%s2Unknown or missing0", get_string(659));
  449.               pl(s);
  450.             } else
  451.               pl("File : Unknown or Missing");
  452.         }
  453.         nl();
  454.         if (mode == 0) {
  455.           prt(2, "R:ead, A:ttach, N:ext, Q:uit : ");
  456.           ch = onek("QRAN");
  457.         } else {
  458.           prt(2, "R:ead, A:ttach, Q:uit : ");
  459.           ch = onek("QRA");
  460.         }
  461.         switch (ch) {
  462.         case 'Q':
  463.           done1 = 1;
  464.           done = 1;
  465.           break;
  466.         case 'A':
  467.           done2 = 0;
  468.           if (m.status & status_file) {
  469.             prt(6, "File already attached, D:elete, O:verwrite, or Q:uit? : ");
  470.             ch1 = onek("QDO");
  471.             switch (ch1) {
  472.             case 'Q':
  473.               done2 = 1;
  474.               break;
  475.             case 'D':
  476.             case 'O':
  477.               m.status ^= status_file;
  478.               sh_lseek(f, ((long) sizeof(mailrec)) * -1L, SEEK_CUR);
  479.               sh_write(f, (void *) (&m), sizeof(mailrec));
  480.               sprintf(s2, "%sATTACH.DAT", syscfg.datadir);
  481.               f1 = sh_open1(s2, O_RDWR | O_BINARY);
  482.               if (f1 > -1) {
  483.                 found = 0;
  484.                 l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  485.                 while ((l1 > 0) && (!found)) {
  486.                   if (m.daten == fsr.id) {
  487.                     fsr.id = 0;
  488.                     sprintf(s, "%s%s", attach_dir, fsr.filename);
  489.                     unlink(s);
  490.                     sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  491.                     sh_write(f1, (void *) (&fsr), sizeof(fsr));
  492.                   }
  493.                   if (!found)
  494.                     l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  495.                 }
  496.                 f1 = sh_close(f1);
  497.                 pl("File attachment removed.");
  498.               }
  499.               if (ch1 == 'D')
  500.                 done2 = 1;
  501.               break;
  502.             }
  503.           }
  504.           if (freek1(attach_dir) < 500) {
  505.             pl("Not enough free space to attach a file.");
  506.           } else {
  507.             if (!done2) {
  508.               remote_upld = found = 0;
  509.               nl();
  510.               if (so()) {
  511.                 if (incom) {
  512.                   prt(5, "Upload from remote? ");
  513.                   if (yn())
  514.                     remote_upld = 1;
  515.                 }
  516.                 if (!remote_upld) {
  517.                   prt(2, "Path and filename (wildcards okay) : ");
  518.                   mpl(50);
  519.                   input(s, 50);
  520.                   if (s[0]) {
  521.                     nl();
  522.                     if (strchr(s, '*') != NULL || strchr(s, '?') != NULL)
  523.                       strcpy(s, get_wildlist(s));
  524.                     if (!exist(s))
  525.                       found = 1;
  526.                     if ((!okfn(stripfn(s))) || (strchr(s, '?')))
  527.                       found = 1;
  528.                   }
  529.                   if ((!found) && (s[0])) {
  530.                     sprintf(s1, "%s%s", attach_dir, stripfn(s));
  531.                     nl();
  532.                     npr("5%s? ", s);
  533.                     if (!yn())
  534.                       found = 1;
  535.                   }
  536.                 }
  537.               }
  538.               if ((!so()) || (remote_upld)) {
  539.                 prt(2, get_string(44));
  540.                 mpl(12);
  541.                 input(s, 12);
  542.                 sprintf(s1, "%s%s", attach_dir, s);
  543.                 if ((!okfn(s)) || (strchr(s, '?')))
  544.                   found = 1;
  545.               }
  546.               if (exist(s1)) {
  547.                 pl("Target file exists.");
  548.                 do {
  549.                   found = 1;
  550.                   prt(5, "New name? ");
  551.                   if (yn()) {
  552.                     prt(5, get_string(44));
  553.                     mpl(12);
  554.                     input(s3, 12);
  555.                     sprintf(s1, "%s%s", attach_dir, s3);
  556.                     if ((okfn(s3)) && (!strchr(s3, '?')) && (!exist(s1))) {
  557.                       found = 0;
  558.                       done3 = newname = 1;
  559.                     } else
  560.                       pl("Try Again.");
  561.                   } else
  562.                     done3 = 1;
  563.                 } while ((!done3) && (!hangup));
  564.               }
  565.               sprintf(s2, "%sATTACH.DAT", syscfg.datadir);
  566.               f1 = sh_open(s2, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE); /* B */
  567.               if (f1 > -1) {
  568.                 l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  569.                 while ((l1 > 0) && (!found))
  570.                   if (m.daten == fsr.id)
  571.                     found = 1;
  572.                   else
  573.                     l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  574.                 f1 = sh_close(f1);
  575.               }
  576.               if (found) {
  577.                 pl("File already exists or invalid filename.");
  578.               } else {
  579.                 if ((so()) && (!remote_upld)) {
  580.                   if ((b = malloca(16400)) == NULL) {
  581.                     f = sh_close(f);
  582.                     return;
  583.                   }
  584.                   d1 = sh_open1(s,
  585.                       O_RDONLY | O_BINARY);
  586.                   d2 = sh_open(s1,
  587.                       O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  588.                   if ((d1 > -1) && (d2 > -1)) {
  589.                     i = sh_read(d1, (void *) b, 16384);
  590.                     outstr("Copying.");
  591.                     while (i > 0) {
  592.                       outstr(".");
  593.                       sh_write(d2, (void *) b, i);
  594.                       i = sh_read(d1, (void *) b, 16384);
  595.                     }
  596.                     r.h.ah = 0x57;
  597.                     r.h.al = 0;
  598.                     r.x.bx = d1;
  599.                     int86(0x21, &r, &r);
  600.                     r.h.ah = 0x57;
  601.                     r.h.al = 1;
  602.                     r.x.bx = d2;
  603.                     int86(0x21, &r, &r);
  604.                     d1 = sh_close(d1);
  605.                     d2 = sh_close(d2);
  606.                     bbsfree(b);
  607.                     outstr("done.");
  608.                     nl();
  609.                     ok = 1;
  610.                   } else {
  611.                     nl();
  612.                     ansic(6);
  613.                     pl("Error in copy.");
  614.                     getkey();
  615.                   }
  616.                 } else {
  617.                   sprintf(s1, "%s%s", attach_dir, s);
  618.                   receive_file(s1, &ok, &u_filetype, "", 0);
  619.                 }
  620.                 if (ok) {
  621.                   f1 = sh_open1(s1, O_RDONLY | O_BINARY);
  622.                   if (f1 < 0) {
  623.                     ok = 0;
  624.                     nl();
  625.                     nl();
  626.                     pl("DOS error - File not found.");
  627.                     nl();
  628.                   } else {
  629.                     fsr.numbytes = filelength(f1);
  630.                     f1 = sh_close(f1);
  631.                     if (newname)
  632.                       strcpy(fsr.filename, stripfn(s3));
  633.                     else
  634.                       strcpy(fsr.filename, stripfn(s));
  635.                     fsr.id = m.daten;
  636.                     sprintf(s, "Attach %s (%ld bytes) to Email? ",
  637.                       fsr.filename, fsr.numbytes);
  638.                     prt(5, s);
  639.                     if (yn()) {
  640.                       m.status ^= status_file;
  641.                       sh_lseek(f, ((long) sizeof(mailrec)) * -1L, SEEK_CUR);
  642.                       sh_write(f, (void *) (&m), sizeof(mailrec));
  643.                       sprintf(s2, "%sATTACH.DAT", syscfg.datadir);
  644.                       f1 = sh_open(s2,
  645.                           O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  646.                       if (f1 < 0) {
  647.                         pl("Could not write attachment data.");
  648.                         m.status ^= status_file;
  649.                         sh_lseek(f, ((long) sizeof(mailrec)) * -1L, SEEK_CUR);
  650.                         sh_write(f, (void *) (&m), sizeof(mailrec));
  651.                       } else {
  652.                         fsr1.id = 1;
  653.                         do {
  654.                           l1 = sh_read(f1, (void *) (&fsr1),
  655.                               sizeof(filestatusrec));
  656.                         } while ((l1 > 0) && (fsr1.id != 0));
  657.                         if (fsr1.id == 0)
  658.                           sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  659.                         else
  660.                           sh_lseek(f1, 0L, SEEK_END);
  661.                         sh_write(f1, (void *) (&fsr), sizeof(filestatusrec));
  662.                         f1 = sh_close(f1);
  663.                         sprintf(s1, "Attached %s (%ld bytes) in message to %s",
  664.                           fsr.filename, fsr.numbytes, nam(&u, m.touser));
  665.                         pl("File attached.");
  666.                         sysoplog(s1);
  667.                       }
  668.                     } else {
  669.                       sprintf(s1, "%s%s", attach_dir, fsr.filename);
  670.                       unlink(s1);
  671.                     }
  672.                   }
  673.                 }
  674.               }
  675.             }
  676.           }
  677.           break;
  678.         case 'N':
  679.           done1 = 1;
  680.           if (forward)
  681.             --cur;
  682.           else
  683.             ++cur;
  684.           if ((cur >= max) || (cur < 0))
  685.             done = 1;
  686.           break;
  687.         case 'R':
  688.           nl();
  689.           nl();
  690.           strcpy(s, "Title: ");
  691.           strcat(s, m.title);
  692.           pl(s);
  693.           setorigin(0, 0);
  694.           read_message1(&m.msg, (m.anony & 0x0f), 0, &i1, "EMAIL");
  695.           if (m.status & status_file) {
  696.             sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  697.             f1 = sh_open(s, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); /* B */
  698.             if (f1 > -1) {
  699.               found = 0;
  700.               l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  701.               while ((l1 > 0) && (!found)) {
  702.                 if (m.daten == fsr.id) {
  703.                   sprintf(s, "Attached file: %s (%ld bytes).",
  704.                     fsr.filename, fsr.numbytes);
  705.                   pl(s);
  706.                   found = 1;
  707.                 }
  708.                 if (!found)
  709.                   l1 = sh_read(f1, (void *) (&fsr), sizeof(fsr));
  710.               }
  711.               if (!found)
  712.                 pl("File attached but attachment data missing.  Alert sysop!");
  713.               f1 = sh_close(f1);
  714.             } else
  715.               pl("File attached but attachment data missing.  Alert sysop!");
  716.           }
  717.           break;
  718.         }
  719.       } while ((!hangup) && (!done1));
  720.     }
  721.   } while ((!done) && (!hangup));
  722.   f = sh_close(f);
  723. }
  724.  
  725. unsigned char *get_wildlist(char *s)
  726. {
  727.   int i, mark;
  728.   char *path, t;
  729.   struct ffblk mrff;
  730.  
  731.   if (findfirst(s, &mrff, 0) == -1) {
  732.     pl("No files found");
  733.     s[0] = 0;
  734.     return (s);
  735.   } else
  736.     npr("%12.12s ", mrff.ff_name);
  737.   if (strchr(s, '\\') == NULL)
  738.     s[0] = 0;
  739.   else
  740.     for (i = 0; i < strlen(s); i++)
  741.       if (s[i] == '\\')
  742.         mark = i + 1;
  743.   t = s[mark];
  744.   s[mark] = 0;
  745.   strcpy(path, s);
  746.   s[mark] = t;
  747.   t = strlen(path);
  748.   strcat(path, mrff.ff_name);
  749.   for (i = 1;; i++) {
  750.     if (i % 5 == 0)
  751.       nl();
  752.     if (findnext(&mrff) == -1)
  753.       break;
  754.     npr("%12.12s ", mrff.ff_name);
  755.     if (inkey() == 32) {
  756.       nl();
  757.       break;
  758.     }
  759.   }
  760.   nl();
  761.   if (i == 1) {
  762.     npr("One file found: %s\r\n", mrff.ff_name);
  763.     outstr("Use this file? ");
  764.     if (yn())
  765.       return (path);
  766.     else {
  767.       path[0] = 0;
  768.       return (path);
  769.     }
  770.   }
  771.   path[t] = 0;
  772.   outstr("Filename: ");
  773.   mpl(12);
  774.   input(s, 12);
  775.   strcat(path, s);
  776.   return (path);
  777. }
  778.  
  779. Save <READMAIL.C>
  780.  
  781. *** Step Six ***
  782.  
  783. Open <MISCCMD.C>
  784.  
  785. Search for "void kill_old_email(void)" and add/modify the declarations:
  786.  
  787. ==  int cur,max,i,i1,f,done,done1,forward;
  788. =+  char s[161],s1[81],ch;   /* Expands the size of 's' and adds 's1' */
  789. ==  long l;
  790. ==  mailrec m, m1;
  791. ==  userrec u;
  792. ==  slrec ss;
  793. ++  filestatusrec fsr;
  794. ++  int f1, found;
  795. ++  long l1;
  796. ==
  797. ==  if (rip_on()) {
  798.  
  799. Search down about a hundred lines and add this chunk of code where indicated:
  800.  
  801. ==        npr("%d ",i);
  802. ==        pl(get_string(506));
  803. /* BEGIN BLOCK READ */
  804.         if (m.status & status_file) {
  805.           sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  806.           f1 = sh_open(s, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); /* B */
  807.           if (f1 > -1) {
  808.             found = 0;
  809.             l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  810.             while ((l1 > 0) && (!found)) {
  811.               if (m.daten == fsr.id) {
  812.                 if (E_C)
  813.                   sprintf(s, "%s2%s (%ld bytes)0",
  814.                     get_string(659), fsr.filename, fsr.numbytes);
  815.                 else
  816.                   sprintf(s, "File : %s (%ld bytes)",
  817.                     fsr.filename, fsr.numbytes);
  818.                 pl(s);
  819.                 found = 1;
  820.               }
  821.               if (!found)
  822.                 l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  823.             }
  824.             if (!found)
  825.               if (E_C) {
  826.                 sprintf(s, "%s2Unknown or missing0", get_string(659));
  827.                 pl(s);
  828.               } else
  829.                 pl("File : Unknown or Missing");
  830.             sh_close(f1);
  831.           } else
  832.             if (E_C) {
  833.               sprintf(s, "%s2Unknown or missing0", get_string(659));
  834.               pl(s);
  835.             } else
  836.               pl("File : Unknown or Missing");
  837.         }
  838. /* END BLOCK READ */
  839. ==        nl();
  840. ==        prt(2,get_string(507));
  841. ==        ch=onek("QRDN");
  842.  
  843. A few lines further down, delete case 'D' and replace it with this:
  844.  
  845. ==          case 'D':
  846. /* BEGIN BLOCK READ */
  847.             done1=1;
  848.             f=open_email(1);
  849.             sh_lseek(f,((long) cur) * sizeof(mailrec), SEEK_SET);
  850.             sh_read(f,(void *)&m1,sizeof(mailrec));
  851.             if (memcmp(&m, &m1, sizeof(mailrec))==0) {
  852.               delmail(f,cur);
  853.               found = 0;
  854.               if (m.status & status_file) {
  855.                 sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  856.                 f1 = sh_open1(s, O_RDWR | O_BINARY);
  857.                 if (f1 > -1) {
  858.                   l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  859.                   while ((l1 > 0) && (!found)) {
  860.                     if (m.daten == fsr.id) {
  861.                       found = 1;
  862.                       fsr.id = 0;
  863.                       sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  864.                       sh_write(f1, (void *)(&fsr), sizeof(filestatusrec));
  865.                       sprintf(s1, "%s%s", attach_dir, fsr.filename);
  866.                       unlink(s1);
  867.                     } else
  868.                       l1 = sh_read(f1, (void *)(&fsr), sizeof(filestatusrec));
  869.                   }
  870.                   f1 = sh_close(f1);
  871.                 }
  872.               }
  873.               nl();
  874.               if (found) {
  875.                 pl("Mail and file deleted.");
  876.                 nl();
  877.                 sprintf(s, "Deleted mail and attached file %s.",
  878.                     fsr.filename);
  879.                 sysoplog(s);
  880.               } else {
  881.                 pl(get_string(508));
  882.                 nl();
  883.                 sprintf(s1,get_stringx(1, 100),nam(&u,m1.touser));
  884.                 sysoplog(s1);
  885.               }
  886.             } else {
  887.               pl(get_string(1174));
  888.             }
  889.             f=sh_close(f);
  890.             break;
  891. /* END BLOCK READ */
  892. ==          case 'R':
  893.  
  894. Save <MISCCMD.C>
  895.  
  896. ** Step Seven **
  897.  
  898. Open <SYSOPF.C>
  899.  
  900. Search for "void mailr(void)" and add these to the declarations:
  901.  
  902. ==  userrec u;
  903. ++  filestatusrec fsr;
  904. ++  int f1, found;
  905. ++  long l1;
  906. ++  char s[161],s1[81];
  907. ==
  908. ==  f=open_email(0);
  909.  
  910. Hop down a few lines and block read in this chunk of code:
  911.  
  912. ==          set_net_num(nn);
  913. ==          outstr(get_string(326)); pl(m.title);
  914. /* BEGIN BLOCK READ */
  915.           if (m.status & status_file) {
  916.             sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  917.             f1 = sh_open(s, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); /* B */
  918.             if (f1 > -1) {
  919.               found = 0;
  920.               l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  921.               while ((l1 > 0) && (!found)) {
  922.                 if (m.daten == fsr.id) {
  923.                   if (E_C)
  924.                     sprintf(s, "%s2%s (%ld bytes)0",
  925.                       get_string(659), fsr.filename, fsr.numbytes);
  926.                   else
  927.                     sprintf(s, "File : %s (%ld bytes)",
  928.                       fsr.filename, fsr.numbytes);
  929.                   pl(s);
  930.                   found = 1;
  931.                 }
  932.                 if (!found)
  933.                   l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  934.               }
  935.               if (!found)
  936.                 if (E_C) {
  937.                   sprintf(s, "%s2Unknown or missing0", get_string(659));
  938.                   pl(s);
  939.                 } else
  940.                   pl("File : Unknown or Missing");
  941.               f1 = sh_close(f1);
  942.             } else {
  943.               if (E_C) {
  944.                 sprintf(s, "%s2Unknown or missing0", get_string(659));
  945.                 pl(s);
  946.               } else
  947.                 pl("File : Unknown or Missing");
  948.             }
  949.           }
  950. /* END BLOCK READ */
  951. ==          setorigin(m.fromsys, m.fromuser);
  952. ==          read_message1(&(m.msg),m.anony & 0x0f,1,&next,"EMAIL");
  953.  
  954. A few lines further down, modify this code (note the two changed lines before
  955. and after the block read!)
  956.  
  957. ==          if (c=='D') {
  958. ==            f=open_email(1);
  959. ==            sh_lseek(f,((long) (i)) * ((long) sizeof(mailrec)),SEEK_SET);
  960. ==            sh_read(f,(void *)&m1,sizeof(mailrec));
  961. =+            if (memcmp(&m, &m1, sizeof(mailrec))==0) {/* CHANGE THIS LINE! */
  962. ==              delmail(f,i);
  963. /* BEGIN BLOCK READ */
  964.               found = 0;
  965.               if (m.status & status_file) {
  966.                 sprintf(s, "%sATTACH.DAT", syscfg.datadir);
  967.                 f1 = sh_open1(s, O_RDWR | O_BINARY);
  968.                 if (f1 > -1) {
  969.                   l1 = sh_read(f1, (void *)(&fsr), sizeof(fsr));
  970.                   while ((l1 > 0) && (!found)) {
  971.                     if (m.daten == fsr.id) {
  972.                       found = 1;
  973.                       fsr.id = 0;
  974.                       sh_lseek(f1, sizeof(filestatusrec) * -1L, SEEK_CUR);
  975.                       sh_write(f1, (void *)(&fsr), sizeof(filestatusrec));
  976.                       sprintf(s1, "%s%s", attach_dir, fsr.filename);
  977.                       unlink(s1);
  978.                     } else
  979.                       l1 = sh_read(f1, (void *)(&fsr), sizeof(filestatusrec));
  980.                   }
  981.                   f1 = sh_close(f1);
  982.                 }
  983.               }
  984. /* END BLOCK READ */
  985. =+            } else       /* CHANGE THIS LINE! */
  986. ==              pl(get_string(1308));
  987. ==            f=sh_close(f);
  988.  
  989. Save <SYSOPF.C>
  990.  
  991. ** Step Eight **
  992.  
  993. Open <MSGBASE.C>
  994.  
  995. Search for "void sendout_email(char *title, ..etc.. int fwd, int fnn)" and add
  996. the following lines:
  997.  
  998. ==      sysoplog(s1);
  999. ==      strcat(s,get_string(482));
  1000. ==    }
  1001. ++    if ((sy==0) && (actsl>syscfg.newusersl) && (ur.forwardsys==0)) {  /*C*/
  1002. ++      nln(2);
  1003. ++      prt(5,"Attach a file to this message? ");
  1004. ++      if (yn())
  1005. ++        attach_file(1);
  1006. ++    }
  1007. ==  } else {
  1008. ==    if (net_num_max>1) {
  1009.  
  1010. Save <MSGBASE.C>
  1011.  
  1012. ** Step Nine **
  1013.  
  1014. Open <XINIT.C>
  1015.  
  1016. Search for "void init(void)" and add the declaration near the top:
  1017.  
  1018. ==void init(void)
  1019. =={
  1020. ==  char *ss,s[161];
  1021. ++  unsigned char olddir[81];
  1022. ==  int i,i1,sm;
  1023. ==  int f1,f2,f3,f4,f5,f6,f7, pk;
  1024. ==#ifndef __OS2__
  1025.  
  1026. Hop down a couple hundred lines and add this code:
  1027.  
  1028. ==  if (!read_ini_info()) {
  1029. ==    printf("Insufficient memory for system info structure.\n");
  1030. ==    end_bbs(noklevel);
  1031. ==  }
  1032. /* BEGIN BLOCK READ */
  1033.   get_dir(olddir,1);
  1034.  
  1035.   attach_dir[0] = 0;
  1036.   if (ini_init("WWIV.INI", "WWIV", NULL) == 0) {
  1037.     if ((ss = ini_get("ATTACH_DIR", -1, NULL)) != NULL)
  1038.       if (ss)
  1039.         strcpy(attach_dir, ss);
  1040.     ini_done();
  1041.   }
  1042.   if (attach_dir[0] == 0)
  1043.     sprintf(attach_dir, "%sATTACHES\\", syscfg.datadir);
  1044.   strcpy(s, attach_dir);
  1045.   i = strlen(s);
  1046.   if (s[0] == 0)
  1047.     i1 = 1;
  1048.   else {
  1049.     if (s[i-1] != '\\') {
  1050.       attach_dir[i] = '\\';
  1051.       attach_dir[i+1] = 0;
  1052.     } else
  1053.       if (s[i-2] != ':')
  1054.         s[i-1]=0;
  1055.     i1=chdir(s);
  1056.   }
  1057.  
  1058.   if (i1) {
  1059.     cd_to(cdir);
  1060.     if (mkdir(s)) {
  1061.       printf("Unable to create attach directory: %s\r\n", attach_dir);
  1062.       getkey();
  1063.     }
  1064.   } else
  1065.     cd_to(cdir);
  1066.   cd_to(olddir);
  1067. /* END BLOCK READ */
  1068. ==  net_networks=NULL;
  1069.  
  1070. Save <XINIT.C>
  1071.  
  1072. ** Step Ten **
  1073.  
  1074. This is not necessary if you can/do use 'MAKE FCNS' from the commandline.
  1075.  
  1076. Open <FCNS.H>
  1077.  
  1078. Search for "/* File: readmail.c */" and prototype the new functions:
  1079.  
  1080. ==void add_netsubscriber(unsigned short sn);
  1081. ==void readmail(void);
  1082. ++void attach_file(int mode);
  1083. ++unsigned char *get_wildlist(char *s);
  1084.  
  1085. Save <FCNS.H>
  1086.  
  1087. ** Last Step **
  1088.  
  1089. Open <WWIV.INI>
  1090.  
  1091. In the [WWIV] section, add the path for your directory to store attached
  1092. files, like:
  1093.  
  1094. ==[WWIV]
  1095. ++;
  1096. ++; Directory for attached files
  1097. ++;
  1098. ++ATTACH_DIR      = C:\WWIV\ATTACH
  1099. ==;
  1100. ==; Default spawn options
  1101. ==;
  1102. ==;SPAWNOPT[TIMED]        = SHRINK, FILES                 ; for timed event
  1103.  
  1104. Save <WWIV.INI>
  1105.  
  1106. Recompile.  Update your menu to reflect the //ATTACH command, if you want.
  1107.  
  1108. Drop me a note to say you like (or hate) this mod so I make more!
  1109.  
  1110.