home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msixse.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  9KB  |  315 lines

  1. /*
  2.   XSEND - Generates command files for MS-DOS Kermit, ftp, and other PC file
  3.   transfer programs, to send and replicate tree-structured file systems.
  4.  
  5.     Mon,  4 Mar 91 - Frank da Cruz, Columbia University
  6.     Minor corrections to syntax of constructed Kermit commands.
  7.  
  8.     Fri, 21 Apr 89 - Vace Kundakci, Columbia University
  9.     Version 0.5V add tftp (and other) support and parse switches on the
  10.         arg line
  11.  
  12.     Thu, 20 Apr 89 - Vace Kundakci, Columbia University
  13.     Version 0.4V eliminate full path specification to server and add cd ..
  14.  
  15.     Program created by, and all previous edits by, Mark Zinzow:
  16.  
  17.     Wednesday, March 30, 1988
  18.     Version 0.4 added blank lines for server cwd password
  19.  
  20.     Saturday, November 21, 1987
  21.     Version 0.3 added kludged turbo dir functions for IBM & Microsoft C
  22.  
  23.     Version 0.2 attempt to do above with far pointers to ffblk failed.
  24.     Version 0.1
  25.         by Mark S. Zinzow
  26.         (MARKZ@UIUCVMD.BITNET or markz@vmd.cso.uiud.edu)
  27.  
  28.     Program to generate TAKE (script) files for MS-DOS Kermit to allow it
  29.     to send files and directories to a server over entire tree branches or
  30.     disks.
  31.  
  32.     Change directory to the desired directory in which you wish all
  33.     files and subdirectories copied.  Then run XSEND redirecting the
  34.     output with the dos redirection symbol ">". (e.g. C:>XSEND >takeme)
  35.     Then establish a connection to the remote system with kermit and put
  36.     the remote system in server mode.  Then just take the take file on the
  37.     local system.  If you wish to avoid the password prompt on the remote
  38.     cwd commands use MS-Kermit 2.30/A or later and redirect the takeme
  39.     file into it.  (For example KERMIT <takeme but don't forget to make
  40.     sure you have the right parity, baud, and port etc. set in your ini
  41.     file, or use a text editor to add the appropriate set commands to your
  42.     take file.)
  43.  
  44.     Compileable with Microsoft C 5.0 and Borland TurboC Version 1.0
  45. */
  46.  
  47. #include <stdio.h>
  48.  
  49. #ifdef __TURBOC__
  50. #include <dir.h>
  51. #endif
  52.  
  53. #include <dos.h>
  54. #include <string.h>
  55.  
  56. #ifndef __TURBOC__
  57.  
  58. /* from Turbo errno.h  */
  59. #define ENOENT  2       /* No such file or directory */
  60. #define ENMFILE 18      /* No more files */
  61.  
  62. extern int errno;
  63.  
  64. /* From turbo dir.h */
  65. struct  ffblk {
  66.     char        ff_reserved[21];
  67.     char        ff_attrib;
  68.     unsigned    ff_ftime;
  69.     unsigned    ff_fdate;
  70.     long        ff_fsize;
  71.     char        ff_name[13];
  72. };
  73.  
  74. /* From Turbo dos.h */
  75. #define FA_RDONLY   0x01    /* Read only attribute */
  76. #define FA_HIDDEN   0x02    /* Hidden file */
  77. #define FA_SYSTEM   0x04    /* System file */
  78. #define FA_LABEL    0x08    /* Volume label */
  79. #define FA_DIREC    0x10    /* Directory */
  80. #define FA_ARCH     0x20    /* Archive */
  81.  
  82. #endif
  83.  
  84. #define FILEALL     0xF7
  85. #define FILENONE    0x16
  86.  
  87. #define MAXDIRLEN   84  /* maximum string length for path strings */
  88.                 /* the dos maximum is 64 bytes */
  89. #ifdef __TURBOC__
  90. int ls (char *twd);
  91. #endif
  92.  
  93. char *comm;
  94. char *move;
  95. char *md;
  96. char *cd;
  97. char opc;
  98. char hn[64];
  99. char fn[13];
  100. int vflag;
  101. int cwdlen;
  102.  
  103. main (argc,argv) int argc; char *argv[]; {
  104.     int i;
  105.     char cwd[MAXDIRLEN]; /* string to hold Current Working Directory */
  106.     char pn[MAXDIRLEN];
  107.     char c[MAXDIRLEN];
  108.  
  109.     opc = 'k';
  110.     strcpy(hn,"");
  111.     strcpy(fn,"*.*");
  112.     strcpy(pn,"");
  113.     md = "mkdir";
  114.     cd = "cd";
  115.     comm = "rem";
  116.     vflag = 0;
  117.  
  118.     for (i = 1; i < argc; i++) {
  119.         strcpy(c,argv[i]);
  120.         if (c[0] == '-') {
  121.             switch(c[1]) {
  122.                 case 'g':
  123.                 case 'p':
  124.                 case 'm':
  125.                 case 'z':
  126.                 case 'l':
  127.                 case 'c':
  128.                 case 'k': opc = c[1]; strcpy(pn,&c[2]); break;
  129.  
  130.                 case 'h': strcpy(hn,&c[2]); break;
  131.  
  132.                 case 'v': vflag = 1; break;
  133.  
  134.                 case 'f': strcpy(fn,&c[2]); break;
  135.  
  136.                 default:
  137.                     printf("xsend switches: ckmgpzlvf\n");
  138.                     exit(0);
  139.             }
  140.         } else {
  141.             printf("usage: xsend switches\n");
  142.             printf("  -k[path]: kermit commands (default)\n");
  143.             printf("  -c[path]: copy commands\n");
  144.             printf("  -m[path]: mkdir commands\n");
  145.             printf("  -z[path]: del and rmdir commands\n");
  146.             printf("  -l[path]: list full names\n");
  147.             printf("  -g[path]: tftp get commands\n");
  148.             printf("  -p[path]: tftp put commands\n");
  149.             printf("  -h<name>: tftp to/from host\n");
  150.             printf("  -f<name>: select files with name\n");
  151.             printf("  -v: verbose (applies for -cklz)\n");
  152.             exit(0);
  153.         }
  154.     }
  155.  
  156.     switch(opc) {
  157.         case 'm': vflag = 0; break;
  158.         case 'z': move = "del"; break;
  159.         case 'c': move = "copy"; break;
  160.         case 'l': move = "f"; break;
  161.  
  162.         case 'g':
  163.         case 'p':
  164.             if (hn[0] == '\0') {
  165.                 printf("no hostname");
  166.                 exit(0);
  167.             }
  168.             move = "tftp"; vflag = 1; break;
  169.  
  170.         case 'k':
  171.             md = "remote host mkdir"; cd = "remote cd";
  172.             move = "send"; comm = "echo"; break;
  173.     }
  174.  
  175.     printf("%s XSEND Version 0.5V\n",comm);
  176.  
  177.     if (pn[0] == '\0') getcwd(cwd,MAXDIRLEN); else strcpy(cwd,pn);
  178.     i = strlen(cwd) - 1;
  179.     if (i >= 0 && cwd[i] == '\\') cwd[i] = '\0'; /* chop ending \ */
  180.     cwdlen = strlen(cwd);
  181.     ls(cwd);
  182. }
  183.  
  184. ls(twd) char twd[]; {
  185.     char xwd[MAXDIRLEN];
  186.     char far *p;
  187.     struct ffblk ffblk;
  188.     int done;
  189.  
  190.     strcpy(xwd,twd);
  191.     strcat(xwd,"\\");
  192.     strcat(xwd,fn);
  193.     p = &xwd[0];
  194.     if (!vflag && (opc != 'm') && (opc != 'l'))
  195.         printf("%s %s\n",move,xwd);
  196.  
  197.     done = findfirst(p,&ffblk,FILEALL) || !vflag;
  198.     while (!done) {
  199.         if (!(ffblk.ff_attrib & FILENONE)) {
  200.         switch (opc) {
  201.             case 'p':
  202.             if (cwdlen == strlen(twd))
  203.                 printf("tftp -p %s\\%s %s %s image\n",
  204.                 twd,ffblk.ff_name,hn,ffblk.ff_name);
  205.             else
  206.                 printf("tftp -p %s\\%s %s %s\\%s image\n",
  207.                 twd,ffblk.ff_name,hn,&twd[cwdlen + 1],
  208.                 ffblk.ff_name);
  209.             break;
  210.  
  211.             case 'g':
  212.             printf("tftp -g %s\\%s %s %s image\n",
  213.                 twd,ffblk.ff_name,hn,ffblk.ff_name);
  214.             break;
  215.  
  216.             case 'z':
  217.             case 'c':
  218.             case 'l':
  219.             case 'k':
  220.             printf("%s %s\\%s\n",move,twd,ffblk.ff_name);
  221.         }
  222.         }
  223.         done = findnext(&ffblk);
  224.     }
  225.  
  226.     strcpy(xwd,twd);
  227.     strcat(xwd,"\\*.*");
  228.     p = &xwd[0];
  229.  
  230.     done = findfirst(p,&ffblk,FILEALL); /* &ffblk seems to be near */
  231.     while (!done) {
  232.         if ((ffblk.ff_attrib & FA_DIREC) && (ffblk.ff_name[0] != '.' )) {
  233.         strcpy(xwd,twd);
  234.         strcat(xwd,"\\");
  235.         strcat(xwd,ffblk.ff_name);
  236.         if ((opc != 'l') && (opc != 'p') && (opc != 'z'))
  237.             printf("%s %s\n",md,ffblk.ff_name);
  238.         if (opc != 'l') printf("%s %s\n\n",cd,ffblk.ff_name);
  239.         else if (!vflag) printf ("d %s\n",xwd);
  240.         ls(xwd);
  241.         if (opc != 'l') printf("%s ..\n",cd);
  242.         if (opc == 'z') printf("rmdir %s\n",ffblk.ff_name);
  243.         }
  244.         done = findnext(&ffblk);
  245.     }
  246.     return;
  247. }
  248.  
  249. # ifndef __TURBOC__
  250.  
  251. /*
  252.     function written from description in Turbo reference and dos manual
  253.     without turbo source for compatibility with other compiler(s?).  I
  254.     added far to the declarations as I can't figure out how to do this
  255.     near and far as a general case.  Perhaps some clever use of sizeof?
  256. */
  257.  
  258. findfirst(pathname, ffblk, attrib)
  259. char far *pathname;
  260. struct ffblk *ffblk;
  261. int attrib;
  262. {
  263.     struct SREGS sregs;
  264.     union REGS inregs, outregs;
  265.     int result;
  266.     char far *p;
  267.     extern int errno;
  268.  
  269. /* Set Disk Transfer Area to ffblk structure passed */
  270.  
  271.     segread(&sregs);        /* Set DTA wants DS:DX to point to */
  272.     inregs.x.dx = FP_OFF(ffblk);    /* the disk transfer area to be set */
  273.     inregs.h.ah = 0x1a;     /* Set Disk Transfer Area */
  274.     result = int86x(0x21,&inregs,&outregs,&sregs);
  275.  
  276.     sregs.ds = FP_SEG(pathname);    /* FindFirst wants DS:DX to point */
  277.     inregs.x.dx = FP_OFF(pathname); /* to an ASCIIZ string */
  278.     inregs.x.cx = attrib;
  279.     inregs.h.ah = 0x4e;     /* FindFirst */
  280.     errno = int86x(0x21,&inregs,&outregs,&sregs);
  281.  
  282.     if (errno == ENOENT || errno == ENMFILE) return(-1);
  283.     return(0);
  284. }
  285.  
  286. int findnext(ffblk) struct ffblk far *ffblk; {
  287.     struct SREGS sregs;
  288.     union REGS inregs, outregs;
  289.     int result;
  290.     extern int errno;
  291.  
  292. /*
  293.     I use the current DS register as I can't figure out how to get a far
  294.     address to a structure declared and passed, so I'm assuming near.  My
  295.     appologies for this brute force and ignorance (trial and error)
  296.     solution.  Please send me the more elegant method if you can get the
  297.     compiler to do it!  When declaring far *ffblk FP_SEG returned attrib!
  298.     - mz
  299. */
  300.  
  301. /* Set Disk Transfer Area to ffblk structure passed */
  302.  
  303.     segread(&sregs);
  304.     inregs.x.dx = FP_OFF(ffblk);    /* the disk transfer area to be set */
  305.     inregs.h.ah = 0x1a;     /* Set Disk Transfer Area */
  306.     result = int86x(0x21,&inregs,&outregs,&sregs);
  307.  
  308.     inregs.h.ah = 0x4f;     /* FindNext */
  309.     errno = int86x(0x21,&inregs,&outregs,&sregs);
  310.  
  311.     if (errno == ENMFILE) return(-1);
  312.     return(0);
  313. }
  314. #endif
  315.