/* Xsend Wednesday, March 30, 1988 Version 0.4 added blank lines for server cwd password Saturday, November 21, 1987 Version 0.3 added kludged turbo dir functions for IBM & Microsoft C Version 0.2 attempt to do above with far pointers to ffblk failed. Version 0.1 by Mark S. Zinzow (MARKZ@UIUCVMD.BITNET or markz@vmd.cso.uiud.edu) Program to generate TAKE (script) files for MS-DOS Kermit to allow it to send files and directories to a server over entire tree branches or disks. This version generates commands with absolute path names. Change directory to the desired directory below which you wish all files and subdirectories copied. Then run XSEND redirecting the output with the dos redirection symbol ">". (e.g. C:>XSEND >takeme) Then establish a connection to the remote system with kermit and put the remote system in server mode. Then just take the take file on the local system. If you wish to avoid the password prompt on the remote cwd commands use MS-Kermit 2.30/A or later and redirect the takeme file into it. (For example KERMIT #ifdef __TURBOC__ #include #endif #include #include #ifndef __TURBOC__ /* from Turbo errno.h */ #define ENOENT 2 /* No such file or directory */ #define ENMFILE 18 /* No more files */ extern int errno; /* From turbo dir.h */ struct ffblk { char ff_reserved[21]; char ff_attrib; unsigned ff_ftime; unsigned ff_fdate; long ff_fsize; char ff_name[13]; }; /* int findfirst(char far *pathname, struct ffblk *ffblk, int attrib); int findnext(struct ffblk *ffblk); /* MSC doesn't like far in forward declarations even with /Ze? */ /* From Turbo dos.h */ #define FA_RDONLY 0x01 /* Read only attribute */ #define FA_HIDDEN 0x02 /* Hidden file */ #define FA_SYSTEM 0x04 /* System file */ #define FA_LABEL 0x08 /* Volume label */ #define FA_DIREC 0x10 /* Directory */ #define FA_ARCH 0x20 /* Archive */ #endif #define MAXDIRLEN 84 /* maximum string length for path strings */ /* The dos maximum is 64 bytes */ #ifdef __TURBOC__ int ls (char *twd); #endif main () { int i; char cwd[MAXDIRLEN]; /* string to hold Current Working Directory */ getcwd(cwd,MAXDIRLEN); i = strlen(cwd) - 1; printf("echo XSEND Version 0.4 Kermit script. Pipe to MS-Kermit.\n"); if ( i > 2 ) /* don't create root, it's already there I hope! */ printf("remote host mkdir %s\n",&cwd[2]); printf("remote cwd %s\n\n",&cwd[2]); /* [2] to chop d: */ if ( i >= 0 && cwd[i] == '\\' ) cwd[i] = '\0'; /* chop \ from drive letter*/ printf("send %s\\*.*\n",&cwd[2]); ls(cwd); } ls(twd) char twd[]; { char xwd[MAXDIRLEN]; char far *p; struct ffblk ffblk; int done; strcpy(xwd,twd); strcat(xwd,"\\*.*"); p = &xwd[0]; done = findfirst(p,&ffblk,FA_DIREC); /* &ffblk seems to be near */ while (!done) { if ((ffblk.ff_attrib & FA_DIREC) && (ffblk.ff_name[0] != '.' )) { strcpy(xwd,twd); strcat(xwd,"\\"); strcat(xwd,ffblk.ff_name); printf("remote host mkdir %s\n",&xwd[2]); /* [2] to chop d: */ printf("remote cwd %s\n\n",&xwd[2]); printf("send %s\\*.*\n",&xwd[2]); ls(xwd); /* recursive call on directories other than . and .. */ } done = findnext(&ffblk); } return; } # ifndef __TURBOC__ /* function written from description in Turbo reference and dos manual with out turbo source for compatibility with other compiler(s?). */ /* I added far to the declarations as I can't figure out how to do this near and far as a general case. Perhaps some cleaver use of sizeof? */ findfirst(pathname, ffblk, attrib) char far *pathname; struct ffblk *ffblk; int attrib; { struct SREGS sregs; union REGS inregs, outregs; int result; char far *p; extern int errno; /* Set Disk Transfer Area to ffblk structure passed */ segread(&sregs); /* Set DTA wants DS:DX to point to */ /* I use the current DS register as I can't figure out how to get a far address to a structure declared and passed, so I'm assuming near. My appologies for this brute force and ignorance (trial and error) solution. Please send me the more elogant method if you can get the compiler to do it! When declaring far *ffblk FP_SEG returned attrib! */ inregs.x.dx = FP_OFF(ffblk); /* the disk transfer area to be set */ inregs.h.ah = 0x1a; /* Set Disk Transfer Area */ result = int86x(0x21,&inregs,&outregs,&sregs); sregs.ds = FP_SEG(pathname); /* FindFirst wants DS:DX to point to */ inregs.x.dx = FP_OFF(pathname); /* an ASCIIZ string */ inregs.x.cx = attrib; inregs.h.ah = 0x4e; /* FindFirst */ errno = int86x(0x21,&inregs,&outregs,&sregs); if ( errno == ENOENT || errno == ENMFILE ) return(-1); /* if (outregs.x.cflag) return(-1); /* not sure about this one */ return(0); } int findnext(ffblk) struct ffblk far *ffblk; { struct SREGS sregs; union REGS inregs, outregs; int result; extern int errno; /* Set Disk Transfer Area to ffblk structure passed */ segread(&sregs); inregs.x.dx = FP_OFF(ffblk); /* the disk transfer area to be set */ inregs.h.ah = 0x1a; /* Set Disk Transfer Area */ result = int86x(0x21,&inregs,&outregs,&sregs); inregs.h.ah = 0x4f; /* FindNext */ errno = int86x(0x21,&inregs,&outregs,&sregs); if ( errno == ENMFILE ) return(-1); /* if (outregs.x.cflag) return(-1); /* not sure about this one */ return(0); } #endif