home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / UTILITY / UU121B11.ARJ / UU.C next >
Text File  |  1991-12-03  |  38KB  |  1,376 lines

  1. /* The UU???.MOD and UU???.EXE source file.  See version number defined
  2.    below.  This file can be used to produce the obj file UU.OBJ, for use
  3.    with WWIV version 4.20 or the stand alone EXE file UU.EXE.
  4.  
  5.    To produce the EXE version simply remove the #define for MOD below and
  6.    compile.  An example .PRJ (UU.PRJ) is included.  The project file, for
  7.    TC++, will require some changes to work for you.  The paths and
  8.    directories are set up for my system.  It uses the large memory model
  9.    and duplicate strings are merged.
  10.  
  11.    The EXE version requires two support files be placed in the same
  12.    directory in which the EXE resides.  These files, UU.CFG and UU.HLP,
  13.    are included in the archive UU???.ZIP.
  14.  
  15.    To install the mod, remove void extract_out(char *b, long len, char
  16.    *title) from msgbase1.c.  Make sure the line: #define MOD
  17.    is still in the source file uu.c and has not been removed to produce the
  18.    EXE.  Add uu.c to your makefile or project.  Put uu.c in your source
  19.    directory, make fcns and make.  Detailed instructions for doing
  20.    this are included as UU.MOD in the archive UU???.ZIP.
  21.  
  22.    The MOD version requires three support files be placed in the GFILES
  23.    directory.  These files, UU1.MSG (the main menu for UU???.MOD),
  24.    UU2.MSG (a sub menu for UU???.MOD), and zipcomnt.msg (a comment to be
  25.    added to all extracted and zipped files) are included in the archive
  26.    UU???.ZIP.
  27.  
  28.    If you make changes be careful.  Some functions are used only for the
  29.    MOD, some only for the EXE and some for both.  Extreme care must be
  30.    used when changing those functions used by both.  It is very easy to
  31.    change the mod to do something you want; only to find the EXE no longer
  32.    works.  If it aint broke don't fix it.  Tell me about it.
  33.  
  34.    You are welcome to use this file as you see fit; but you must not
  35.    distribute modified versions of this file.  It must be included, intact,
  36.    in any file which describes enhancements or changes.
  37.  
  38.    Jim Wire
  39.    HIT BBS
  40.    (319) 296-1529
  41. */
  42.  
  43. #define UU_VER_NO "1.21b11"
  44. #define UU_DATE "12/03/91"
  45. #define MOD
  46. #define SWITCH
  47.  
  48. #ifdef MOD
  49.  
  50. #include "vars.h"
  51.  
  52. #pragma hdrstop
  53.  
  54. #include <dir.h>
  55.  
  56. #else
  57.  
  58. #include <stdio.h>
  59. #include <string.h>
  60. #include <io.h>
  61. #include <stdlib.h>
  62. #include <dir.h>
  63. #include <fcntl.h>
  64. #include <sys\stat.h>
  65. #include <sys\types.h>
  66.  
  67. #endif
  68.  
  69.  
  70. char buf[80];
  71. char in_path[MAXPATH];
  72. char out_path[MAXPATH];
  73. char home_path[MAXPATH];
  74. int out_file_specified;
  75.  
  76. long count=0L;
  77. long size=18000L;
  78. int line=300;
  79. int seg=1;
  80. int segs=1;
  81. int mode;
  82. int uu_type=1;
  83.  
  84. #ifndef SWITCH
  85.  
  86. /* This little guy deletes a file.  I use him in other areas on my bbs.
  87.    I put him in utility.c, so he does not get overlayed.  I found him
  88.    to be of particular value with Adam Caldwell's editinfo.mod.  Call
  89.    delete_file everywhere he uses remove.  As a matter of fact you might
  90.    want to replace all calls to unlink and remove in the BBS to delete_file
  91.    calls.
  92.  */
  93.  
  94. void delete_file(char *file_name) /* Not WITH SWITCH MOD  */
  95. {
  96.   char s[161];
  97.   int res=0;
  98.  
  99.   if(!exist(file_name))
  100.     return;
  101.   res=unlink(file_name);
  102.   if(res==0)
  103.     return;
  104.   _chmod(file_name,1,0);
  105.   res=unlink(file_name);
  106.   if(res==0)
  107.     return;
  108. #ifdef MOD
  109.   npr("6Unable to delete the file %s.0\r\n",file_name);
  110. #else
  111.   sprintf(s,"Unable to delete the file %s.\r\n",file_name);
  112.   printf(s);
  113. #endif
  114. }
  115.  
  116. #endif
  117.  
  118. #ifdef MOD
  119.  
  120. /* This function handles the interface between the BBS and the UU
  121.    decode function.  If you add directories or change the ones that
  122.    are offered here you need also to make changes in several other
  123.    places to allow your changes to function.  The lines or files that
  124.    require changes are indicated with the comment 'change this too'.
  125.    As always if you have trouble getting what you want from this mod
  126.    let me know and I'll be happy to help.  It should not be at all
  127.    difficult to add as many directories as you want.  This portion of
  128.    mod is based on EXTRACT?.MOD which was based on EXTRMSG.MOD.
  129.  
  130.     Birdhunter    (1@3451)
  131.     AlleyKat      (1@8352)
  132.  
  133. MOD Version only. */
  134.  
  135. void extract_out(char *b, long len, char *title)
  136. {
  137.   char s[MAXPATH],ch=26,ch1;
  138.   int i,ret;
  139.   int transfer=0,uued=0,quit=0,append=0;
  140.   char in_drive[MAXDRIVE];
  141.   char in_dir[MAXDIR];
  142.   char in_file[MAXFILE];
  143.   char in_ext[MAXEXT];
  144.  
  145.  
  146.   /* do not alter these next few lines.*/
  147.   npr("\r\n1 UU.MOD, version %s, dated %s.0\r\n",
  148.     UU_VER_NO,UU_DATE);
  149.   npr("   2by Jim Wire @3950, @139500\r\n");
  150.   /* Thank you.*/
  151.  
  152.   printfile("UU1.MSG");                          /* Change this file too */
  153.   npr("\r\n2Which (1-7,Q) : ");                 /* Change this too */
  154.   ch1=onek("1234567Q");                          /* Change this too */
  155.   switch(ch1) {
  156.     case '1':
  157.       strcpy(s,"..\\EXTRACT\\MAIL\\");           /* directory */
  158.       strcpy(in_ext,".MSG");                     /* default file extension */
  159.     break;
  160.     case '2':
  161.       strcpy(s,"..\\EXTRACT\\FEEDBACK\\");           /* directory */
  162.       strcpy(in_ext,".FBK");                     /* default file extension */
  163.     break;
  164.     case '3':
  165.       strcpy(s,"D:\\DLOADS\\MODS\\");            /* directory */
  166.       strcpy(in_ext,".MOD");                     /* default file extension */
  167.       transfer=1;                                /* a transfer directory */
  168.     break;
  169.     case '4':
  170.       strcpy(s,"D:\\DLOADS\\WWIVMODN\\");        /* directory */
  171.       strcpy(in_ext,".MOD");                     /* default file extension */
  172.       transfer=1;                                /* a transfer directory */
  173.     break;
  174.     case '5':
  175.       strcpy(s,syscfg.gfilesdir);                /* directory */
  176.       strcpy(in_ext,".MSG");                     /* default file extension */
  177.     case '6':
  178.       strcpy(s,syscfg.datadir);                  /* directory */
  179.       strcpy(in_ext,".MSG");                     /* default file extension */
  180.     break;
  181.     case '7':
  182.       sprintf(s,"..\\EXTRACT\\LOAD\\");      /* directory */
  183.       strcpy(in_ext,".UUE");                     /* default file extension */
  184.     break;
  185.     case 'Q':
  186.       npr("\n\r7Extract aborted.\r\n\r\n");
  187.       return;
  188.   }
  189.  
  190.   do {
  191.     npr("\r\n1Save under what filename? ");
  192.     ret=get_name(s,in_ext);
  193.     if(ret==3)
  194.       return;
  195.     if(ret==2) {
  196.       append=1;
  197.       ret=0;
  198.     }
  199.     fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
  200.     strcpy(out_path,in_path);
  201.     if((strcmp(in_ext,".UUE")==0) && (ret==0))
  202.       uued=1;
  203.   } while ((!hangup) && (ret!=0));
  204.   if(!hangup) {
  205.     i=open(in_path,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  206.     if(i<0) {
  207.       npr("\n\r6Unable to get a handle for %s.0\r\n",in_path);
  208.       return;
  209.     }
  210.     if(append)
  211.       lseek(i,-1L,SEEK_END);
  212.     else
  213.       lseek(i,0L,SEEK_END);
  214.     write(i,title,strlen(title));
  215.     write(i,"\r\n",2);
  216.     write(i,(void *)b,len);
  217.     write(i,&ch,1);
  218.     close(i);
  219.  
  220.     sprintf(s,"%s%s",in_drive,in_dir);
  221.     npr("\r\n1File %s written",in_path);
  222.     if(uued==1) {
  223.       npr("\r\n2Decode the file? (y/N) ");
  224.       if(yn())
  225.         decd();
  226.     } else {
  227.       npr("\r\n2Compress the file? (y/N) ");
  228.       if(yn()) {
  229.         compress();
  230.         delete_file(in_path);
  231.       }
  232.     }
  233.     if(transfer==1) {
  234.       npr("\r\n2//UPLOAD all the files in %s? (y/N) ",s);
  235.       if(yn()) {
  236.         for (i=0; (i<64) && (udir[i].subnum>=0) && (!quit); i++) {
  237.           if(strcmp(s,(directories[udir[i].subnum].path))==0) {
  238.             npr("\r\n1Now //UPLOADing files in %s.0\r\n",s);
  239.             uploadall(udir[i].subnum);
  240.           }
  241.         }
  242.       } else {
  243.         npr("\r\n2//UPLOAD the file %s? (y/N) ",out_path);
  244.         if(yn()) {
  245.  
  246.           fnsplit(out_path,in_drive,in_dir,in_file,in_ext);
  247.           for (i=0; (i<64) && (udir[i].subnum>=0) && (!quit); i++) {
  248.             if(strcmp(s,(directories[udir[i].subnum].path))==0) {
  249.               curdir=udir[i].subnum;
  250.               sprintf(s,"%s%s",in_file,in_ext);
  251.               npr("\r\n1Now //UPLOADing %s.0\r\n",s);
  252.               upload_file(s,curdir,"");
  253.             }
  254.           }
  255.         }
  256.       }
  257.     }
  258.   }
  259.   topscreen();                                   /* added by ED */
  260.   farfree(b);
  261. }
  262.  
  263.  
  264. /* This function handles the interface between the BBS and the UU
  265.    encode function.  It allows you to choose from a list of files in
  266.    a single directory or load a file from anywhere.  If demand warrants
  267.    I'll add more directories to choose from.  Once selected the file
  268.    can be encoded and or edited.
  269.  
  270.   MOD Version only. */
  271.  
  272. void loadfile()
  273. {
  274.   char in_drive[MAXDRIVE];
  275.   char in_dir[MAXDIR];
  276.   char in_file[MAXFILE];
  277.   char in_ext[MAXEXT];
  278.   char out_drive[MAXDRIVE];
  279.   char out_dir[MAXDIR];
  280.   char out_file[MAXFILE];
  281.   char out_ext[MAXEXT];
  282.   char du_drive[MAXDRIVE];
  283.   char du_dir[MAXDIR];
  284.   char du_file[MAXFILE];
  285.   char du_ext[MAXEXT];
  286.   int in_flags;
  287.   int choose,f1,i=1;
  288.   char s[MAXPATH],s1[MAXPATH],*sss;
  289.   struct ffblk ff;
  290.  
  291.   /* do not alter these next few lines.*/
  292.   npr("\r\n1 UU.MOD, version %s, dated %s.0\r\n",
  293.     UU_VER_NO,UU_DATE);
  294.   npr("   2by Jim Wire @3950, @139500\r\n");
  295.   /* Thank you.*/
  296.  
  297.   npr("\r\n2Choose from list of available files? (Y/n) ");
  298.   if(ny()) {
  299.     sprintf(s,"..\\EXTRACT\\LOAD\\");
  300.     fnsplit(s,in_drive,in_dir,du_file,du_ext);
  301.     npr("\r\n1Default directory is %s.",in_dir);
  302.     npr("\r\n2Change directory? (y/N) ");
  303.     if(yn()) {
  304.       npr("\r\n2New //LOAD directory? (ending \\ required) 1");
  305.       input(in_path,MAXPATH);
  306.       fnsplit(in_path,in_drive,in_dir,du_file,du_ext);
  307.     }
  308.     fnmerge(in_path,in_drive,in_dir,"","");
  309.     sprintf(s,"%s*.*",in_path);
  310.     f1=findfirst(s,&ff,0);
  311.     if(f1) {
  312.       npr("\r\n6No files available.0\r\n");
  313.       return;
  314.     }
  315.     npr("\r\n1Available files:\r\n");
  316.     while (f1==0) {
  317.       if(i==5) {
  318.         npr("1%-12s",ff.ff_name);
  319.         i=1;
  320.       } else {
  321.         npr("1%-17s",ff.ff_name);
  322.         ++i;
  323.       }
  324.       f1=findnext(&ff);
  325.     }
  326.     if(i !=1)
  327.       nl();
  328.     npr("\r\n2Filename? 1");
  329.     input(s,12);
  330.     if(s[0]) {
  331.       fnsplit(s,du_drive,du_dir,in_file,in_ext);
  332.     } else {
  333.       npr("\n\r7//LOAD Aborted.");
  334.       return;
  335.     }
  336.   } else {
  337.     npr("\n\r2Filename? 1");
  338.     input(s,80);
  339.     fnsplit(s,in_drive,in_dir,in_file,in_ext);
  340.   }
  341.   fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
  342.   if(strcmp(in_ext,".UUE")!=0) {
  343.     npr("\r\n2Encode the file? ");
  344.     if(yn()) {
  345.       nl();
  346.       fnsplit(in_path,out_drive,out_dir,out_file,out_ext);
  347.       strcpy(out_ext, ".UUE");
  348.       npr("\r\n2Use TEMP directory? ");
  349.       if(ny()) {
  350.         sprintf(s,"%s",syscfg.tempdir);
  351.         fnsplit(s,out_drive,out_dir,du_file,du_ext);
  352.       }
  353.       fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
  354.       encd();
  355.       strcpy(in_path,out_path);
  356.     }
  357.   }
  358.   npr("\r\n2Allow editing? (y/N) ");
  359.   if(yn())
  360.     load_workspace(in_path,0);
  361.   else
  362.     load_workspace(in_path,1);
  363.   topscreen();
  364. }
  365.  
  366. /* Gets a name for the file to be extracted from the user.  Checks for the
  367.    existance of that file and offers the user a series of choices if it is
  368.    already there.
  369.  
  370. MOD Version only. */
  371.  
  372. int get_name(char *path, char *ext)
  373. {
  374.   char s[MAXPATH],resp[3],ch1;
  375.   char in_drive[MAXDRIVE];
  376.   char in_dir[MAXDIR];
  377.   char in_file[MAXFILE];
  378.   char in_ext[MAXEXT];
  379.   int in_flags;
  380.   char du_drive[MAXDRIVE];
  381.   char du_dir[MAXDIR];
  382.   char du_file[MAXFILE];
  383.   char du_ext[MAXEXT];
  384.  
  385.   fnsplit(path,in_drive,in_dir,du_file,du_ext);
  386.   input(s,12);
  387.   in_flags=fnsplit(s,du_drive,du_dir,in_file,in_ext);
  388.  
  389.   if(!(in_flags & FILENAME))
  390.     return(0);
  391.   if(!(in_flags & EXTENSION))
  392.     strcpy(in_ext,ext);
  393.   fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
  394.   if(exist(in_path)) {
  395.     npr("\r\n6%s already exists. 0\r\n",in_path);
  396.     printfile("UU2.MSG");
  397.     npr("\r\n2Which (A,N,O,Q) : ");
  398.     ch1=onek("QOAN");
  399.     nl();
  400.     switch(ch1) {
  401.       case 'Q':
  402.         return(3);
  403.       case 'N':
  404.         return(1);
  405.       case 'A':
  406.         return(2);
  407.       case 'O':
  408.        npr("\r\n2Do you want to overwrite %s? (Y/N) ",in_path);
  409.        scanf("%s",resp);
  410.         if((resp[0]!='Y') && (resp[0]!='y'))
  411.           return(1);
  412.         delete_file(in_path);
  413.         return(0);
  414.       default:
  415.         npr("\r\nAborting");
  416.         return(3);
  417.     }
  418.   } else
  419.   return(0);
  420. }
  421.  
  422. /* This function was added for the //MASTER mod and several others.  It
  423.    provides backwards compatability.
  424.  
  425. MOD Version only. */
  426.  
  427. void compress1(char *fn, char *path)
  428. {
  429.   char in_drive[MAXDRIVE];
  430.   char in_dir[MAXDIR];
  431.   char in_file[MAXFILE];
  432.   char in_ext[MAXEXT];
  433.   char du_drive[MAXDRIVE];
  434.   char du_dir[MAXDIR];
  435.   char du_file[MAXFILE];
  436.   char du_ext[MAXEXT];
  437.  
  438.   fnsplit(fn,du_drive,du_dir,in_file,in_ext);
  439.   fnsplit(path,in_drive,in_dir,du_file,du_ext);
  440.   fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
  441.   compress();
  442. }
  443.  
  444. /* This function compresses the file and removes the source file if
  445.    compression was successful.  If the system has ZIP as the default
  446.    archive extension adds a comment to the ZIP.  It receives as input
  447.    the file name and path.  It is also used by several of my other mods.
  448.    If you already have a void compress(char *fn, char *dir) in your BBS
  449.    the other one can safely be removed.
  450.  
  451. MOD Version only. */
  452.  
  453. void compress()
  454. {
  455.   char s[161];
  456.   int ret;
  457.   char in_drive[MAXDRIVE];
  458.   char in_dir[MAXDIR];
  459.   char in_file[MAXFILE];
  460.   char in_ext[MAXEXT];
  461.   char out_ext[MAXEXT];
  462.  
  463.   npr("2Now compressing %s.\r\n",in_path);
  464.   fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
  465.   sprintf(out_ext,".%s",syscfg.arcs[0].extension);
  466.   fnmerge(out_path,in_drive,in_dir,in_file,out_ext);
  467.   if(exist(out_path)) {
  468.     npr("\r\n6The file %s already exists.",out_path);
  469.     npr("\r\n2Alter contents? (y/N) ");
  470.       if(!yn())
  471.          return;
  472.   }
  473.   stuff_in(s,syscfg.arcs[0].arca,out_path,in_path,"","","");
  474.   ret=do_remote(s,0);
  475.   if(ret == 0) {
  476.     delete_file(in_path);
  477.     if(strcmp(out_ext,".ZIP") ==0)
  478.       comment();
  479.   }
  480.   topscreen();
  481. }
  482.  
  483. /* This function adds a comment to a ZIPped file.
  484. MOD Version only. */
  485.  
  486. /* Ed O'Brien #1 @7350  */
  487.  
  488. void comment()
  489. {
  490.   char s1[161];
  491.  
  492.   npr("2Adding comment to %s.\r\n0",out_path);
  493.     sprintf(s1,"PKZIP -z -k %s < %sZIPCOMNT.MSG",out_path,syscfg.gfilesdir);
  494.   run_external(s1);
  495.   nl();
  496.   nl();
  497. }
  498.  
  499. #endif
  500.  
  501. /* Based on Waynes npr function.  This puts the information passed it into
  502.    the file passed. */
  503.  
  504. void fpr(FILE *out, char *fmt, ...)
  505. {
  506.   va_list ap;
  507.   char s[512];
  508.  
  509.   va_start(ap, fmt);
  510.   vsprintf(s, fmt, ap);
  511.   va_end(ap);
  512.   fprintf(out,s);
  513.   count+=strlen(s);
  514. }
  515.  
  516. /* This function passes back the location of the specified character in the
  517.    string it is passed.  If you already have int find_dot (char *fn, char ch)
  518.    in your bbs, you will need to remove it and chaange all calls to it.
  519.    The calls now require the search character be included in the call.
  520.    Example:
  521.  
  522.    dot=find_dot(sig,'.');
  523.  
  524.    will return the location of the character '.' in the string sig. */
  525.  
  526. int find_dot (char *fn, char ch)
  527. {
  528.   char *ptr;
  529.   int dot;
  530.  
  531.   ptr=strchr(fn,ch);
  532.   dot=ptr-fn;
  533.   if(dot<=0)
  534.     dot=0;
  535.   return(dot);
  536. }
  537.  
  538. /* This function sets up the segment numbers and file names for multi-segment
  539.    files, both new and old format. */
  540.  
  541. char *forjon(char *ss, int x)
  542. {
  543.   char temp[12],s[12],s1[12];
  544.   int len;
  545.   char in_drive[MAXDRIVE];
  546.   char in_dir[MAXDIR];
  547.   char in_file[MAXFILE];
  548.   char in_ext[MAXEXT];
  549.  
  550.   fnsplit(ss,in_drive,in_dir,in_file,in_ext);
  551.   sprintf(temp,"%d",segs);
  552.   len=strlen(temp);
  553.   sprintf(s,"%d",x);
  554.   while(strlen(s) < 8-strlen(in_file)) {
  555.     strrev(s);
  556.     strcat(s,"0");
  557.     strrev(s);
  558.   }
  559.   strcpy(temp,in_file);
  560.   if(strlen(in_file)+len >= 8){
  561.     strcpy(s1,strrev(strrev(temp)+len-(8-strlen(temp))));
  562.     strcpy(temp,s1);
  563.   }
  564.   sprintf(s1,"%s%s",temp,s);
  565.   return(s1);
  566. }
  567.  
  568. /* This function reads four encoded characters from the input file and
  569.    decodes them to produce three 8 bit characters.  The three characters
  570.    are then written to the output file. */
  571.  
  572. void decout(char *p,  FILE *f,int n)
  573. {
  574.   int c1, c2, c3;
  575.  
  576.   c1 =((p[0] - 0x20) & 0x3f) << 2 | ((p[1] - 0x20) & 0x3f) >> 4;
  577.   c2 =((p[1] - 0x20) & 0x3f) << 4 | ((p[2] - 0x20) & 0x3f) >> 2;
  578.   c3 =((p[2] - 0x20) & 0x3f) << 6 | ((p[3] - 0x20) & 0x3f);
  579.   if(n >= 1)
  580.     putc(c1, f);
  581.   if(n >= 2)
  582.     putc(c2, f);
  583.   if(n >= 3)
  584.     putc(c3, f);
  585.   count += n;
  586. }
  587.  
  588. /* This function reads a line from the input file.  These lines are passed
  589.    to the decout function in groups of 4 characters where they are decoded
  590.    and written to the output file. */
  591.  
  592. void decode(FILE *in, FILE *out)
  593. {
  594.   char *bp, s[81], s1[81];
  595.   int n;
  596.   char in_drive[MAXDRIVE];
  597.   char in_dir[MAXDIR];
  598.   char in_file[MAXFILE];
  599.   char in_ext[MAXEXT];
  600.   char out_drive[MAXDRIVE];
  601.   char out_dir[MAXDIR];
  602.   char out_file[MAXFILE];
  603.   char out_ext[MAXEXT];
  604.  
  605.   fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
  606.   fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
  607.   for (;;) {
  608.     if((fgets(buf, sizeof buf, in) == NULL)
  609.       || (strncmp(buf,"uu end segment ", 15)==0)
  610.       || (strncmp(buf,"sum ", 4)==0)) {
  611.       if(strncmp(buf, "sum ", 4) == 0)
  612.         ++segs;
  613.       if(seg==segs) {
  614. #ifdef MOD
  615.         npr("\r\n6Short file.0\r\n");
  616.         return;
  617. #else
  618.         printf("Short file\n");
  619.         exit(10);
  620. #endif
  621.       }
  622.       ++seg;
  623.       if(uu_type == 0)
  624.         sprintf(s1,"%s%d",out_file,seg);
  625.       else
  626.         strcpy(s1,forjon(out_path,seg));
  627.       fnmerge(s,out_drive,out_dir,s1,in_ext);
  628.       if((in = fopen(s, "r")) == NULL) {
  629. #ifdef MOD
  630.         npr("\r\n6Cant open %s.0\r\n",s);
  631.         return;
  632. #else
  633.         perror(s);
  634.         exit(1);
  635. #endif
  636.       }
  637.       fseek(in, 0, SEEK_SET);
  638.       for (;;) {
  639.         if(fgets(buf, sizeof buf, in) == NULL) {
  640. #ifdef MOD
  641.           npr("\r\n6No begin line.0\r\n");
  642.           return;
  643. #else
  644.           fprintf(stderr, "No begin line.\n");
  645.           exit(3);
  646. #endif
  647.     }
  648.         if(((strncmp(buf, "begin ", 6) == 0)
  649.           && (uu_type == 1))
  650.           || ((strncmp(buf, "section ", 8) == 0)
  651.           && (uu_type == 0)))
  652.           break;
  653.       }
  654. #ifdef MOD
  655.       npr("         %s to produce %s.\n",s,out_file);
  656. #else
  657.       printf("         %s to produce %s.\n",s,out_file);
  658. #endif
  659.       fgets(buf, sizeof buf, in);
  660.     }
  661.     n = ((buf[0] - 0x20) & 0x3f);
  662.     if(n <= 0)
  663.       break;
  664.     bp = &buf[1];
  665.     while (n > 0) {
  666.       decout(bp, out, n);
  667.       bp += 4;
  668.       n -= 3;
  669.     }
  670.   }
  671. }
  672.  
  673. /* This function calls the other fuctions required to perform the decoding
  674.    of the file.  It is passed the file name and path for the input file and
  675.    hands that information off to the other functions. */
  676.  
  677. int decd()
  678. {
  679.   FILE *in, *out;
  680.   struct ftime ft;
  681.   char sig[81], sig1[81];
  682.   char resp[81], s[81], s1[81];
  683.   long in_size, out_size;
  684.   int temp, dot, ret;
  685.   int x, x1=0;
  686.   char ft1[3];
  687.  
  688.   char in_drive[MAXDRIVE];
  689.   char in_dir[MAXDIR];
  690.   char in_file[MAXFILE];
  691.   char in_ext[MAXEXT];
  692.   char out_drive[MAXDRIVE];
  693.   char out_dir[MAXDIR];
  694.   char out_file[MAXFILE];
  695.   char out_ext[MAXEXT];
  696.   char du_drive[MAXDRIVE];
  697.   char du_dir[MAXDIR];
  698.  
  699.   fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
  700.   fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
  701.   sig[0]=0;
  702.   if((in = fopen(in_path, "r")) == NULL) {
  703.     perror(in_path);
  704.     return(1);
  705.   }
  706.  
  707.   fseek(in, 0, SEEK_SET);
  708.   for (;;) {
  709.     if(fgets(buf, sizeof buf, in) == NULL) {
  710.       fprintf(stderr, "No section line\n");
  711.       return(3);
  712.     }
  713.     if(strncmp(buf, "section ", 6) == 0)
  714.       break;
  715.   }
  716.  
  717.   (void)sscanf(buf, "section %d of %d uu", &seg, &segs);
  718.   fseek(in, 0, SEEK_SET);
  719.   for (;;) {
  720.     if(fgets(buf, sizeof buf, in) == NULL) {
  721. #ifdef MOD
  722.       npr("No signature line\r\n");
  723.       npr("Switching to old multi-segment file format.\r\n");
  724. #else
  725.       printf("No signature line\n");
  726.       printf("Switching to old multi-segment file format.\n");
  727. #endif
  728.       uu_type=0;
  729.       break;
  730.     }
  731.     if(strncmp(buf, "File signature :",16) == 0) {
  732.       strcpy(sig,buf+16);
  733.       break;
  734.     }
  735.   }
  736.  
  737.   if(sig[0]) {
  738.     dot=find_dot(sig,'/');
  739.     strcpy(sig1,sig);
  740.     strrev(sig1);
  741.     ft.ft_month=atoi(strrev(sig1+strlen(sig1)-dot));
  742.     strcpy(sig,sig+dot+1);
  743.     dot=find_dot(sig,'/');
  744.     strcpy(sig1,sig);
  745.     strrev(sig1);
  746.     ft.ft_day=atoi(strrev(sig1+strlen(sig1)-dot));
  747.     strcpy(sig,sig+dot+1);
  748.     dot=find_dot(sig,' ');
  749.     strcpy(sig1,sig);
  750.     strrev(sig1);
  751.     ft.ft_year=atoi(strrev(sig1+strlen(sig1)-dot));
  752.     ft.ft_year=ft.ft_year-60;
  753.     strcpy(sig,sig+dot+1);
  754.     dot=find_dot(sig,':');
  755.     strcpy(sig1,sig);
  756.     strrev(sig1);
  757.     ft.ft_hour=atoi(strrev(sig1+strlen(sig1)-dot));
  758.     strcpy(sig,sig+dot+1);
  759.     dot=find_dot(sig,':');
  760.     strcpy(sig1,sig);
  761.     strrev(sig1);
  762.     ft.ft_min=atoi(strrev(sig1+strlen(sig1)-dot));
  763.     strcpy(sig,sig+dot+1);
  764.     dot=find_dot(sig,' ');
  765.     strcpy(sig1,sig);
  766.     strrev(sig1);
  767.     ft.ft_tsec=atoi(strrev(sig1+strlen(sig1)-dot));
  768.     strcpy(sig,sig+dot+1);
  769.     in_size=atol(sig);
  770.   }
  771.   fseek(in, 0, SEEK_SET);
  772.   for (;;) {
  773.     if(fgets(buf, sizeof buf, in) == NULL) {
  774.       fprintf(stderr, "No begin line\n");
  775.       return(3);
  776.     }
  777.     if(strncmp(buf, "begin ", 6) == 0)
  778.       break;
  779.   }
  780.  
  781.   (void)sscanf(buf, "begin %o %s", &mode, s1);
  782.   if(!out_file_specified)
  783.     fnsplit(s1,du_drive,du_dir,out_file,out_ext);
  784.   fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
  785.  
  786.  
  787.   if(segs > 1) {
  788. #ifdef MOD
  789.     npr("Joining %d segments to make %s.\r\n\n",segs,out_file);
  790. #else
  791.     printf("Joining %d segments to make %s.\n\n",segs,out_file);
  792. #endif
  793.     for(x = seg; x < segs+1 ; ++x ) {
  794.       strcpy(s1,forjon(in_path,x));
  795.       fnmerge(s,in_drive,in_dir,s1,in_ext);
  796.       if(!exist(s)) {
  797. #ifdef MOD
  798.         npr("Can't find %s and don't know how to make it.\r\n",s);
  799. #else
  800.         printf("Can't find %s and don't know how to make it.\n",s);
  801. #endif
  802.         x1=1;
  803.       }
  804.     }
  805.     if(x1 == 1)
  806.       return(8);
  807.   }
  808.   if(exist(out_path)) {
  809. #ifdef MOD
  810.     npr("\r\nDo you want to overwrite %s? (Y/N) ",out_path);
  811. #else
  812.     printf("\r\nDo you want to overwrite %s? (Y/N) ",out_path);
  813. #endif
  814.     scanf("%s",resp);
  815.     if((resp[0]!='Y') && (resp[0]!='y'))
  816.       return(7);
  817.   }
  818.   if(segs > 1)
  819.     strcpy(s1,forjon(in_path,seg));
  820.   else
  821.     strcpy(s1,in_file);
  822.   fnmerge(s,in_drive,in_dir,s1,in_ext);
  823. #ifdef MOD
  824.   npr("\r\nDECODING %s to produce %s%s.\r\n",s,out_file,out_ext);
  825. #else
  826.   printf("\r\nDECODING %s to produce %s%s.\r\n",s,out_file,out_ext);
  827. #endif
  828.   out = fopen(out_path, "w+b");        /* Binary file */
  829.   if(out == NULL) {
  830.     perror(out_path);
  831.     return(4);
  832.   }
  833.  
  834.   decode(in, out);
  835.  
  836.   fclose(out);
  837.   temp=open(out_path,O_RDONLY);
  838.   if(temp<=0) {
  839.     perror(out_path);
  840.     return(1);
  841.   }
  842.   if(sig[0]) {
  843.     out_size=filelength(temp);
  844.     if(out_size != in_size) {
  845.       fprintf(stderr, "File sizes differ.\n");
  846.       return(8);
  847.     }
  848.     setftime(temp,&ft);
  849.   }
  850.   close(temp);
  851.   _chmod(out_path,1,0);
  852. #ifdef MOD
  853.   npr("\r\n1Success.");
  854.   npr("\r\n2Delete the UUE file(s)? (y/N)");
  855.   if(yn()) {
  856. #endif
  857.     if((segs > 1) && (out_file_specified!=1)) {
  858.       for(x = 1; x < segs+1 ; ++x ) {
  859.         if(uu_type == 0)
  860.       sprintf(s1,"%s%d",out_file,x);
  861.         else
  862.           strcpy(s1,forjon(in_path,x));
  863.         fnmerge(s,in_drive,in_dir,s1,in_ext);
  864. #ifdef MOD
  865.         npr("Deleting %s.\n",s);
  866. #else
  867.         printf("Deleting %s.\n",s);
  868. #endif
  869.         delete_file(s);
  870.       }
  871.     } else {
  872. #ifdef MOD
  873.       npr("Deleting %s.\n\n",in_path);
  874. #else
  875.       printf("Deleting %s.\n\n",in_path);
  876. #endif
  877.       delete_file(in_path);
  878.     }
  879. #ifdef MOD
  880.   }
  881.   npr("\r\n2Compress the file %s? ",out_path);
  882.   if(yn())
  883.     compress();
  884. #endif
  885.   return(0);
  886. }
  887.  
  888. /* This function takes three eight bit characters and encodes them into
  889.    four characters.  All four characters which can be displayed using 7
  890.    bits and are above 20 hex.   The four characteres are written to the
  891.    output file individually.
  892.     p[0]        p[1]        p[3]
  893.    [0000 0000] [1111 1111] [2222 2222]
  894.    (1111 1122) (2222 3333) (3344 4444)
  895.     c1()   c2()      c3()     c4()    */
  896.  
  897. void encout(char *p, FILE *f)
  898. {
  899.   int c1, c2, c3, c4;
  900.  
  901.   c1 = (p[0] >> 2) & 0x3f;                     /* first 6 bits of p[0] */
  902.   c2 = (p[0] << 4) & 0x30 | (p[1] >> 4) & 0x0f;/* last 2 p[0] first 4 p[1] */
  903.   c3 = (p[1] << 2) & 0x3c | (p[2] >> 6) & 0x03;/* last 4 of p[1] first 2 p[2] */
  904.   c4 = (p[2] & 0x3f);                          /* last 6 bits if p[2] */
  905.   putc(((c1) ? ((c1) & 0x3f) + 0x20 : 0x60), f);
  906.   putc(((c2) ? ((c2) & 0x3f) + 0x20 : 0x60), f);
  907.   putc(((c3) ? ((c3) & 0x3f) + 0x20 : 0x60), f);
  908.   putc(((c4) ? ((c4) & 0x3f) + 0x20 : 0x60), f);
  909.   count += 4;
  910. }
  911.  
  912. /* This function reads blocks of 45 characters from the input file.  These
  913.    blocks are passed to the encout function in groups of 3 characters where
  914.    they are encoded and written to the output file. */
  915.  
  916. int encode(FILE *in, FILE *out, char *sig)
  917. {
  918.   int i, n;
  919.   char s[81], s1[81];
  920.   char in_drive[MAXDRIVE];
  921.   char in_dir[MAXDIR];
  922.   char in_file[MAXFILE];
  923.   char in_ext[MAXEXT];
  924.   char out_drive[MAXDRIVE];
  925.   char out_dir[MAXDIR];
  926.   char out_file[MAXFILE];
  927.   char out_ext[MAXEXT];
  928.  
  929.   fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
  930.   fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
  931.   for (;;) {
  932.     n = fread(buf, 1, 45, in);
  933.     putc(((n) ? ((n) & 0x3f) + 0x20 : 0x60), out);
  934.     ++count;
  935.     for (i=0; i<n; i += 3)
  936.       encout(&buf[i], out);
  937.     putc('\n', out);
  938.     count = count + 2;
  939.     if((count >=size) && (segs !=1)) {
  940.       fpr(out, "uu end segment %d of %d.\n",seg,segs);
  941.       fclose(out);
  942.       strcpy(s1,forjon(out_path,seg));
  943.       sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
  944.  
  945.       _chmod(s,1,0);
  946.  
  947.       count=0;
  948.       ++seg;
  949.       strcpy(s1,forjon(out_path,seg));
  950.       sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
  951. #ifdef MOD
  952.       npr("          %s%s to produce %s.\r\n",in_file,in_ext,s);
  953. #else
  954.       printf("          %s%s to produce %s.\r\n",in_file,in_ext,s);
  955. #endif
  956.       if((out = fopen(s, "w+")) == NULL) {
  957. #ifdef MOD
  958.         npr("\r\n6Cant open %s.0\r\n",s);
  959.         return(4);
  960. #else
  961.         perror(s);
  962.         exit(4);
  963. #endif
  964.       }
  965.       fpr(out,"section %d of %d uu %s of file %s%s   by J.L.W\n",
  966.     seg,segs,"1.12",in_file,in_ext);
  967.       fpr(out, sig);
  968.       fpr(out,"File name : %s%s\n",s1,out_ext);
  969.       fpr(out, "begin %o %s%s\n", mode, in_file,in_ext);
  970.     }
  971.     if(n <= 0)
  972.       break;
  973.   }
  974.   return(0);
  975. }
  976.  
  977. /* This function calls the other fuctions required to perform the encoding
  978.    of the file.  It is passed the file name and path for the input file and
  979.    hands that information off to the other functions. */
  980.  
  981. void encd()
  982. {
  983.   FILE *in, *out;
  984.   struct stat sbuf;
  985.   struct ftime ft;
  986.   char resp[81], s[81], s1[81], s2[12], sig[81];
  987.   int temp, x, x1=0;
  988.   long in_size, out_size;
  989.   char in_drive[MAXDRIVE];
  990.   char in_dir[MAXDIR];
  991.   char in_file[MAXFILE];
  992.   char in_ext[MAXEXT];
  993.   char out_drive[MAXDRIVE];
  994.   char out_dir[MAXDIR];
  995.   char out_file[MAXFILE];
  996.   char out_ext[MAXEXT];
  997.  
  998.   fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
  999.   fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
  1000.   temp=open(in_path,O_RDONLY);
  1001.   if(temp<=0) {
  1002. #ifdef MOD
  1003.     npr("\r\n6Cant open %s.0\r\n",in_path);
  1004.     return;
  1005. #else
  1006.     perror(in_path);
  1007.     exit(1);
  1008. #endif
  1009.   }
  1010.   getftime(temp,&ft);
  1011.   in_size = filelength(temp);
  1012.   close(temp);
  1013.  
  1014.   out_size = in_size/45;
  1015.   out_size = out_size*63;
  1016.   out_size = out_size+(173*(in_size/size));
  1017.   if((in = fopen(in_path, "rb")) == NULL) {
  1018. #ifdef MOD
  1019.     npr("\r\n6Cant open %s.0\r\n",in_path);
  1020.     return;
  1021. #else
  1022.     perror(in_path);
  1023.     exit(1);
  1024. #endif
  1025.   }
  1026.   if(out_size >=size) {
  1027.     segs = (out_size/size)+1;
  1028.     sprintf(s,"%d",segs);
  1029.     if(strlen(s) > 8) {
  1030. #ifdef MOD
  1031.       npr("Who are you kidding?  %d files?  That is rediculous!",segs);
  1032.       return;
  1033. #else
  1034.       printf("Who are you kidding?  %d files?  That is rediculous!",segs);
  1035.       exit(11);
  1036. #endif
  1037.     }
  1038.     if(strlen(s) > 1) {
  1039. #ifdef MOD
  1040.       npr("Who are you kidding?  %d files?  That seems a little rediculous!",segs);
  1041.       npr("I'll do it for you though Jon; but who is going to send %d messages?",segs);
  1042. #else
  1043.       printf("Who are you kidding?  %d files?  That seems a little rediculous!",segs);
  1044.       printf("I'll do it for you though Jon; but who is going to send %d messages?",segs);
  1045. #endif
  1046.     }
  1047. #ifdef MOD
  1048.     npr("Dividing %s into %d segments.\n\n",in_path,segs);
  1049. #else
  1050.     printf("Dividing %s into %d segments.\n\n",in_path,segs);
  1051. #endif
  1052.     for(x = seg; x < segs+1    ; ++x ) {
  1053.       strcpy(s1,forjon(out_path,x));
  1054.       sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
  1055.       if(exist(s)) {
  1056.     printf("   The file %s already exists.\n",s);
  1057.         x1=1;
  1058.       }
  1059.     }
  1060.     if(x1) {
  1061. #ifdef MOD
  1062.       npr("\nDo you want to overwrite? %s (Y/N) ",s);
  1063. #else
  1064.       printf("\nDo you want to overwrite? %s (Y/N) ",s);
  1065. #endif
  1066.       scanf("%s",resp);
  1067.       if((resp[0]!='Y') && (resp[0]!='y')) {
  1068. #ifdef MOD
  1069.         npr("Choosing not to overwrite, aborting.\r\n");
  1070.         return;
  1071. #else
  1072.         printf("Choosing not to overwrite, aborting.\n");
  1073.         exit(7);
  1074. #endif
  1075.       }
  1076.     }
  1077.     for(x = seg; x < segs+1 ; ++x ) {
  1078.       strcpy(s1,forjon(out_path,x));
  1079.       sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
  1080.       delete_file(s);
  1081.     }
  1082.     strcpy(s1,forjon(out_path,seg));
  1083.     sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
  1084.   } else {
  1085.     strcpy(s1,in_file);
  1086.     sprintf(s,"%s%s%s%s",out_drive,out_dir,in_file,out_ext);
  1087.     if(exist(s)) {
  1088. #ifdef MOD
  1089.       npr("\nDo you want to overwrite? %s (Y/N) ",s);
  1090. #else
  1091.       printf("\nDo you want to overwrite? %s (Y/N) ",s);
  1092. #endif
  1093.       scanf("%s",resp);
  1094.       if((resp[0]!='Y') && (resp[0]!='y')) {
  1095. #ifdef MOD
  1096.         npr("Choosing not to overwrite, aborting.\r\n");
  1097.         return;
  1098. #else
  1099.         printf("Choosing not to overwrite, aborting.\n");
  1100.         exit(7);
  1101. #endif
  1102.       }
  1103.     }
  1104.   }
  1105.   if((out = fopen(s, "w+")) == NULL) {
  1106. #ifdef MOD
  1107.     npr("\r\n6Cant open %s.0\r\n",s);
  1108.     return;
  1109. #else
  1110.     perror(s);
  1111.     exit(4);
  1112. #endif
  1113.   }
  1114.   if(fstat(fileno(in), &sbuf) < 0 || !isatty(fileno(in)))
  1115.      mode = 0666 & ~umask(0666);
  1116.   else
  1117.      mode = sbuf.st_mode & 0777;
  1118.   fpr(out,"section %d of %d uu %s of file %s%s   by J.L.W\n",
  1119.     seg,segs,"1.12",in_file,in_ext);
  1120.   fpr(out,"File name : %s%s\n",s1,out_ext);
  1121.   sprintf(sig, "File signature : %u/%u/%u %u:%u:%u %ld\n\n",
  1122.     ft.ft_month, ft.ft_day, ft.ft_year+1980,
  1123.     ft.ft_hour, ft.ft_min,ft.ft_tsec * 2,in_size);
  1124.   fpr(out, sig);
  1125.   fpr(out, "begin %o %s%s\n", mode, in_file,in_ext);
  1126.   sprintf(s,"%s%s",in_file,in_ext);
  1127. #ifdef MOD
  1128.   npr("\r\nENCODING  %s to produce %s%s.\n",s,s1,out_ext);
  1129. #else
  1130.   printf("\r\nENCODING  %s to produce %s%s.\n",s,s1,out_ext);
  1131. #endif
  1132.  
  1133.   encode(in, out, sig);
  1134.  
  1135.   fpr(out, "end\n");
  1136.   fclose(out);
  1137.   strcpy(s1,forjon(out_path,seg));
  1138.   sprintf(s,"%s%s%s%s",out_drive,out_path,s1,out_ext);
  1139.   _chmod(s,1,0);
  1140. }
  1141.  
  1142. #ifndef MOD
  1143.  
  1144. /* This function locates and loads the UU config file.  It is not currently
  1145.    called by the mod version of UU; but may soon be. */
  1146.  
  1147. int uudefault() /* EXE only */
  1148. {
  1149.   FILE *cfg;
  1150.   int cfgerror=0;
  1151.   char errm[81];
  1152.   char in_ext[MAXEXT];
  1153.   char out_ext[MAXEXT];
  1154.  
  1155.   if(exist(home_path)) {
  1156.     if((cfg = fopen(home_path, "r")) == NULL) {
  1157.       strcpy(errm,"Can't seem to access my cfg file");
  1158.       cfgerror |= 1;
  1159.       perror(home_path);
  1160.       return(1);
  1161.     }
  1162.     fseek(cfg, 0, SEEK_SET);
  1163.     for (;;) {
  1164.       if(fgets(buf, sizeof buf, cfg) == NULL) {
  1165.     fprintf(stderr, "No in ext line\n");
  1166.         cfgerror |= 2;
  1167.         return(3);
  1168.       }
  1169.       if(strncmp(buf, "in ext:", 7) == 0)
  1170.         break;
  1171.     }
  1172.     (void)sscanf(buf, "in ext:%s", &in_ext);
  1173.  
  1174.     fseek(cfg, 0, SEEK_SET);
  1175.     for (;;) {
  1176.       if(fgets(buf, sizeof buf, cfg) == NULL) {
  1177.     fprintf(stderr, "No out ext line\n");
  1178.         cfgerror |= 4;
  1179.         return(3);
  1180.       }
  1181.       if(strncmp(buf, "out ext:", 8) == 0)
  1182.         break;
  1183.     }
  1184.     (void)sscanf(buf, "out ext:%s", &out_ext);
  1185.  
  1186.     fseek(cfg, 0, SEEK_SET);
  1187.     for (;;) {
  1188.       if(fgets(buf, sizeof buf, cfg) == NULL) {
  1189.     fprintf(stderr, "No output file size line\n");
  1190.         cfgerror |= 8;
  1191.         return(3);
  1192.       }
  1193.       if(strncmp(buf, "out size:", 9) == 0)
  1194.         break;
  1195.     }
  1196.     (void)sscanf(buf, "out size:%ld", &size);
  1197.  
  1198.     fseek(cfg, 0, SEEK_SET);
  1199.     for (;;) {
  1200.       if(fgets(buf, sizeof buf, cfg) == NULL) {
  1201.     fprintf(stderr, "No output file line count line\n");
  1202.         cfgerror |= 16;
  1203.         return(3);
  1204.       }
  1205.       if(strncmp(buf, "out line:", 9) == 0)
  1206.         break;
  1207.     }
  1208.     (void)sscanf(buf, "out line:%d", &line);
  1209.   } else {
  1210. #ifdef MOD
  1211.     npr("can't find my .cfg file.\r\n");
  1212. #else
  1213.     printf("can't find my .cfg file.\n");
  1214. #endif
  1215.   }
  1216.   return(1);
  1217. }
  1218.  
  1219. /* This function locates and displays the UU help file.  It is not currently
  1220.    called by the mod version of UU; but may soon be. */
  1221.  
  1222. int help() /* EXE only */
  1223. {
  1224.   FILE *hlp;
  1225.   int hlperror=0;
  1226.   char errm[81];
  1227.   char resp[3];
  1228.  
  1229.   if(exist(home_path)) {
  1230.     if((hlp = fopen(home_path, "r")) == NULL) {
  1231.       strcpy(errm,"Can't seem to access my help file");
  1232.       hlperror |= 1;
  1233.       perror(home_path);
  1234.       return(hlperror);
  1235.     }
  1236.     fseek(hlp, 0, SEEK_SET);
  1237.     for (;;) {
  1238.       if(fgets(buf, sizeof buf, hlp) == NULL) {
  1239.     fprintf(stderr, "Unexpected end of file.\n");
  1240.         hlperror |= 2;
  1241.         return(3);
  1242.       }
  1243.       if(strncmp(buf, "end help", 8) == 0)
  1244.         break;
  1245.       else if(strncmp(buf, "page help", 8) == 0) {
  1246. #ifdef MOD
  1247.         npr("More? (Y/N) ");
  1248. #else
  1249.         printf("More? (Y/N) ");
  1250. #endif
  1251.         scanf("%s",resp);
  1252.         if((resp[0]!='Y') && (resp[0]!='y'))
  1253.           return(0);
  1254.         clrscr();
  1255.     sprintf(errm,"UU.EXE version %s by Jim Wire\r\n",UU_VER_NO);
  1256.     printf(errm);
  1257.       }
  1258.       else
  1259. #ifdef MOD
  1260.         npr(buf);
  1261. #else
  1262.         printf(buf);
  1263. #endif
  1264.     }
  1265.   } else {
  1266. #ifdef MOD
  1267.     npr("can't find my .hlp file.\r\n");
  1268. #else
  1269.     printf("can't find my .hlp file.\n");
  1270. #endif
  1271.   }
  1272.   return(1);
  1273. }
  1274.  
  1275. /* Stolen from WWIV, this little guy checks for the file */
  1276.  
  1277. int exist(char *s) /* EXE only */
  1278. {
  1279.   int f;
  1280.  
  1281.   f=open(s,O_RDONLY | O_BINARY);
  1282.   close(f);
  1283.   if(f>0) {
  1284.     _chmod(s,1,0);
  1285.     return(1);
  1286.   } else
  1287.     return(0);
  1288. }
  1289.  
  1290.  
  1291. int main(int argc, char *argv[]) /* EXE only */
  1292. {
  1293.   char s[81],s1[12],cmd[3],resp[81];
  1294.   int res;
  1295.  
  1296.   char in_drive[MAXDRIVE];
  1297.   char in_dir[MAXDIR];
  1298.   char in_file[MAXFILE];
  1299.   char in_ext[MAXEXT];
  1300.   char out_drive[MAXDRIVE];
  1301.   char out_dir[MAXDIR];
  1302.   char out_file[MAXFILE];
  1303.   char out_ext[MAXEXT];
  1304.   int out_flags=0;
  1305.   char home_drive[MAXDRIVE];
  1306.   char home_dir[MAXDIR];
  1307.   char home_file[MAXFILE];
  1308.   char home_ext[MAXEXT];
  1309.  
  1310.   clrscr();
  1311.   sprintf(s,"UU.EXE version %s by Jim Wire\r\n",UU_VER_NO);
  1312.   printf(s);
  1313.   fnsplit(argv[0],home_drive,home_dir,home_file,home_ext);
  1314.   fnmerge(home_path,home_drive,home_dir,home_file,".CFG");
  1315.   uudefault();
  1316.   if(argc >= 2) {
  1317.     strcpy(s,argv[1]);
  1318.     strcpy(cmd,s+strlen(s)-1);
  1319.   }
  1320.   if((argc < 3) || ((strcmp(cmd,"H")==0)
  1321.     || (strcmp(cmd,"h")==0) || (strcmp(cmd,"?")==0))) {
  1322.     fnmerge(home_path,home_drive,home_dir,home_file,".HLP");
  1323.     help();
  1324.     return(0);
  1325.   } else {
  1326.     fnsplit(argv[2],in_drive,in_dir,in_file,in_ext);
  1327.     fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
  1328.     if((strcmp(cmd,"E")==0) || (strcmp(cmd,"e")==0)) {
  1329.       if(argc == 4) {
  1330.         out_flags=fnsplit(argv[3],out_drive,out_dir,out_file,out_ext);
  1331.     if(!(out_flags & DRIVE))
  1332.       strcpy(out_drive,in_drive);
  1333.     if(!(out_flags & DIRECTORY) && (strcmp(out_drive,in_drive) !=0))
  1334.       strcpy(out_dir,in_dir);
  1335.     if(!((out_flags & FILENAME) && (out_flags & EXTENSION))) {
  1336.           strcpy(out_file,in_file);
  1337.           strcpy(out_ext,".UUE");
  1338.         }
  1339.       } else {
  1340.         out_flags=fnsplit(in_path,out_drive,out_dir,out_file,out_ext);
  1341.         strcpy(out_ext,".UUE");
  1342.       }
  1343.       if(strcmp(out_ext,".UUE") !=0) {
  1344.         printf("Allow command line to override default? (Y/N)");
  1345.         scanf("%s",resp);
  1346.         if((resp[0]!='Y') && (resp[0]!='y'))
  1347.           strcpy(out_ext,".UUE");
  1348.       }
  1349.       fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
  1350.       res=encd();
  1351.     }
  1352.     if((strcmp(cmd,"D")==0) || (strcmp(cmd,"d")==0)) {
  1353.       if(argc == 4) {
  1354.         out_flags=fnsplit(argv[3],out_drive,out_dir,out_file,out_ext);
  1355.     if(!(out_flags & DRIVE))
  1356.       strcpy(out_drive,in_drive);
  1357.     if(!(out_flags & DIRECTORY) && (strcmp(out_drive,in_drive) !=0))
  1358.       strcpy(out_dir,in_dir);
  1359.     if((out_flags & FILENAME) && (out_flags & EXTENSION)) {
  1360.       out_file_specified=1;
  1361.       fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
  1362.     } else
  1363.       fnmerge(out_path,out_drive,out_dir,in_file,in_ext);
  1364.       } else
  1365.         fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
  1366.       res=decd();
  1367.     }
  1368.     if(res==0) {
  1369.       printf("Success.\r\n");
  1370.     }
  1371.   }
  1372.   return(res);
  1373. }
  1374.  
  1375. #endif
  1376.