home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / UTIL / WWIVSOR / QWK.C < prev    next >
Text File  |  1995-05-12  |  39KB  |  1,847 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15.  
  16.  
  17. #include "vars.h"
  18.  
  19. #pragma hdrstop
  20.  
  21. #include "subxtr.h"
  22. #include "vardec1.h"
  23.  
  24. #include <conio.h>
  25. #include <ctype.h>
  26.  
  27.  
  28. #ifdef STATS
  29. #include <sys\timeb.h>
  30. #endif
  31.  
  32.  
  33. char *QWKFrom="0QWKFrom:";
  34. int qwk_bi_mode;
  35. static int qwk_percent;
  36. static char qwk_opened_filename[81];
  37. static int qwk_opened_file;
  38. static unsigned max_msgs;
  39.  
  40.  
  41.  
  42.  
  43.  
  44. void build_qwk_packet(void)
  45. {
  46.   struct qwk_junk qwk_info;
  47.   struct qwk_config qwk_cfg;
  48.   char filename[201];
  49.   int i, msgs_ok, abort=0, save_conf=0;
  50.   long *save_qsc_p;
  51.  
  52.   save_qsc_p=qwk_save_qscan();
  53.   if(!save_qsc_p)
  54.     return;
  55.  
  56.   remove_from_temp("*.*", QWK_DIRECTORY, 0);
  57.  
  58. #ifdef STATS
  59. {
  60.   timeb time1, time2;
  61.   long double diff1, diff2;
  62.   float diff3;
  63.   char temp[81];
  64.   ftime(&time1);
  65. #endif
  66.  
  67.  
  68.  
  69.   if ((uconfsub[1].confnum!=-1) && (okconf(&thisuser)))
  70.   {
  71.     save_conf=1;
  72.     tmp_disable_conf(1);
  73.   }
  74.   tmp_disable_pause(1);
  75.  
  76.  
  77.   read_qwk_cfg(&qwk_cfg);
  78.   max_msgs=qwk_cfg.max_msgs;
  79.   if(thisuser.qwk_max_msgs < max_msgs && thisuser.qwk_max_msgs)
  80.     max_msgs=thisuser.qwk_max_msgs;
  81.  
  82.   if(!qwk_cfg.fu)
  83.     qwk_cfg.fu=time(NULL);
  84.  
  85.  
  86.   ++qwk_cfg.timesd;
  87.   write_qwk_cfg(&qwk_cfg);
  88.   close_qwk_cfg(&qwk_cfg);
  89.  
  90.  
  91.   write_inst(INST_LOC_QWK, usub[cursub].subnum, INST_FLAGS_ONLINE);
  92.   read_status();
  93.  
  94.  
  95.   sprintf(filename, "%sMESSAGES.DAT", QWK_DIRECTORY);
  96.   qwk_info.file=sh_open1(filename, O_RDWR | O_BINARY | O_CREAT);
  97.  
  98.   if(qwk_info.file<1)
  99.   {
  100.     pl(get_string(1530));
  101.     sysoplog(get_stringx(1,120));
  102.     return;
  103.   }
  104.  
  105.  
  106.   // Setup my optimized open files
  107.   qwk_opened_filename[0]=0;
  108.   qwk_opened_file=-1;
  109.  
  110.   // Setup index and other values
  111.   qwk_info.index=-1;
  112.   qwk_info.cursub=-1;
  113.  
  114.   qwk_info.in_email=0;
  115.   qwk_info.personal=-1;
  116.   qwk_info.zero=-1;
  117.  
  118.  
  119.   memset(&qwk_info.qwk_rec, ' ', sizeof(qwk_info.qwk_rec));
  120.   strcpy((char *)&qwk_info.qwk_rec, get_string(1532));
  121.   append_block(qwk_info.file, (void *)&qwk_info.qwk_rec, sizeof(qwk_info.qwk_rec));
  122.  
  123.   // Logical record number
  124.   qwk_info.qwk_rec_num=1;
  125.   qwk_info.qwk_rec_pos=2;
  126.  
  127.   qwk_info.abort=0;
  128.  
  129.   if(!thisuser.qwk_dont_scan_mail && !qwk_info.abort)
  130.     qwk_gather_email(&qwk_info);
  131.  
  132.   checka(&abort, &abort);
  133.   if(abort)
  134.     qwk_info.abort=abort;
  135.  
  136.   CLS();
  137.   if(!qwk_info.abort)
  138.   {
  139.     ansic(9);
  140.     outchr('┌');   /* "9┌────┬────────────────────────────────────────────────────────────┬─────┬────┐" */
  141.     repeat_char('─', 4);
  142.     outchr('┬');
  143.     repeat_char('─', 60);
  144.     outchr('┬');
  145.     repeat_char('─', 5);
  146.     outchr('┬');
  147.     repeat_char('─', 4);
  148.     outchr('┐');
  149.     nl();
  150.   }
  151.  
  152.   
  153.   checka(&abort, &abort);
  154.   if(abort)
  155.     qwk_info.abort=abort;
  156.  
  157.   if(!qwk_info.abort)
  158.   {
  159.     ansic(9);  /* "9│2Sub1 │2Sub name                                                    9│8Total9│5New 9│" */
  160.     outchr('│');
  161.     ansic(2);
  162.     outstr(get_string(1533));
  163.     ansic(9);
  164.     outchr('│');
  165.     ansic(3);
  166.     outstr(get_string(1534));
  167.     repeat_char(' ', 52);
  168.     ansic(9);
  169.     outchr('│');
  170.     ansic(8);
  171.     outstr(get_string(1535));
  172.     ansic(9);
  173.     outchr('│');
  174.     ansic(5);
  175.     outstr(get_string(1536));
  176.     ansic(9);
  177.     outchr('│');
  178.     nl();
  179.   }
  180.  
  181.  
  182.   checka(&abort, &abort);
  183.   if(abort)
  184.     qwk_info.abort=abort;
  185.  
  186.   if(!qwk_info.abort)
  187.   {
  188.     ansic(9);     /* "9├────┼────────────────────────────────────────────────────────────┼─────┼────┤" */
  189.     outchr('├');
  190.     repeat_char('─', 4);
  191.     outchr('┼');
  192.     repeat_char('─', 60);
  193.     outchr('┼');
  194.     repeat_char('─', 5);
  195.     outchr('┼');
  196.     repeat_char('─', 4);
  197.     outchr('┤');
  198.     nl();
  199.   }
  200.  
  201.   msgs_ok=1;
  202.  
  203.   for (i=0; (usub[i].subnum!=-1) && (i<num_subs) && (!hangup) && !qwk_info.abort && msgs_ok; i++)
  204.   {
  205.  
  206.     msgs_ok = (max_msgs ? qwk_info.qwk_rec_num <= max_msgs : 1);
  207.  
  208.     if(qsc_q[usub[i].subnum/32]&(1L<<(usub[i].subnum%32)))
  209.       qwk_gather_sub(i,&qwk_info);
  210.   }
  211.  
  212.   ansic(9);      /* "9└────┴────────────────────────────────────────────────────────────┴─────┴────┘" */
  213.   outchr('└');
  214.   repeat_char('─', 4);
  215.   outchr('┴');
  216.   repeat_char('─', 60);
  217.   outchr('┴');
  218.   repeat_char('─', 5);
  219.   outchr('┴');
  220.   repeat_char('─', 4);
  221.   outchr('┘');
  222.   nln(2);
  223.  
  224.   if(qwk_info.abort)
  225.   {
  226.     ansic(1);
  227.     outstr(get_string(1537));
  228.     if(!yn())
  229.       qwk_info.abort=0;
  230.   }
  231.  
  232.   qwk_info.file=sh_close(qwk_info.file);
  233.   qwk_info.index=sh_close(qwk_info.index);
  234.   qwk_info.personal=sh_close(qwk_info.personal);
  235.   qwk_info.zero=sh_close(qwk_info.zero);
  236.  
  237.  
  238.   if(!qwk_info.abort)
  239.     build_control_dat(&qwk_info);
  240.  
  241.  
  242. #ifdef STATS
  243.     ftime(&time2);
  244.     diff1=(long double)time1.time+((long double)time1.millitm/(long double)1000);
  245.     diff2=(long double)time2.time+((long double)time2.millitm/(long double)1000);
  246.  
  247.     diff3=diff2-diff1;
  248.  
  249.     sprintf(temp, get_stringx(1,136), diff3);
  250.     sysoplog(temp);
  251.   }
  252. #endif
  253.  
  254.  
  255.  
  256.   if(!qwk_info.abort)
  257.     finish_qwk(&qwk_info);
  258.  
  259.  
  260.   // Restore on hangup too, someone might have hungup in the middle of
  261.   // building the list
  262.   if(qwk_info.abort || thisuser.qwk_dontsetnscan || hangup)
  263.     qwk_restore_qscan(save_qsc_p);  // restore nscan pointers if we aborted
  264.  
  265.   if(qwk_info.abort)
  266.     sysoplog(get_stringx(1,119));
  267.  
  268.   bbsfree(save_qsc_p);         /* free up memory allocated to save qsc pointers */
  269.  
  270.   if(thisuser.qwk_delete_mail && !qwk_info.abort)
  271.     qwk_remove_email(); // Delete email
  272.  
  273.   read_status();
  274.  
  275.   if(save_conf)
  276.     tmp_disable_conf(0);
  277.   tmp_disable_pause(0);
  278.  
  279.   // Close down my optimized open files
  280.   qwk_opened_filename[0]=0;
  281.   if(qwk_opened_file>0)
  282.     sh_close(qwk_opened_file);
  283.  
  284. }
  285.  
  286.  
  287.  
  288.  
  289. void qwk_gather_sub(int bn, struct qwk_junk *qwk_info)
  290. {
  291.   int i,os,sn;
  292.   char subinfo[201], thissub[81];
  293.   unsigned long qscnptrx,sd;
  294.  
  295.   float temp_percent;
  296.  
  297.  
  298.  
  299.   sn=usub[bn].subnum;
  300.  
  301.   if ((hangup) || (sn<0))
  302.     return;
  303.  
  304.  
  305.   qscnptrx=qsc_p[sn];
  306.   sd=sub_dates[sn];
  307.  
  308.   if (qwk_percent || ((!sd) || (sd>qscnptrx)) )
  309.   {
  310.     int ab=0;
  311.     os=cursub;
  312.     cursub=bn;
  313.     i=1;
  314.  
  315.  
  316.     // Get total amount of messages in base
  317.     if (!qwk_iscan(cursub))
  318.       return;
  319.  
  320.     qscnptrx=qsc_p[sn];
  321.  
  322.     if(!qwk_percent)
  323.     {
  324.       // Find out what message number we are on
  325.       for (i=nummsgs; (i>1) && (get_post(i-1)->qscan>qscnptrx); i--)
  326.         ;
  327.     }
  328.     else  // Get last qwk_percent of messages in sub
  329.     {
  330.       temp_percent=(float)qwk_percent/100.0;
  331.       if(temp_percent>1.0)
  332.         temp_percent=1.0;
  333.       i=nummsgs-(temp_percent * nummsgs);
  334.     }
  335.  
  336.  
  337.     strncpy(thissub, subboards[curlsub].name, 65);
  338.     thissub[60]=0;
  339.     sprintf(subinfo, "9│2%-4d9│2%-60s9│ 8%-4d9│5%-4d9│",
  340.                      bn+1, thissub, nummsgs,
  341.                      nummsgs-i+1-(qwk_percent ? 1 : 0));
  342.     pl(subinfo);
  343.  
  344.     checka(&ab, &ab);
  345.     if(ab)
  346.       qwk_info->abort=1;
  347.  
  348.  
  349.     if ((nummsgs>0) && (i<=nummsgs) && !qwk_info->abort)
  350.     {
  351.       if ((get_post(i)->qscan>qsc_p[curlsub]) || qwk_percent)
  352.         qwk_start_read(i, qwk_info);   // read messsage
  353.     }
  354.  
  355.     read_status();
  356.     qsc_p[curlsub]=status.qscanptr-1;
  357.     
  358.     cursub=os;
  359.   }
  360.   else
  361.   {
  362.     int ab=0;
  363.  
  364.     os=cursub;
  365.     cursub=bn;
  366.     i=1;
  367.  
  368.     qwk_iscan(cursub);
  369.     
  370.     strncpy(thissub, subboards[curlsub].name, 65);
  371.     thissub[60]=0;
  372.     sprintf(subinfo, "9│2%-4d9│2%-60s9│ 8%-4d9│5%-4d9│",
  373.                       bn+1, thissub, nummsgs, 0);
  374.     pl(subinfo);
  375.  
  376.     cursub=os;
  377.  
  378.     checka(&ab, &ab);
  379.  
  380.     if(ab)
  381.       qwk_info->abort=1;
  382.   }
  383.  
  384.   ansic(0);
  385. }
  386.  
  387.  
  388. void qwk_start_read(int msgnum, struct qwk_junk *qwk_info)
  389. {
  390.   statusbarrec sb;
  391.   int done, val;
  392.   int amount=1;
  393.   int abort=0;
  394.  
  395.  
  396.   irt[0]=0;
  397.   irt_name[0]=0;
  398.   done=0;
  399.   val=0;
  400.  
  401.   if (curlsub<0)
  402.     return;
  403.  
  404.  
  405.   sb.width=10;
  406.   sb.amount_per_square=4;
  407.   sb.square_list[0]='■';
  408.   sb.square_list[1]='░';
  409.   sb.square_list[2]='▒';
  410.   sb.square_list[3]='▓';
  411.   sb.empty_space='-';
  412.   sb.side_char1='[';
  413.   sb.side_char2=']';
  414.   sb.surround_color=BLUE;
  415.   sb.box_color=GREEN+(BLUE<<4);
  416.   sb.total_items=nummsgs-msgnum+1;
  417.   sb.current_item=0;
  418.  
  419.   outchr('\t');
  420.   statusbar(&sb);
  421.  
  422.   // Used to be inside do loop
  423.   if (xsubs[curlsub].num_nets)
  424.     set_net_num(xsubs[curlsub].nets[0].net_num);
  425.   else
  426.     set_net_num(0);
  427.  
  428.  
  429.   do
  430.   {
  431.     ++sb.current_item;
  432.     statusbar(&sb);
  433.  
  434.     if ((msgnum>0) && (msgnum<=nummsgs))
  435.       make_pre_qwk(msgnum, &val, qwk_info);
  436.  
  437.     ++msgnum;
  438.     if (msgnum>nummsgs)
  439.       done=1;
  440.  
  441.     if(thisuser.qwk_max_msgs_per_sub ? amount > thisuser.qwk_max_msgs_per_sub : 0)
  442.       done=1;
  443.  
  444.     if(max_msgs ? qwk_info->qwk_rec_num > max_msgs : 0)
  445.       done=1;
  446.  
  447.  
  448.     ++amount;
  449.  
  450.     checka(&abort, &abort);
  451.     if(abort)
  452.       qwk_info->abort=abort;
  453.  
  454.   } while ((!done) && (!hangup) && !qwk_info->abort);
  455.  
  456.   outchr('\r');
  457. }
  458.  
  459.  
  460.  
  461. void make_pre_qwk(int msgnum, int *val, struct qwk_junk *qwk_info)
  462. {
  463.   postrec p;
  464.   int nn;
  465.  
  466.   p=*get_post(msgnum);
  467.  
  468.   if (p.status & (status_unvalidated | status_delete))
  469.   {
  470.     if (!lcs())
  471.       return;
  472.     *val |= 1;
  473.   }
  474.  
  475.     nn=net_num;
  476.  
  477.     if (p.status & status_post_new_net)
  478.         set_net_num(p.title[80]);
  479.  
  480.   put_in_qwk(&p,(subboards[curlsub].filename), msgnum, qwk_info);
  481.  
  482.   if (nn!=net_num)
  483.     set_net_num(nn);
  484.  
  485.   ++thisuser.msgread;
  486.   ++msgreadlogon;
  487.  
  488.  
  489.   if (p.qscan>qsc_p[curlsub])  // Update qscan pointer right here
  490.     qsc_p[curlsub]=p.qscan;    // And here
  491.   if (p.qscan>=status.qscanptr)
  492.   {
  493.     lock_status();
  494.     if (p.qscan>=status.qscanptr)
  495.       status.qscanptr=p.qscan+1;
  496.     save_status();
  497.   }
  498. }
  499.  
  500. void put_in_qwk(postrec *m1, char *fn, int msgnum, struct qwk_junk *qwk_info)
  501. {
  502.   struct tm *time_now;
  503.   char n[205],d[81],*ss, temp[101];
  504.   char qwk_address[201];
  505.   int f,cur, p, p1;
  506.   messagerec m;
  507.   char filename[101], date[10];
  508.   float msbin;
  509.   int cur_block=2;
  510.  
  511.   long len;
  512.   postrec pr;
  513.  
  514.   int amount_blocks=0;
  515.  
  516.  
  517.   pr=*get_post(msgnum);
  518.  
  519.   if (pr.status & (status_unvalidated | status_delete))
  520.   {
  521.     if (!lcs())
  522.       return;
  523.   }
  524.  
  525.  
  526.   memset(&qwk_info->qwk_rec, ' ', sizeof(qwk_info->qwk_rec));
  527.  
  528.  
  529.   ss=NULL;
  530.   m=(m1->msg);
  531.   f=-1;
  532.   cur=0;
  533.  
  534. #ifdef SLOWER_BUT_SAFER
  535.   ss=readfile(&m,fn,&len);
  536. #else
  537.   ss=qwk_readfile(&m,fn,&len);
  538. #endif
  539.  
  540.   if (ss==NULL)
  541.   {
  542.     outstr(get_string(89));
  543.     nl();
  544.     return;
  545.   }
  546.  
  547.   p=0;
  548.  
  549.   // n = name...
  550.   while ((ss[p]!=13) && ((long)p<len) && (p<200) && !hangup)
  551.     n[p]=ss[p++];
  552.   n[p]=0;
  553.   ++p;
  554.  
  555.  
  556.  
  557.   // if next is ascii 10 (linefeed?) go one more...
  558.   p1=0;
  559.   if (ss[p]==10)
  560.     ++p;
  561.  
  562.   // d = date
  563.   while ((ss[p+p1]!=13) && ((long)p+p1<len) && (p1<60) && !hangup)
  564.     d[p1]=ss[(p1++)+p];
  565.   d[p1]=0;
  566.  
  567.   // ss+cur now is where the text starts
  568.   cur=p+p1+1;
  569.  
  570.  
  571.   sprintf(qwk_address, "%s%s", QWKFrom,  n);  // Copy wwivnet address to qwk_address
  572.   if(!strchr(qwk_address, '@'))
  573.   {
  574.     sprintf(temp, "@%d", m1->ownersys);
  575.     strcat(qwk_address, temp);
  576.   }
  577.  
  578.  
  579.  
  580.   // Took the annonomouse stuff out right here
  581.   if(!qwk_info->in_email)
  582.     strncpy(qwk_info->qwk_rec.to, "ALL", 3);
  583.   else
  584.   {
  585.  
  586.     strncpy(temp, thisuser.name, 25);
  587.     temp[25]=0;
  588.     strupr(temp);
  589.  
  590.     strncpy(qwk_info->qwk_rec.to, temp, 25);
  591.  
  592.   }
  593.  
  594.   strip_heart_colors(n);
  595.   strncpy(qwk_info->qwk_rec.from, strupr(n), 25);
  596.  
  597.   time_now=localtime((time_t *)&m1->daten);
  598.   strftime(date, 10, "%m-%d-%y", time_now);
  599.   strncpy(qwk_info->qwk_rec.date, date, 8);
  600.  
  601.  
  602.  
  603.   p=0;
  604.   p1=0;
  605.  
  606.   len=len-cur;
  607.   make_qwk_ready(ss+cur, &len, qwk_address);
  608.  
  609.  
  610.  
  611.   amount_blocks=((int)len/sizeof(qwk_info->qwk_rec))+2;
  612.  
  613.  
  614.   // Save Qwk Record
  615.   sprintf(qwk_info->qwk_rec.amount_blocks, "%d", amount_blocks);
  616.   sprintf(qwk_info->qwk_rec.msgnum, "%d", msgnum);
  617.  
  618.   strip_heart_colors(pr.title);
  619.   strip_heart_colors(qwk_info->email_title);
  620.  
  621.   if(!qwk_info->in_email)
  622.     strncpy(qwk_info->qwk_rec.subject, pr.title, 25);
  623.   else
  624.     strncpy(qwk_info->qwk_rec.subject, qwk_info->email_title, 25);
  625.  
  626.   qwk_remove_null((char *) &qwk_info->qwk_rec, 123);
  627.   qwk_info->qwk_rec.conf_num=usub[cursub].subnum+1;
  628.   qwk_info->qwk_rec.logical_num=qwk_info->qwk_rec_num;
  629.  
  630.  
  631.   if(append_block(qwk_info->file, (void *)&qwk_info->qwk_rec, sizeof(qwk_info->qwk_rec)) != sizeof(qwk_info->qwk_rec))
  632.   {
  633.     qwk_info->abort=1;  // Must be out of disk space
  634.     pl(get_string(1539));
  635.     pausescr();
  636.   }
  637.  
  638.  
  639.   // Save Qwk NDX
  640.   qwk_info->qwk_ndx.pos=qwk_info->qwk_rec_pos;
  641.   _fieeetomsbin(&qwk_info->qwk_ndx.pos, &msbin);
  642.   qwk_info->qwk_ndx.pos=msbin;
  643.  
  644.   qwk_info->qwk_ndx.nouse=0;
  645.  
  646.  
  647.   if(!qwk_info->in_email)   // Only if currently doing messages...
  648.   {
  649.     // Create new index if it hasnt been already
  650.     if(cursub != qwk_info->cursub || qwk_info->index < 0)
  651.     {
  652.       qwk_info->cursub=cursub;
  653.       sprintf(filename, "%s%03d.NDX", QWK_DIRECTORY, usub[cursub].subnum+1);
  654.       qwk_info->index=sh_close(qwk_info->index);
  655.       qwk_info->index=sh_open1(filename, O_RDWR | O_APPEND | O_BINARY | O_CREAT);
  656.     }
  657.  
  658.     append_block(qwk_info->index, (void *)&qwk_info->qwk_ndx, sizeof(qwk_info->qwk_ndx));
  659.   }
  660.   else  // Write to email indexes
  661.   {
  662.     append_block(qwk_info->zero, (void *)&qwk_info->qwk_ndx, sizeof(qwk_info->qwk_ndx));
  663.     append_block(qwk_info->personal, (void *)&qwk_info->qwk_ndx, sizeof(qwk_info->qwk_ndx));
  664.   }
  665.  
  666.   // Setup next NDX position
  667.   qwk_info->qwk_rec_pos+=amount_blocks;
  668.  
  669.   while(cur_block<=amount_blocks && !hangup)
  670.   {
  671.     int this_pos;
  672.     memset(&qwk_info->qwk_rec, ' ', sizeof(qwk_info->qwk_rec));
  673.  
  674.     this_pos=((cur_block-2)*sizeof(qwk_info->qwk_rec));
  675.  
  676.     if(this_pos < len)
  677.     {
  678.       memmove(&qwk_info->qwk_rec, ss+cur+this_pos, this_pos + sizeof(qwk_info->qwk_rec) > (int)len
  679.                                        ? (int)len-this_pos-1 : sizeof(qwk_info->qwk_rec));
  680.     }
  681.     // Save this block
  682.     append_block(qwk_info->file, (void *)&qwk_info->qwk_rec, sizeof(qwk_info->qwk_rec));
  683.  
  684.  
  685.     this_pos+=sizeof(qwk_info->qwk_rec);
  686.     ++cur_block;
  687.   }
  688.   // Global variable on total amount of records saved
  689.   ++qwk_info->qwk_rec_num;
  690.  
  691.   if (f!=-1)
  692.     sh_close(f);
  693.  
  694.   if(ss!=NULL)
  695.     farfree(ss);
  696.  
  697. }
  698.  
  699. // Takes text, deletes all ascii '10' and converts '13' to '227' (π)
  700. // And does other conversions as specified
  701. void make_qwk_ready(char *text, long *len, char *address)
  702. {
  703.   unsigned pos=0, new_pos=0;
  704.   char *temp;
  705.   int x;
  706.   long new_size=*len+PAD_SPACE+1;
  707.  
  708.   temp=(char *)malloca(new_size);
  709.  
  710.   if(!temp)
  711.   {
  712.     sysoplog(get_stringx(1,121));
  713.     return;
  714.   }
  715.  
  716.  
  717.  
  718.   while(pos<*len && new_pos < new_size && !hangup)
  719.   {
  720.     x=(unsigned char)text[pos];
  721.  
  722.     if(x==0)
  723.       break;
  724.  
  725.     if(x==13)
  726.     {
  727.       temp[new_pos]=227;
  728.       ++pos;
  729.       ++new_pos;
  730.     }
  731.     // Strip out Newlines, NULLS, 1's and 2's
  732.     else if(x==10 || x < 3)
  733.       ++pos;
  734.     else if(thisuser.qwk_remove_color && x==3)
  735.       pos+=2;
  736.     else if(thisuser.qwk_convert_color && x==3)
  737.     {
  738.       char ansi_string[30];
  739.       int save_curatr=curatr;
  740.  
  741.       curatr=255;
  742.  
  743.  
  744.       // Only convert to ansi if we have memory for it, but still strip heart
  745.       // code even if we don't have the memory.
  746.       if(new_pos+10 < new_size)
  747.       {
  748.         makeansi(text[pos+1], ansi_string, 1);
  749.         temp[new_pos]=0;
  750.         strcat(temp, ansi_string);
  751.         new_pos=strlen(temp);
  752.       }
  753.  
  754.       pos+=2;
  755.  
  756.       curatr=save_curatr;
  757.     }
  758.     else if(thisuser.qwk_keep_routing == FALSE && x==4 && text[pos+1]=='0')
  759.     {
  760.       if(text[pos+1]==0)
  761.         ++pos;
  762.       else
  763.       {
  764.         while((unsigned char)text[pos]!=(unsigned char)227 && text[pos]!= '\r' && pos<*len && text[pos] != 0 && !hangup)
  765.           ++pos;
  766.       }
  767.       ++pos;
  768.       if(text[pos]=='\n')
  769.         ++pos;
  770.     }
  771.     else if(x==4 && text[pos+1]!='0')
  772.       pos+=2;
  773.     else
  774.     {
  775.       temp[new_pos]=x;
  776.       ++pos;
  777.       ++new_pos;
  778.     }
  779.   }
  780.  
  781.   temp[new_pos]=0;
  782.   strcpy(text, temp);
  783.   bbsfree(temp);
  784.  
  785.   *len=new_pos;
  786.  
  787.   // Only add address if it does not yet exist
  788.   if(!strstr(text, QWKFrom+2))  // Don't search for dimond or number, just text after that
  789.     insert_after_routing(text, address, len);
  790. }
  791.  
  792.  
  793.  
  794. void qwk_remove_null(char *memory, int size)
  795. {
  796.   int pos=0;
  797.  
  798.   while(pos<size && !hangup)
  799.   {
  800.     if((char *)memory[pos]==0)
  801.       ((char *)memory)[pos]=' ';
  802.  
  803.     ++pos;
  804.   }
  805. }
  806.  
  807.  
  808.  
  809.  
  810. void build_control_dat(struct qwk_junk *qwk_info)
  811. {
  812.   FILE *fp;
  813.   struct qwk_config qwk_cfg;
  814.   int amount=0;
  815.   int cur=0;
  816.   char file[201];
  817.   char system_name[20], temp[20];
  818.   char date_time[51];
  819.   time_t secs_now;
  820.   struct tm *time_now;
  821.  
  822.   time(&secs_now);
  823.   time_now=localtime(&secs_now);
  824.  
  825.   // Creates a string like 'mm-dd-yyyy,hh:mm:ss'
  826.   strftime(date_time, 50, "%m-%d-%Y,%H:%M:%S", time_now);
  827.  
  828.   sprintf(file, "%sCONTROL.DAT", QWK_DIRECTORY);
  829.   fp=fsh_open(file, "wb");
  830.  
  831.   if (!fp)
  832.     return;
  833.  
  834.   read_qwk_cfg(&qwk_cfg);
  835.  
  836.   
  837.   qwk_system_name(system_name);
  838.  
  839.  
  840.   fprintf(fp, "%s.QWK\r\n", system_name);
  841.   fprintf(fp, "%s\r\n", "");   // System City and State
  842.   fprintf(fp, "%s\r\n", syscfg.systemphone);
  843.   fprintf(fp, "%s\r\n", syscfg.sysopname);
  844.   fprintf(fp, "%s,%s\r\n", "00000", system_name);
  845.   fprintf(fp, "%s\r\n", date_time);
  846.   fprintf(fp, "%s\r\n", thisuser.name);
  847.   fprintf(fp, "%s\r\n", "");
  848.   fprintf(fp, "%s\r\n", "0");
  849.   fprintf(fp, "%d\r\n", qwk_info->qwk_rec_num);
  850.  
  851.  
  852.   for (cur=0; (usub[cur].subnum!=-1) && (cur<num_subs) && (!hangup); cur++)
  853.   {
  854.     if (qsc_q[usub[cur].subnum/32]&(1L<<(usub[cur].subnum%32)))
  855.       ++amount;
  856.   }
  857.  
  858.   fprintf(fp, "%d\r\n", amount);
  859.  
  860.  
  861.   fprintf(fp, "0\r\n");
  862.   fprintf(fp, "E-Mail\r\n");
  863.  
  864.   for (cur=0; (usub[cur].subnum!=-1) && (cur<num_subs) && (!hangup); cur++)
  865.   {
  866.     if (qsc_q[usub[cur].subnum/32]&(1L<<(usub[cur].subnum%32)))
  867.     {
  868.       strncpy(temp, stripcolors(subboards[usub[cur].subnum].name), 13);
  869.       temp[13]=0;
  870.  
  871.       fprintf(fp, "%d\r\n", usub[cur].subnum+1);
  872.       fprintf(fp, "%s\r\n", temp);
  873.     }
  874.   }
  875.  
  876.   fprintf(fp, "%s\r\n", qwk_cfg.hello);
  877.   fprintf(fp, "%s\r\n", qwk_cfg.news);
  878.   fprintf(fp, "%s\r\n", qwk_cfg.bye);
  879.  
  880.   fsh_close(fp);
  881.   close_qwk_cfg(&qwk_cfg);
  882. }
  883.  
  884. int _fmsbintoieee(float *src4, float *dest4)
  885. {
  886.    unsigned char *msbin = (unsigned char *)src4;
  887.    unsigned char *ieee = (unsigned char *)dest4;
  888.    unsigned char sign = 0x00;
  889.    unsigned char ieee_exp = 0x00;
  890.    int i;
  891.  
  892.    /* MS Binary Format                         */
  893.    /* byte order =>    m3 | m2 | m1 | exponent */
  894.    /* m1 is most significant byte => sbbb|bbbb */
  895.    /* m3 is the least significant byte         */
  896.    /*      m = mantissa byte                   */
  897.    /*      s = sign bit                        */
  898.    /*      b = bit                             */
  899.  
  900.    sign = msbin[2] & 0x80;      /* 1000|0000b  */
  901.                                                
  902.    /* IEEE Single Precision Float Format       */
  903.    /*    m3        m2        m1     exponent   */
  904.    /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee  */
  905.    /*          s = sign bit                    */
  906.    /*          e = exponent bit                */
  907.    /*          m = mantissa bit                */
  908.  
  909.    for (i=0; i<4; i++) ieee[i] = 0;
  910.  
  911.    /* any msbin w/ exponent of zero = zero */
  912.    if (msbin[3] == 0) return 0;
  913.    
  914.    ieee[3] |= sign;
  915.  
  916.    /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places   */
  917.    /* the decimal point before the assumed bit, while          */
  918.    /* IEEE places the decimal point after the assumed bit.     */
  919.  
  920.    ieee_exp = msbin[3] - 2;    /* actually, msbin[3]-1-128+127 */
  921.  
  922.    /* the first 7 bits of the exponent in ieee[3] */
  923.    ieee[3] |= ieee_exp >> 1;   
  924.  
  925.    /* the one remaining bit in first bin of ieee[2] */
  926.    ieee[2] |= ieee_exp << 7;   
  927.  
  928.    /* 0111|1111b : mask out the msbin sign bit */
  929.    ieee[2] |= msbin[2] & 0x7f;
  930.  
  931.    ieee[1] = msbin[1];
  932.    ieee[0] = msbin[0];
  933.  
  934.    return 0;
  935. }
  936.  
  937. int _fieeetomsbin(float *src4, float *dest4)
  938. {
  939.    unsigned char *ieee = (unsigned char *)src4;
  940.    unsigned char *msbin = (unsigned char *)dest4;
  941.    unsigned char sign = 0x00;
  942.    unsigned char msbin_exp = 0x00;
  943.    int i;
  944.  
  945.    /* See _fmsbintoieee() for details of formats   */
  946.    sign = ieee[3] & 0x80;
  947.    msbin_exp |= ieee[3] << 1;
  948.    msbin_exp |= ieee[2] >> 7;
  949.  
  950.    /* An ieee exponent of 0xfe overflows in MBF    */
  951.    if (msbin_exp == 0xfe)
  952.     return 1;
  953.  
  954.    msbin_exp += 2;     /* actually, -127 + 128 + 1 */
  955.  
  956.    for (i=0; i<4; i++) msbin[i] = 0;
  957.  
  958.    msbin[3] = msbin_exp;
  959.  
  960.    msbin[2] |= sign;
  961.    msbin[2] |= ieee[2] & 0x7f;
  962.    msbin[1] = ieee[1];
  963.    msbin[0] = ieee[0];
  964.  
  965.    return 0;
  966. }
  967.  
  968.  
  969.  
  970.  
  971. char * qwk_system_name(char *qwkname)
  972. {
  973.   int x;
  974.   struct qwk_config qwk_cfg;
  975.  
  976.   read_qwk_cfg(&qwk_cfg);
  977.  
  978.   strcpy(qwkname, qwk_cfg.packet_name);
  979.   trimstr1(qwkname);
  980.  
  981.   close_qwk_cfg(&qwk_cfg);
  982.  
  983.   if(!qwkname[0])
  984.     strncpy(qwkname, syscfg.systemname, 8);
  985.  
  986.   qwkname[8]=0;
  987.   x=0;
  988.   while(qwkname[x] && !hangup && x < 9)
  989.   {
  990.     if(qwkname[x]==' ' || qwkname[x]=='.' )
  991.       qwkname[x]='-';
  992.     ++x;
  993.   }
  994.   qwkname[8]=0;
  995.   strupr(qwkname);
  996.   return(qwkname);
  997. }
  998.  
  999.  
  1000.  
  1001. void qwk_menu(void)
  1002. {
  1003.   int done=0;
  1004.   int key;
  1005.   char temp[101], namepath[101];
  1006.  
  1007.   qwk_percent=0.0;
  1008.   qwk_bi_mode=0;
  1009.  
  1010.   while(!done)
  1011.   {
  1012.     if (rip_on()) {
  1013.       if (so())
  1014.         printmenu(369);
  1015.       else
  1016.         printmenu(368);
  1017.     } else {
  1018.       CLS();
  1019.       printfile("QWK");
  1020.       if(so())
  1021.       {
  1022.         pl(get_string(1541));
  1023.       }
  1024.     }
  1025.  
  1026.     if(qwk_percent)
  1027.     {
  1028.       ansic(3);
  1029.       nl();
  1030.       npr("%s %d%%\r\n", get_string(1636), qwk_percent);
  1031.     }
  1032.     nl();
  1033.     strcpy(temp, "7[3Q1DCUBS%");
  1034.     if(so())
  1035.       strcat(temp, "1");
  1036.     strcat(temp, "7] ");
  1037.     outstr(temp);
  1038.     mpl(1);
  1039.  
  1040.     strcpy(temp, "Q\r?CDUBS%");
  1041.     if(so())
  1042.       strcat(temp, "1");
  1043.     key=onek(temp);
  1044.     if (rip_on())
  1045.       rip_cls();
  1046.  
  1047.     switch(key)
  1048.     {
  1049.       case '?':
  1050.         break;
  1051.  
  1052.       case 'Q':
  1053.       case '\r':
  1054.         done=1;
  1055.         break;
  1056.  
  1057.       case 'U':
  1058.         sysoplog(get_stringx(1,122));
  1059.         qwk_bi_mode=0;
  1060.         upload_reply_packet();
  1061.         break;
  1062.  
  1063.       case 'D':
  1064.         sysoplog(get_stringx(1,123));
  1065.         qwk_system_name(temp);
  1066.         strcat(temp, ".REP");
  1067.         sprintf(namepath, "%s%s", QWK_DIRECTORY, temp);
  1068.         unlink(namepath);
  1069.  
  1070.         build_qwk_packet();
  1071.  
  1072.         if(exist(namepath))
  1073.         {
  1074.           sysoplog(get_stringx(1,124));
  1075.           qwk_bi_mode=1;
  1076.           upload_reply_packet();
  1077.         }
  1078.         break;
  1079.  
  1080.       case 'B':
  1081.         sysoplog(get_stringx(1,125));
  1082.         qwk_bi_mode=1;
  1083.  
  1084.         qwk_system_name(temp);
  1085.         strcat(temp, ".REP");
  1086.         sprintf(namepath, "%s%s", QWK_DIRECTORY, temp);
  1087.         unlink(namepath);
  1088.  
  1089.         build_qwk_packet();
  1090.  
  1091.         if(exist(namepath))
  1092.           upload_reply_packet();
  1093.         break;
  1094.  
  1095.  
  1096.       case 'S':
  1097.         sysoplog(get_stringx(1,126));
  1098.         config_qscan();
  1099.         break;
  1100.  
  1101.       case 'C':
  1102.         sysoplog(get_stringx(1,127));
  1103.         config_qwk();
  1104.         break;
  1105.  
  1106.       case '%':
  1107.         sysoplog(get_stringx(1,129));
  1108.         ansic(2);
  1109.         outstr(get_string(1548));
  1110.         mpl(3);
  1111.         input(temp, 3);
  1112.         qwk_percent=atoi(temp);
  1113.         if(qwk_percent>100.0)
  1114.           qwk_percent=100.0;
  1115.         break;
  1116.  
  1117.       case '1':
  1118.         if(so())
  1119.         {
  1120.           sysoplog(get_stringx(1,128));
  1121.           qwk_sysop();
  1122.         }
  1123.         break;
  1124.  
  1125.     }
  1126.   }
  1127. }
  1128.  
  1129. void qwk_send_file(char *fn, int *sent, int *abort)
  1130. {
  1131.   int i,i1;
  1132.   double percent;
  1133.  
  1134.   *sent=0;
  1135.   *abort=0;
  1136.  
  1137.  
  1138.   if(thisuser.qwk_protocol<=1 || qwk_bi_mode)
  1139.   {
  1140.     if(qwk_bi_mode)
  1141.       i=get_protocol(xf_bi);
  1142.     else
  1143.       i=get_protocol(xf_down_temp);
  1144.   }
  1145.   else
  1146.     i=thisuser.qwk_protocol;
  1147.  
  1148.   percent=0.0;
  1149.  
  1150.   switch(i)
  1151.   {
  1152.     case -1:
  1153.       *abort=1;
  1154.  
  1155.       break;
  1156.     case 0:
  1157.       break;
  1158.  
  1159.     case 2:
  1160.     case 3:
  1161.     case 4:
  1162.       maybe_internal(fn, sent, &percent, 0, NULL, 1, i);
  1163.       break;
  1164.  
  1165.     default:
  1166.       i1=extern_prot(i-6,fn,1);
  1167.       *abort=0;
  1168.       if (i1==externs[i-6].ok1)
  1169.         *sent=1;
  1170.       break;
  1171.   }
  1172. }
  1173.  
  1174. int select_qwk_protocol(struct qwk_junk *qwk_info)
  1175. {
  1176.   int i;
  1177.  
  1178.   i=get_protocol(xf_down_temp);
  1179.  
  1180.   switch(i)
  1181.   {
  1182.     case -1:
  1183.       qwk_info->abort=1;
  1184.       return i;
  1185.  
  1186.     default:
  1187.       return i;
  1188.   }
  1189. }
  1190.  
  1191.  
  1192.  
  1193.  
  1194. long * qwk_save_qscan(void)
  1195. {
  1196.   long * save_qsc_p;
  1197.   int i;
  1198.  
  1199.   save_qsc_p=(long *)malloca(max_subs*sizeof(long));
  1200.   if(!save_qsc_p)
  1201.     return save_qsc_p;
  1202.  
  1203.     for (i=0; i<max_subs; i++)
  1204.         save_qsc_p[i]=qsc_p[i];
  1205.  
  1206.     return save_qsc_p;
  1207. }
  1208.  
  1209. void qwk_restore_qscan(long *save_qsc_p)
  1210. {
  1211.     int i;
  1212.  
  1213.     for (i=0; i<max_subs; i++)
  1214.         qsc_p[i]=save_qsc_p[i];
  1215. }
  1216.  
  1217.  
  1218. void insert_after_routing(char *text, char *text2insert, long *len)
  1219. {
  1220.     int pos=0;
  1221.  
  1222.   strip_heart_colors(text2insert);
  1223.  
  1224.   while(pos<*len && text[pos] != 0 && !hangup)
  1225.     {
  1226.         if(text[pos]==4 && text[pos+1]=='0')
  1227.         {
  1228.       while(pos<*len && text[pos] != 'π' && !hangup)
  1229.                 ++pos;
  1230.  
  1231.       if(text[pos]== 'π')
  1232.         ++pos;
  1233.     }
  1234.         else if(pos<*len)
  1235.         {
  1236.       char *dst, *src;
  1237.       long size;
  1238.       int addsize;
  1239.  
  1240.       strcat(text2insert, "ππ");
  1241.       addsize=strlen(text2insert);
  1242.  
  1243.       dst=text+pos+addsize;
  1244.       src=text+pos;
  1245.       size=(*len)-pos+1;
  1246.  
  1247.  
  1248.       memmove(dst, src, size);
  1249.       strncpy(src, text2insert, addsize);
  1250.  
  1251.  
  1252.       *len= (*len) + addsize;
  1253.  
  1254.       return;
  1255.     }
  1256.   }
  1257. }
  1258.  
  1259.  
  1260. void close_qwk_cfg(struct qwk_config *qwk_cfg)
  1261. {
  1262.   int x=0;
  1263.  
  1264.   while(x<qwk_cfg->amount_blts)
  1265.   {
  1266.     if(qwk_cfg->blt[x])
  1267.       bbsfree(qwk_cfg->blt[x]);
  1268.     if(qwk_cfg->bltname[x])
  1269.       bbsfree(qwk_cfg->bltname[x]);
  1270.  
  1271.     ++x;
  1272.   }
  1273. }
  1274.  
  1275.  
  1276.  
  1277. void read_qwk_cfg(struct qwk_config *qwk_cfg)
  1278. {
  1279.   int f;
  1280.   char s[201];
  1281.   int x=0;
  1282.   long pos;
  1283.  
  1284.   sprintf(s, "%s%s", syscfg.datadir, "QWK.CFG");
  1285.  
  1286.   memset(qwk_cfg, 0, sizeof(struct qwk_config));
  1287.  
  1288.   f=sh_open1(s, O_BINARY | O_RDONLY);
  1289.   if (f<0)
  1290.     return;
  1291.  
  1292.   sh_read(f,(void *) qwk_cfg, sizeof(struct qwk_config));
  1293.  
  1294.   x=0;
  1295.   while(x<qwk_cfg->amount_blts)
  1296.   {
  1297.     pos=sizeof(struct qwk_config)+(x*BULL_SIZE);
  1298.     sh_lseek(f, pos, SEEK_SET);
  1299.     qwk_cfg->blt[x]=(char *)malloca(BULL_SIZE);
  1300.     sh_read(f, (void *)qwk_cfg->blt[x], BULL_SIZE);
  1301.  
  1302.     ++x;
  1303.   }
  1304.  
  1305.   x=0;
  1306.   while(x<qwk_cfg->amount_blts)
  1307.   {
  1308.     pos=sizeof(struct qwk_config)+(qwk_cfg->amount_blts * BULL_SIZE) + (x*BNAME_SIZE);
  1309.     sh_lseek(f, pos, SEEK_SET);
  1310.     qwk_cfg->bltname[x]=(char *)malloca(BNAME_SIZE * qwk_cfg->amount_blts);
  1311.     sh_read(f, (void *)qwk_cfg->bltname[x], BNAME_SIZE);
  1312.  
  1313.     ++x;
  1314.   }
  1315.  
  1316.   sh_close(f);
  1317. }
  1318.  
  1319.  
  1320.  
  1321. void write_qwk_cfg(struct qwk_config *qwk_cfg)
  1322. {
  1323.   int f,x, new_amount=0;
  1324.   char s[201];
  1325.   long pos;
  1326.  
  1327.   sprintf(s, "%s%s", syscfg.datadir, "QWK.CFG");
  1328.  
  1329.   f=sh_open1(s, O_BINARY | O_RDWR | O_CREAT | O_TRUNC);
  1330.   if (f<0)
  1331.     return;
  1332.  
  1333.   sh_write(f,(void *) qwk_cfg, sizeof(struct qwk_config));
  1334.  
  1335.   x=0;
  1336.   while(x<qwk_cfg->amount_blts)
  1337.   {
  1338.     pos=sizeof(struct qwk_config)+(new_amount*BULL_SIZE);
  1339.     sh_lseek(f, pos, SEEK_SET);
  1340.  
  1341.     if(qwk_cfg->blt[x])
  1342.     {
  1343.       sh_write(f, (void *)qwk_cfg->blt[x], BULL_SIZE);
  1344.       ++new_amount;
  1345.     }
  1346.     ++x;
  1347.   }
  1348.  
  1349.   x=0;
  1350.   while(x<qwk_cfg->amount_blts)
  1351.   {
  1352.     pos=sizeof(struct qwk_config)+(qwk_cfg->amount_blts * BULL_SIZE) + (x*BNAME_SIZE);
  1353.     sh_lseek(f, pos, SEEK_SET);
  1354.  
  1355.     if(qwk_cfg->bltname[x])
  1356.       sh_write(f, (void *)qwk_cfg->bltname[x], BNAME_SIZE);
  1357.  
  1358.     ++x;
  1359.   }
  1360.  
  1361.   qwk_cfg->amount_blts=new_amount;
  1362.   sh_lseek(f, 0, SEEK_SET);
  1363.   sh_write(f,(void *) qwk_cfg, sizeof(struct qwk_config));
  1364.  
  1365.   sh_close(f);
  1366. }
  1367.  
  1368. int get_qwk_max_msgs(unsigned int *max_msgs, unsigned int *max_per_sub)
  1369. {
  1370.   char temp[6];
  1371.  
  1372.   CLS();
  1373.   nl();
  1374.   ansic(2);
  1375.   npr(get_string(1550));
  1376.   mpl(5);
  1377.   input(temp, 5);
  1378.  
  1379.   if(!temp[0])
  1380.     return 0;
  1381.  
  1382.   *max_msgs=atoi(temp);
  1383.  
  1384.   npr(get_string(1551));
  1385.   mpl(5);
  1386.   input(temp, 5);
  1387.  
  1388.   if(!temp[0])
  1389.     return 0;
  1390.  
  1391.   *max_per_sub=atoi(temp);
  1392.  
  1393.   return 1;
  1394. }
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404. void qwk_nscan(void)
  1405. {
  1406.   uploadsrec u;
  1407.   int abort=0, od, newfile, i, i1, i5, f, count, color=3;
  1408.   char s[201], *ext;
  1409.  
  1410.   ansic(3);
  1411.   pl(get_string(1552));
  1412.  
  1413.   sprintf(s, "%s%s", QWK_DIRECTORY, "NEWFILES.DAT");
  1414.   newfile=sh_open1(s, O_BINARY| O_RDWR | O_TRUNC | O_CREAT);
  1415.   if(newfile<1)
  1416.   {
  1417.     pl(get_string(1553));
  1418.     return;
  1419.   }
  1420.  
  1421.   for (i=0; (i<num_dirs) && (!abort) && (udir[i].subnum!=-1); i++)
  1422.   {
  1423.     checka(&abort, &abort);
  1424.     count++;
  1425.  
  1426.     npr("%d.",color);
  1427.     if (count>=DOTS)
  1428.     {
  1429.       outstr("\r");
  1430.       outstr(get_string(1184));
  1431.       color++;
  1432.       count=0;
  1433.       if (color==4)
  1434.         color++;
  1435.       if (color==10)
  1436.         color=0;
  1437.     }
  1438.  
  1439.     i1=udir[i].subnum;
  1440.     if (qsc_n[i1/32]&(1L<<(i1%32)))
  1441.     {
  1442.       if ((dir_dates[udir[i].subnum]) && (dir_dates[udir[i].subnum]<nscandate))
  1443.         continue;
  1444.  
  1445.       od=curdir;
  1446.       curdir=i;
  1447.       dliscan();
  1448.       if (this_date>=nscandate)
  1449.       {
  1450.         sprintf(s,"\r\n\r\n%s - #%s, %d %s.\r\n\r\n",directories[udir[curdir].subnum].name,
  1451.                                 udir[curdir].keys,numf, get_string(742));
  1452.         sh_write(newfile, (void *) s, strlen(s));
  1453.  
  1454.         f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  1455.         for (i5=1; (i5<=numf) && (!(abort)) && (!hangup); i5++)
  1456.         {
  1457.           SETREC(f,i5);
  1458.           sh_read(f,(void *)&u,sizeof(uploadsrec));
  1459.           if (u.daten>=nscandate)
  1460.           {
  1461.             sprintf(s, "%s %5ldk  %s\r\n", u.filename, (long) bytes_to_k(u.numbytes), u.description);
  1462.             sh_write(newfile, (void *) s, strlen(s));
  1463.  
  1464.  
  1465. #ifndef HUGE_TRAN
  1466.             if(u.mask & mask_extended)
  1467.             {
  1468.               int pos=0;
  1469.               ext=read_extended_description(u.filename);
  1470.  
  1471.               if(ext)
  1472.               {
  1473.                 int spos=21, x;
  1474.  
  1475.                 strcpy(s, "                     ");
  1476.                 while(ext[pos])
  1477.                 {
  1478.                   x=ext[pos];
  1479.  
  1480.                   if(x != '\r' && x != '\n' && x > 2)
  1481.                     s[spos]=x;
  1482.  
  1483.  
  1484.                   if(x=='\n' || x==0)
  1485.                   {
  1486.                     s[spos]=0;
  1487.                     sh_write(newfile, (void *)s, strlen(s));
  1488.                     sh_write(newfile, (void *)"\r\n", 2);
  1489.                     strcpy(s, "                     ");
  1490.                     spos=21;
  1491.                   }
  1492.  
  1493.                   if(x != '\r' && x != '\n' && x > 2)
  1494.                     ++spos;
  1495.  
  1496.                   ++pos;
  1497.                 }
  1498.                 bbsfree(ext);
  1499.               }
  1500.             }
  1501. #endif
  1502.  
  1503.           }
  1504.           else if(!empty())
  1505.             checka(&abort,&abort);
  1506.  
  1507.         }
  1508.         f=sh_close(f);
  1509.       }
  1510.       curdir=od;
  1511.  
  1512.     }
  1513.   }
  1514.  
  1515.  
  1516.   newfile=sh_close(newfile);
  1517. }
  1518.  
  1519.  
  1520. void finish_qwk(struct qwk_junk *qwk_info)
  1521. {
  1522.   char command[201], parem1[201], parem2[201];
  1523.   char qwkname[201];
  1524.   int f, sent=0;
  1525.   long numbytes;
  1526.  
  1527.   struct qwk_config qwk_cfg;
  1528.   int x, done=0;
  1529.   int archiver;
  1530.  
  1531.  
  1532.   if(!thisuser.qwk_dontscanfiles)
  1533.     qwk_nscan();
  1534.  
  1535.   read_qwk_cfg(&qwk_cfg);
  1536.   if(!thisuser.qwk_leave_bulletin)
  1537.   {
  1538.     pl(get_string(1554));
  1539.  
  1540.     if(qwk_cfg.hello[0])
  1541.     {
  1542.       sprintf(parem1, "%s%s", syscfg.gfilesdir, qwk_cfg.hello);
  1543.       sprintf(parem2, "%s%s", QWK_DIRECTORY, qwk_cfg.hello);
  1544.       copyfile(parem1, parem2, 1);
  1545.     }
  1546.  
  1547.     if(qwk_cfg.news[0])
  1548.     {
  1549.       sprintf(parem1, "%s%s", syscfg.gfilesdir, qwk_cfg.news);
  1550.       sprintf(parem2, "%s%s", QWK_DIRECTORY, qwk_cfg.news);
  1551.       copyfile(parem1, parem2, 1);
  1552.     }
  1553.  
  1554.     if(qwk_cfg.bye[0])
  1555.     {
  1556.       sprintf(parem1, "%s%s", syscfg.gfilesdir, qwk_cfg.bye);
  1557.       sprintf(parem2, "%s%s", QWK_DIRECTORY, qwk_cfg.bye);
  1558.       copyfile(parem1, parem2, 1);
  1559.     }
  1560.  
  1561.     x=0;
  1562.     while(x<qwk_cfg.amount_blts)
  1563.     {
  1564.       if(exist(qwk_cfg.blt[x]))
  1565.       {
  1566.         // Only copy if bulletin is newer than the users laston date
  1567.         if(file_daten(qwk_cfg.blt[x]) > date_to_daten(thisuser.laston))
  1568.         {
  1569.           sprintf(parem2, "%s%s", QWK_DIRECTORY, qwk_cfg.bltname[x]);
  1570.           copyfile(qwk_cfg.blt[x], parem2, 1);
  1571.         }
  1572.         ++x;
  1573.       }
  1574.     }
  1575.   }
  1576.   qwk_system_name(qwkname);
  1577.  
  1578.   close_qwk_cfg(&qwk_cfg);
  1579.  
  1580.  
  1581.   strcat(qwkname, ".QWK");
  1582.   
  1583.   if(!thisuser.qwk_archive || !syscfg.arcs[thisuser.qwk_archive-1].extension[0])
  1584.     archiver=select_qwk_archiver(qwk_info, 0)-1;
  1585.   else
  1586.     archiver=thisuser.qwk_archive-1;
  1587.  
  1588.  
  1589.   if(!qwk_info->abort)
  1590.   {
  1591.     sprintf(parem1, "%s%s", QWK_DIRECTORY, qwkname);
  1592.     sprintf(parem2, "%s*.*", QWK_DIRECTORY);
  1593.  
  1594.     stuff_in(command, syscfg.arcs[archiver].arca, parem1, parem2, "", "", "");
  1595.     extern_prog(command, EFLAG_NOPAUSE | EFLAG_SHRINK);
  1596.  
  1597.  
  1598.     sprintf(command, "%s%s", QWK_DIRECTORY, qwkname);
  1599.     make_abs_cmd(command);
  1600.  
  1601.     f=sh_open1(command,O_RDONLY | O_BINARY);
  1602.     if (f<0)
  1603.     {
  1604.       pl(get_string(849));
  1605.       nl();
  1606.       qwk_info->abort=1;
  1607.       return;
  1608.     }
  1609.     numbytes=filelength(f);
  1610.  
  1611.     sh_close(f);
  1612.  
  1613.     if (numbytes==0L) {
  1614.       pl(get_string(850));
  1615.       qwk_info->abort=1;
  1616.       return;
  1617.     }
  1618.   }
  1619.  
  1620.   if(incom)
  1621.   {
  1622.     while(!done && !qwk_info->abort && !hangup)
  1623.     {
  1624.       int abort=0;
  1625.       qwk_send_file(command, &sent, &abort);
  1626.       if (sent)
  1627.         done=1;
  1628.       else
  1629.       {
  1630.         nl();
  1631.         ansic(2);
  1632.         pl(get_string(1555));
  1633.         ansic(1);
  1634.         outstr(get_string(1556));
  1635.  
  1636.         if(!ny())
  1637.         {
  1638.           done=1;
  1639.           abort=1;
  1640.           qwk_info->abort=1;
  1641.         }
  1642.         else
  1643.           abort=0;
  1644.  
  1645.       }
  1646.       if(abort)
  1647.         qwk_info->abort=1;
  1648.     }
  1649.   }
  1650.   else while(!done)
  1651.   {
  1652.     char new_dir[61];
  1653.     char nfile[81];
  1654.  
  1655.     ansic(2);
  1656.     outstr(get_string(1557));
  1657.     mpl(60);
  1658.     input(new_dir, 60);
  1659.  
  1660.     trimstr1(new_dir);
  1661.  
  1662.     if(new_dir[0])
  1663.     {
  1664.  
  1665.       if(new_dir[strlen(new_dir)-1]!='\\')
  1666.         strcat(new_dir, "\\");
  1667.  
  1668.       sprintf(nfile, "%s%s", new_dir, qwkname);
  1669.     }
  1670.     else
  1671.       nfile[0]=0;
  1672.  
  1673.     if(!replacefile(parem1, nfile, 1))
  1674.     {
  1675.       ansic(7);
  1676.       outstr(get_string(1558));
  1677.       if(!ny())
  1678.       {
  1679.         qwk_info->abort=1;
  1680.         done=1;
  1681.       }
  1682.     }
  1683.     else
  1684.       done=1;
  1685.   }
  1686. }
  1687.  
  1688. #ifndef SLOWER_BUT_SAFER
  1689. char *qwk_readfile(messagerec *m1, char *aux, long *l)
  1690. {
  1691.   int f,csec;
  1692.   long l1,l2;
  1693.   char *b,s[81],s1[81];
  1694.   messagerec m;
  1695.  
  1696.   *l=0L;
  1697.   m=*m1;
  1698.   switch(m.storage_type)
  1699.   {
  1700.     case 0:
  1701.     case 1:
  1702.       strcpy(s,syscfg.msgsdir);
  1703.       ltoa(m.stored_as,s1,16);
  1704.       if (m.storage_type==1) {
  1705.         strcat(s,aux);
  1706.         strcat(s,"\\");
  1707.       }
  1708.       strcat(s,s1);
  1709.       f=sh_open1(s,O_RDONLY | O_BINARY);
  1710.       if (f==-1) {
  1711.         *l=0L;
  1712.         return(NULL);
  1713.       }
  1714.       l1=filelength(f);
  1715.       if ((b=(char *)malloca(l1+PAD_SPACE))==NULL)
  1716.       {
  1717.         sh_close(f);
  1718.         return(NULL);
  1719.       }
  1720.       sh_read(f,(void *)b,l1);
  1721.       sh_close(f);
  1722.       *l=l1;
  1723.       b[*l]=0;  // Null terminate out text
  1724.       break;
  1725.     case 2:
  1726.  
  1727.       // You will notice that this case opens, but does not close its file
  1728.       // This is becuase of the optimized open file routine, the file gets
  1729.       // closed if AUX != OPENED_FILE, and when the build build_qwk_packet
  1730.       // function is complete
  1731.  
  1732.       if(strcmp(aux, qwk_opened_filename) == 0)
  1733.         f=qwk_opened_file;
  1734.       else
  1735.       {
  1736.         // Close currently qwk_opened_file (if any)
  1737.         if(qwk_opened_file>0)
  1738.           qwk_opened_file=sh_close(qwk_opened_file);
  1739.  
  1740.         // Open new file
  1741.         f=qwk_open_file(aux);
  1742.  
  1743.         if (f<0) {
  1744.           *l=0;
  1745.           return(NULL);
  1746.         }
  1747.  
  1748.         // Set it qwk_opened_files variables so we can check and match next time
  1749.         qwk_opened_file=f;
  1750.         strcpy(qwk_opened_filename, aux);
  1751.       }
  1752.  
  1753.  
  1754.       if (gat_section!=m.stored_as/2048)
  1755.         set_gat_section(f,m.stored_as/2048);
  1756.  
  1757.       csec=m.stored_as % 2048;
  1758.       l1=0;
  1759.       while ((csec>0) && (csec<2048))
  1760.       {
  1761.         l1+=512L;
  1762.         csec=gat[csec];
  1763.       }
  1764.  
  1765.       if (!l1)
  1766.       {
  1767.         nl();
  1768.         pl(get_string(623));
  1769.         nl();
  1770.         return(NULL);
  1771.       }
  1772.       if ((b=(char *)malloca(l1+PAD_SPACE))==NULL)
  1773.       {
  1774.         return(NULL);
  1775.       }
  1776.       csec=m.stored_as % 2048;
  1777.       l1=0;
  1778.       l2=MSG_STARTING;
  1779.       while ((csec>0) && (csec<2048)) {
  1780.         sh_lseek(f,l2 + 512L*csec,SEEK_SET);
  1781.         l1+=(long)sh_read(f,(void *)(&(b[l1])),512);
  1782.         csec=gat[csec];
  1783.       }
  1784.       l2=l1-512;
  1785.       while ((l2<l1) && (b[l2]!=26))
  1786.         ++l2;
  1787.       *l=l2;
  1788.       b[*l]=0;  // Null terminate out text
  1789.       break;
  1790.     case 255:
  1791.       f=sh_open1(aux,O_RDONLY | O_BINARY);
  1792.       if (f==-1) {
  1793.         *l=0L;
  1794.         return(NULL);
  1795.       }
  1796.       l1=filelength(f);
  1797.       if ((b=(char *)malloca(l1+PAD_SPACE))==NULL)
  1798.       {
  1799.         sh_close(f);
  1800.         return(NULL);
  1801.       }
  1802.       sh_read(f,(void *)b,l1);
  1803.       sh_close(f);
  1804.       *l=l1;
  1805.       b[*l]=0;  // Null terminate out text
  1806.       break;
  1807.     default:
  1808.       /* illegal storage type */
  1809.       *l=0L;
  1810.       b=NULL;
  1811.       break;
  1812.   }
  1813.   return(b);
  1814. }
  1815.  
  1816. int qwk_open_file(char *fn)
  1817. {
  1818.   int f,i;
  1819.   char s[81];
  1820.  
  1821.   sprintf(s,"%s%s.DAT",syscfg.msgsdir,fn);
  1822.   f=sh_open1(s,O_RDWR | O_BINARY);
  1823.  
  1824.   if (f<0)
  1825.   {
  1826.     f=sh_open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1827.     for (i=0; i<2048; i++)
  1828.       gat[i]=0;
  1829.  
  1830.     if (f<0)
  1831.       return(-1);
  1832.     sh_write(f,(void *)gat,4096);
  1833.     strcpy(gatfn,fn);
  1834.     chsize(f,4096L + (75L * 1024L));
  1835.     gat_section=0;
  1836.   }
  1837.   if (strcmp(gatfn,fn) || 1)
  1838.   {
  1839.     sh_lseek(f,0L,SEEK_SET);
  1840.     sh_read(f,(void *)gat,4096);
  1841.     strcpy(gatfn,fn);
  1842.     gat_section=0;
  1843.   }
  1844.   return(f);
  1845. }
  1846. #endif
  1847.