home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / xmodem / part01 next >
Encoding:
Internet Message Format  |  1987-01-18  |  29.2 KB

  1. Subject:  v07i092:  Full-featured XMODEM, Part01/02
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!noao!grandi (Steve Grandi)
  6. Mod.sources: Volume 7, Issue 92
  7. Archive-name: xmodem/Part01
  8.  
  9. [  Sorry.  If I vanish again, I'll at least let you folks know.  --r$  ]
  10.  
  11. : This is a shar archive.  Extract with sh, not csh.
  12. echo x - README
  13. sed -e 's/^X//' > README << '!Funky!Stuff!'
  14. XThe xmodem program implements the Christensen (XMODEM) file transfer
  15. Xprotocol for moving files between 4.2/4.3BSD Unix systems and microcomputers.
  16. XThe XMODEM/CRC protocol, the MODEM7 batch protocol, the XMODEM-1K
  17. Xblock protocol and the YMODEM batch protocol are all supported by xmodem.
  18. XFor details of the protocols, see the document edited by Chuck Forsberg titled
  19. XXMODEM/YMODEM Protocol Reference.
  20. X
  21. XThis program runs on 4.2/4.3BSD systems ONLY.  It has been tested on VAXes
  22. Xand Suns against the MEX-PC program from Niteowl Software.
  23. X
  24. XI have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty structures,
  25. Xgettimeofday system call, etc.) confined to the source file getput.c; but I 
  26. Xmake no guarantees.  Also, I have made no attempt to keep variable names 
  27. Xunder 7 characters.
  28. X
  29. X
  30. XProgram history:
  31. X
  32. XDescended from UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
  33. X
  34. XBased on XMODEM Version 1.0 by Brian Kantor, UCSD (3/84)  (Don't blame him 
  35. Xfor what follows....)
  36. X
  37. XVersion 2.0 (CRC-16 and Modem7 batch file transfer) (5/85)
  38. X
  39. XVersion 2.1 (1K packets) (7/85)
  40. X
  41. XVersion 2.2 (general clean-ups and multi-character read speed-ups) (9/85)
  42. X
  43. XVersion 2.3 (nap while reading packets; split into several source files) (1/86)
  44. X
  45. XVersion 3.0 (Ymodem batch receive; associated changes) (2/86)
  46. X
  47. XVersion 3.1 (Ymodem batch send; associated changes) (8/86)
  48. X
  49. XVersion 3.2 (general cleanups) (9/86)
  50. X
  51. X
  52. X
  53. XPlease send bug fixes, additions and comments to:
  54. XSteve Grandi, National Optical Astronomy Observatories (Tucson, Arizona)
  55. X    {ihnp4,seismo,hao,arizona,...}!noao!grandi 
  56. !Funky!Stuff!
  57. echo x - xmodem.1
  58. sed -e 's/^X//' > xmodem.1 << '!Funky!Stuff!'
  59. X.TH XMODEM LOCAL "August 26, 1986"
  60. X.UC 4.2
  61. X.SH NAME
  62. Xxmodem \- Christensen protocol file transfer utility
  63. X.SH SYNOPSIS
  64. X.B xmodem
  65. X[\fBst|sb|rt|rb\fR][\fBYBKcdlx\fR]
  66. X[file...]
  67. X.br
  68. X.SH DESCRIPTION
  69. XThe
  70. X.I xmodem
  71. Xprogram implements the Christensen (XMODEM) file transfer
  72. Xprotocol for moving files between 4.2/4.3BSD Unix systems and microcomputers.
  73. XThe XMODEM/CRC protocol, the MODEM7 batch protocol, the XMODEM-1K
  74. Xblock protocol and the YMODEM batch protocol are all supported by 
  75. X.IR xmodem .
  76. XFor details of the protocols,
  77. Xsee the document edited by Chuck Forsberg titled
  78. X.I
  79. XXMODEM/YMODEM Protocol Reference.
  80. X.sp
  81. XThis program runs on 4.2/4.3BSD systems ONLY.  It has been tested on VAXes
  82. Xand Suns against the MEX-PC program from Niteowl Software.
  83. X.PP
  84. X.SH PARAMETERS
  85. XExactly one of the following must be selected:
  86. X.TP
  87. X.B rb  
  88. XReceive Binary - files are placed on the Unix disk without conversion.
  89. X.I Xmodem
  90. Xwill silently destroy existing files of the same name.
  91. X.TP
  92. X.B rt  
  93. XReceive Text - files are converted from the CP/M format of CR-LF pairs to the Unix
  94. Xconvention of 
  95. X.I newline 
  96. Xcharacters only between lines.  
  97. XBit 8 of each character is stripped (which makes Wordstar files much
  98. Xmore readable).
  99. XThe resulting file
  100. Xis acceptable to the Unix editors and compilers, and is usually slightly
  101. Xsmaller than the original CP/M file.
  102. X.I Xmodem
  103. Xwill silently destroy existing files of the same name.
  104. X.TP
  105. X.B sb  
  106. XSend Binary - files are sent without conversion as they exist on the Unix disk.
  107. X.TP
  108. X.B st  
  109. XSend Text - newline characters in the file are converted to CR-LF pairs
  110. Xin accord with the CP/M conventions for text files.  The file grows
  111. Xslightly as this occurs so the estimate of file transmission size and
  112. Xtime are always optimistically low.
  113. X.PP
  114. X.SH OPTIONS
  115. X.TP
  116. X.B Y
  117. XSelect the YMODEM batch protocol for sending files; a list of files specified
  118. Xon the command line will be sent in sequence.  The YMODEM batch protocol is 
  119. Xused automatically for file reception if the sending program requests it.
  120. X.TP
  121. X.B B
  122. XSelect the MODEM7 batch protocol for sending files; a list of files specified
  123. Xon the command line will be sent in sequence.  The MODEM7 batch protocol is 
  124. Xused automatically for file reception if the sending program requests it.
  125. X.TP
  126. X.B K
  127. XSelect the XMODEM-1K file transfer mode for sending files. Use of 1K packets on
  128. Xlow-error lines increases throughput.  1K packets are automatically
  129. Xused for file reception if the sending program requests it.
  130. X.TP
  131. X.B c   
  132. XSelect the CRC-16 error-checking protocol on receive.  CRC mode is better at catching
  133. Xtransmission errors that occur than the alternative checksum protocol.  
  134. XCRC mode is automatically selected for file
  135. Xtransmission if the receiving modem program requests it.
  136. X.TP
  137. X.B d   
  138. XDelete the 
  139. X.I xmodem.log
  140. Xfile before file transfer is begun.
  141. X.TP
  142. X.B l   
  143. XDo NOT write to the log file.  If logging is selected, a file
  144. X.I xmodem.log 
  145. Xwill be created (or appended to), with entries for significant events, errors
  146. Xand retries.  This can be useful to see why things went wrong
  147. Xwhen they do.
  148. X.TP
  149. X.B x
  150. XToggle on debug mode.  If debug mode is selected, copious and possibly
  151. Xuseful debugging information will be placed in 
  152. X.IR xmodem.log .
  153. X.SH "FILE NAMES"
  154. XFiles transmitted using one of the batch modes
  155. Xwill be stored on the remote machine under a CP/M-ified name (limited
  156. Xto eight characters plus a three character extension; ":" characters will
  157. Xbe turned into "/" characters; all characters will be in monocase).  Files received using one of the batch modes
  158. Xwill be stored under their transmitted names (except that any "/" characters
  159. Xin the file name will be converted into ":" characters and all upper-case
  160. Xcharacters will be translated into lower case).
  161. X.PP
  162. XWhen a batch receive is requested,
  163. X.I xmodem
  164. Xtakes a wait and see attitude and can adapt to either batch protocol or even
  165. Xa classic XMODEM transfer (note that CRC-16 mode is automatically set under
  166. Xthese circumstances).
  167. XIf a classic, "non-batch" XMODEM file reception takes place, 
  168. Xthe received file is stored as
  169. X.IR xmodem.in .
  170. XFile names present on the command line for a batch receive are ignored.
  171. X.SH NOTES
  172. XWhile waiting for the beginning of a transfer or the beginning of a packet,
  173. X.I xmodem
  174. Xtreats two CAN (Cntrl-X) characters that are received within 3 seconds
  175. Xas a request to abort.
  176. X.PP
  177. XSqueezed CP/M files must be transferred in binary mode, even if they
  178. Xcontain text.
  179. X.PP
  180. XIf you use 
  181. X.I xmodem
  182. Xover a 
  183. X.I rlogin
  184. Xlink, you must use the flag
  185. X.IR "rlogin machine -8" .
  186. X.SH EXAMPLES
  187. XTo receive a text file transmitted from a micro (using CRC-16
  188. Xerror-checking) and store it under the
  189. Xname 
  190. X.IR file.name ,
  191. Xuse the command line
  192. X.RS
  193. X.B "xmodem rtc file.name"
  194. X.RE
  195. XNote that if the transmitting program on the micro uses the 1K packet
  196. Xprotocol or either batch protocol,
  197. X.I xmodem
  198. Xdetects this automatically and takes appropriate action.  Further
  199. Xnote that if one of the batch protocols is used, the received file(s)
  200. Xwill be stored under their own names and the name on the command line
  201. X(if any) will be ignored.
  202. X.PP
  203. XTo send a set of text files to a microcomputer using 1K packets and the
  204. XYMODEM batch protocol, use the command line
  205. X.RS
  206. X.B "xmodem stYK *.txt"
  207. X.RE
  208. X.SH FILES
  209. Xxmodem.log (if logging is enabled)
  210. X.SH BUGS
  211. XBatch mode could be smarter about bad file-names in the midst of a
  212. Xbatch transmit/receive.
  213. X.PP
  214. XBatch mode could allow a mixture of binary and text files.
  215. X.PP
  216. XThe file lengths and creation times embedded in the YMODEM batch protocol are
  217. Xneither set on transmit nor used on receive.  However, the "IMP/KMD record
  218. Xcount" field is utilized.
  219. X.SH SEE ALSO
  220. Xkermit(1)
  221. X.SH AUTHOR
  222. XSteve Grandi, National Optical Astronomy Observatories.  Based on
  223. X.I xmodem
  224. Xby Brian Kantor, University of California at San Diego.
  225. XThis, in turn, was based on
  226. X.I umodem
  227. Xby Lauren Weinstein, Richard Conn and others.
  228. !Funky!Stuff!
  229. echo x - Makefile
  230. sed -e 's/^X//' > Makefile << '!Funky!Stuff!'
  231. XOBJECTS = xmodem.o getput.o misc.o send.o receive.o batch.o
  232. XCFLAGS = -O
  233. X
  234. Xxmodem: $(OBJECTS)
  235. X    cc $(CFLAGS) $(OBJECTS) -o xmodem
  236. X
  237. X$(OBJECTS): xmodem.h
  238. X
  239. Xprint: 
  240. X    lpr -p -Pvmslp xmodem.h xmodem.c getput.c receive.c send.c batch.c misc.c Makefile
  241. !Funky!Stuff!
  242. echo x - xmodem.h
  243. sed -e 's/^X//' > xmodem.h << '!Funky!Stuff!'
  244. X#include <ctype.h>
  245. X#include <stdio.h>
  246. X#include <sys/types.h>
  247. X#include <sys/stat.h>
  248. X#include <sys/time.h>
  249. X#include <sgtty.h>
  250. X#include <signal.h>
  251. X
  252. X/* define macros to print messages in log file */
  253. X#define  logit(string) if(LOGFLAG)fprintf(LOGFP,string)
  254. X#define  logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
  255. X
  256. X#define         VERSION    32    /* Version Number */
  257. X#define      FALSE      0
  258. X#define      TRUE       1
  259. X
  260. X
  261. X/*  ASCII Constants  */
  262. X#define      SOH      001 
  263. X#define         STX    002
  264. X#define         ETX    003
  265. X#define      EOT    004
  266. X#define         ENQ    005
  267. X#define      ACK      006
  268. X#define         LF        012   /* Unix LF/NL */
  269. X#define         CR        015  
  270. X#define      NAK      025
  271. X#define         SYN    026
  272. X#define         CAN    030
  273. X#define         ESC    033
  274. X
  275. X/*  XMODEM Constants  */
  276. X#define      TIMEOUT      -1
  277. X#define      ERRORMAX      10    /* maximum errors tolerated */
  278. X#define      NAKMAX    2     /* maximum times to wait for initial NAK when sending */
  279. X#define      RETRYMAX      5     /* maximum retries to be made */
  280. X#define      CRCSWMAX    4     /* maximum time to try CRC mode before switching */
  281. X#define      KSWMAX    5     /* maximum errors before switching to 128 byte packets */
  282. X#define      SLEEPNUM    100   /* target number of characters to collect during sleepy time */
  283. X#define         BBUFSIZ    1024  /* buffer size */
  284. X#define      NAMSIZ    11    /* length of a CP/M file name string */
  285. X#define         CTRLZ    032   /* CP/M EOF for text (usually!) */
  286. X#define      CRCCHR    'C'   /* CRC request character */
  287. X#define      BAD_NAME    'u'   /* Bad filename indicator */
  288. X
  289. X#define      CREATMODE    0644  /* mode for created files */
  290. X
  291. X/* GLOBAL VARIABLES */
  292. X
  293. Xint ttyspeed;        /* tty speed (bits per second) */
  294. Xunsigned char buff[BBUFSIZ];    /* buffer for data */
  295. Xint nbchr;        /* number of chars read so far for buffered read */
  296. Xchar filename[256];    /* place to construct filenames */
  297. XFILE *LOGFP;        /* descriptor for LOG file */
  298. X
  299. X/* option flags and state variables */
  300. Xchar    XMITTYPE;    /* text or binary? */
  301. Xint    DEBUG;        /* keep debugging info in log? */
  302. Xint    RECVFLAG;    /* receive? */
  303. Xint    SENDFLAG;    /* send? */
  304. Xint    BATCH;        /* batch? (Now used as a state variable) */
  305. Xint    CRCMODE;    /* CRC or checksums? */
  306. Xint    DELFLAG;    /* don't delete old log file? */
  307. Xint    LOGFLAG;    /* keep log? */
  308. Xint    LONGPACK;     /* do not use long packets on transmit? */
  309. Xint    MDM7BAT;    /* MODEM7 batch protocol */
  310. Xint    YMDMBAT;    /* YMODEM batch protocol */
  311. X
  312. X
  313. X/*   CRC-16 constants.  From Usenet contribution by Mark G. Mendel, 
  314. X     Network Systems Corp.  (ihnp4!umn-cs!hyper!mark)
  315. X*/
  316. X
  317. X    /* the CRC polynomial. */
  318. X#define    P    0x1021
  319. X
  320. X    /* number of bits in CRC */
  321. X#define W    16
  322. X
  323. X    /* this the number of bits per char */
  324. X#define B    8
  325. !Funky!Stuff!
  326. echo x - xmodem.c
  327. sed -e 's/^X//' > xmodem.c << '!Funky!Stuff!'
  328. X/*
  329. X *  XMODEM -- Implements the Christensen XMODEM protocol, 
  330. X *            for packetized file up/downloading.    
  331. X *
  332. X *    This version runs on 4.2/4.3BSD ONLY!  It won't work ANYWHERE else.  
  333. X *
  334. X *    I have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty
  335. X *    structures, gettimeofday system call, etc.) in the source file
  336. X *    getput.c; but I make no guarantees.  Also, I have made no attempt to
  337. X *    keep variable names under 7 characters (although a cursory check
  338. X *    shows that all variables are unique within 7 first characters).
  339. X *    The program has been successfully run on VAXes (4.2/4.3BSD) and SUNs
  340. X *    (2.0/3.0) against MEX-PC.
  341. X *
  342. X *   -- Based on UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
  343. X *
  344. X *  XMODEM Version 1.0  - by Brian Kantor, UCSD (3/84)
  345. X *
  346. X *  Version 2.0 (CRC-16 and Modem7 batch file transfer) -- Steve Grandi, NOAO (5/85)
  347. X *
  348. X *  Version 2.1 (1K packets) -- Steve Grandi, NOAO (7/85)
  349. X *
  350. X *  Version 2.2 (general clean-ups and multi-character read speed-ups) -- Steve Grandi, NOAO (9/85)
  351. X *
  352. X *  Version 2.3 (napping while reading packet; split into several source files) -- Steve Grandi, NOAO (1/86)
  353. X *
  354. X *  Version 3.0 (Ymodem batch receive; associated changes) -- Steve Grandi, NOAO (2/86)
  355. X *
  356. X *  Version 3.1 (Ymodem batch send; associated changes) -- Steve Grandi, NOAO (8/86)
  357. X *
  358. X *  Version 3.2 (general cleanups) -- Steve Grandi, NOAO (9/86)
  359. X *
  360. X *  Please send bug fixes, additions and comments to:
  361. X *    {ihnp4,seismo,hao}!noao!grandi 
  362. X */
  363. X
  364. X#include "xmodem.h"
  365. X
  366. Xmain(argc, argv)
  367. Xint argc;
  368. Xchar **argv;
  369. X{
  370. X    char *getenv();
  371. X    FILE *fopen();
  372. X    char *unix_cpm();
  373. X    char *strcpy();
  374. X    char *strcat();
  375. X    
  376. X    char *fname = filename;        /* convenient place to stash file names */
  377. X    char *logfile = "xmodem.log";    /* Name of LOG File */
  378. X    
  379. X    char *stamptime();        /* for timestamp */
  380. X
  381. X    char *defname = "xmodem.in";    /* default file name if none given */
  382. X
  383. X    struct stat filestatbuf;    /* file status info */
  384. X
  385. X    int index;
  386. X    char flag;
  387. X    long expsect;
  388. X
  389. X    /* initialize option flags */
  390. X
  391. X    XMITTYPE = 't';        /* assume text transfer */
  392. X    DEBUG = FALSE;        /* keep debugging info in log */
  393. X    RECVFLAG = FALSE;    /* not receive */
  394. X    SENDFLAG = FALSE;    /* not send either */
  395. X    BATCH = FALSE;        /* nor batch */
  396. X    CRCMODE = FALSE;    /* use checksums for now */
  397. X    DELFLAG = FALSE;    /* don't delete old log file */
  398. X    LOGFLAG = TRUE;        /* keep log */
  399. X    LONGPACK = FALSE;     /* do not use long packets on transmit */
  400. X    MDM7BAT = FALSE;    /* no MODEM7 batch mode */
  401. X    YMDMBAT = FALSE;    /* no YMODEM batch mode */
  402. X
  403. X    printf("XMODEM Version %d.%d", VERSION/10, VERSION%10);
  404. X    printf(" -- UNIX-CP/M Remote File Transfer Facility\n");
  405. X
  406. X    if (argc == 1)
  407. X        {
  408. X        help();
  409. X        exit(-1);
  410. X        }
  411. X
  412. X    index = 0;        /* set index for flag loop */
  413. X
  414. X    while ((flag = argv[1][index++]) != '\0')
  415. X        switch (flag) {
  416. X        case '-' : break;
  417. X        case 'x' : DEBUG = TRUE;  /* turn on debugging log */
  418. X               break;
  419. X        case 'c' : CRCMODE = TRUE; /* enable CRC on receive */
  420. X               break;
  421. X        case 'd' : DELFLAG = TRUE;  /* delete log file */
  422. X               break;
  423. X        case 'l' : LOGFLAG = FALSE;  /* turn off log  */
  424. X               break;
  425. X        case 'B' : MDM7BAT = TRUE;  /* turn on MODEM7 batch protocol */
  426. X               BATCH   = TRUE;
  427. X               break;
  428. X        case 'Y' : YMDMBAT = TRUE;  /* turn on YMODEM batch protocol */
  429. X               BATCH   = TRUE;
  430. X               break;
  431. X        case 'K' : LONGPACK = TRUE;  /* use 1K packets on transmit */
  432. X               break;
  433. X        case 'r' : RECVFLAG = TRUE;  /* receive file */
  434. X               XMITTYPE = gettype(argv[1][index++]);  /* get t/b */
  435. X               break;
  436. X        case 's' : SENDFLAG = TRUE;  /* send file */
  437. X               XMITTYPE = gettype(argv[1][index++]);
  438. X               break;
  439. X        default  : printf ("Invalid Flag %c ignored\n", flag);
  440. X               break;
  441. X       }
  442. X
  443. X    if (DEBUG)
  444. X        LOGFLAG = TRUE;
  445. X
  446. X    if (LOGFLAG)
  447. X       { 
  448. X         if ((fname = getenv("HOME")) == 0)    /* Get HOME variable */
  449. X        error("Fatal - Can't get Environment!", FALSE);
  450. X         fname = strcat(fname, "/");
  451. X         fname = strcat(fname, logfile);
  452. X         if (!DELFLAG)
  453. X        LOGFP = fopen(fname, "a");  /* append to LOG file */
  454. X         else
  455. X        LOGFP = fopen(fname, "w");  /* new LOG file */
  456. X         if (!LOGFP)
  457. X        error("Fatal - Can't Open Log File", FALSE);
  458. X
  459. X         fprintf(LOGFP,"\n++++++++  %s", stamptime());
  460. X         fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
  461. X       }
  462. X
  463. X    getspeed();        /* get tty-speed for time estimates */
  464. X
  465. X    if (RECVFLAG && SENDFLAG)
  466. X        error("Fatal - Both Send and Receive Functions Specified", FALSE);
  467. X
  468. X    if (MDM7BAT && YMDMBAT)
  469. X        error("Fatal - Both YMODEM and MODEM7 Batch Protocols Specified", FALSE);
  470. X
  471. X    if (!RECVFLAG && !SENDFLAG)
  472. X        error("Fatal - Either Send or Receive Function must be chosen!",FALSE);
  473. X    
  474. X    if (SENDFLAG && argc==2)
  475. X        error("Fatal - No file specified to send",FALSE);
  476. X
  477. X    if (RECVFLAG && argc==2)
  478. X        {
  479. X        CRCMODE = TRUE;        /* assume we really want CRC-16 in batch */
  480. X        printf("Ready for BATCH RECEIVE");
  481. X        printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  482. X        printf("Send several Control-X characters to cancel\n");
  483. X        logit("Batch Receive Started");
  484. X        logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  485. X        strcpy(fname, defname);
  486. X        }
  487. X
  488. X    if (RECVFLAG && argc>2)
  489. X        {
  490. X        if(open(argv[2], 0) != -1)  /* check for overwriting */
  491. X            {
  492. X            logit("Warning -- Target File Exists and is Being Overwritten\n");
  493. X            printf("Warning -- Target File Exists and is Being Overwritten\n");
  494. X            }
  495. X        printf("Ready to RECEIVE File %s", argv[2]);
  496. X        printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  497. X        printf("Send several Control-X characters to cancel\n");
  498. X        logitarg("Receiving in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  499. X        strcpy(fname,argv[2]);
  500. X        }
  501. X
  502. X    if (RECVFLAG)
  503. X        {  
  504. X        setmodes();        /* set tty modes for transfer */
  505. X
  506. X        while(rfile(fname) != FALSE);  /* receive files */
  507. X
  508. X        restoremodes(FALSE);    /* restore normal tty modes */
  509. X
  510. X        sleep(2);        /* give other side time to return to terminal mode */
  511. X        exit(0);
  512. X        }
  513. X
  514. X    if (SENDFLAG && BATCH) 
  515. X        {
  516. X        if (YMDMBAT)
  517. X            {
  518. X            printf("Ready to YMODEM BATCH SEND");
  519. X            printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  520. X            logit("YMODEM Batch Send Started");
  521. X            logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  522. X            }
  523. X        else if (MDM7BAT)
  524. X            {
  525. X            printf("Ready to MODEM7 BATCH SEND");
  526. X            printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  527. X            logit("MODEM7 Batch Send Started");
  528. X            logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  529. X            }
  530. X        printf("Send several Control-X characters to cancel\n");
  531. X
  532. X        setmodes();
  533. X        for (index=2; index<argc; index++) {
  534. X            if (stat(argv[index], &filestatbuf) < 0) {
  535. X                logitarg("\nFile %s not found\n", argv[index]);
  536. X                continue;
  537. X            }
  538. X            sfile(argv[index]);
  539. X        }
  540. X        sfile("");
  541. X        restoremodes(FALSE);
  542. X
  543. X        logit("Batch Send Complete\n");
  544. X        sleep(2);
  545. X        exit (0);
  546. X        }
  547. X
  548. X    if (SENDFLAG && !BATCH) 
  549. X        {
  550. X        if (stat(argv[2], &filestatbuf) < 0)
  551. X            error("Can't find requested file", FALSE);
  552. X        expsect = (filestatbuf.st_size/128)+1;
  553. X            
  554. X        printf("File %s Ready to SEND", argv[2]);
  555. X        printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  556. X        printf("Estimated File Size %ldK, %ld Records, %ld Bytes\n",
  557. X              (filestatbuf.st_size/1024)+1, expsect,
  558. X            filestatbuf.st_size);
  559. X        projtime(expsect, stdout);
  560. X        printf("Send several Control-X characters to cancel\n");
  561. X        logitarg("Sending in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  562. X
  563. X        setmodes();
  564. X        sfile(argv[2]);
  565. X        restoremodes(FALSE);
  566. X
  567. X        sleep(2);
  568. X        exit(0);
  569. X        }
  570. X}
  571. !Funky!Stuff!
  572. echo x - getput.c
  573. sed -e 's/^X//' > getput.c << '!Funky!Stuff!'
  574. X/*
  575. X * Contains system routines to get and put bytes, change tty modes, etc
  576. X * Most of the routines are VERY 4.2BSD Specific!!!
  577. X */
  578. X
  579. X#include "xmodem.h"
  580. X
  581. X/*
  582. X *
  583. X *    Get a byte from the specified file.  Buffer the read so we don't
  584. X *    have to use a system call for each character.
  585. X *
  586. X */
  587. Xgetbyte(fildes, ch)                /* Buffered disk read */
  588. Xint fildes;
  589. Xchar *ch;
  590. X
  591. X    {
  592. X    static char buf[BUFSIZ];    /* Remember buffer */
  593. X    static char *bufp = buf;    /* Remember where we are in buffer */
  594. X    
  595. X    if (nbchr == 0)            /* Buffer exausted; read some more */
  596. X        {
  597. X        if ((nbchr = read(fildes, buf, BUFSIZ)) < 0)
  598. X            error("File Read Error", TRUE);
  599. X        bufp = buf;        /* Set pointer to start of array */
  600. X        }
  601. X    if (--nbchr >= 0)
  602. X        {
  603. X        *ch = *bufp++;
  604. X        return(0);
  605. X        }
  606. X    else
  607. X        {
  608. X        return(EOF);
  609. X        }
  610. X    }
  611. X
  612. X/*   CRC-16 constant array...
  613. X     from Usenet contribution by Mark G. Mendel, Network Systems Corp.
  614. X     (ihnp4!umn-cs!hyper!mark)
  615. X*/
  616. X
  617. X/* crctab as calculated by initcrctab() */
  618. Xunsigned short crctab[1<<B] = { 
  619. X    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  620. X    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  621. X    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  622. X    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  623. X    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  624. X    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  625. X    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  626. X    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  627. X    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  628. X    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  629. X    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  630. X    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  631. X    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  632. X    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  633. X    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  634. X    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  635. X    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  636. X    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  637. X    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
  638. X    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
  639. X    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
  640. X    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
  641. X    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
  642. X    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
  643. X    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  644. X    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
  645. X    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  646. X    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  647. X    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  648. X    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  649. X    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  650. X    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  651. X    };
  652. X
  653. X/* get a byte from data stream -- timeout if "seconds" elapses */
  654. X/* This routine is VERY 4.2 specific */
  655. X
  656. Xint
  657. Xreadbyte(seconds)
  658. Xint seconds;
  659. X    {
  660. X    int readfd;
  661. X    char c;
  662. X    struct timeval tmout;
  663. X
  664. X    tmout.tv_sec = seconds;
  665. X    tmout.tv_usec = 0;
  666. X
  667. X    readfd = 1<<0;
  668. X
  669. X    if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
  670. X        return(TIMEOUT);
  671. X
  672. X    read(0, &c, 1);
  673. X
  674. X    if (DEBUG)
  675. X        fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
  676. X
  677. X    return(c & 0xff);  /* return the char */
  678. X    }
  679. X
  680. X/* 
  681. X get a buffer (length bufsize) from data stream -- timeout if "seconds" elapses.
  682. X Read bunches of characters to save system overhead;
  683. X Further process data while kernel is reading stream (calculating "checksum").
  684. X Try to nap long enough so kernel collects 100 characters or so until we wake up
  685. X*/
  686. X
  687. X/* This routine is VERY 4.2 specific */
  688. X
  689. Xint
  690. Xreadbuf(bufsize, seconds, tmode, checksum, bufctr)
  691. X
  692. Xint bufsize,    /* number of chars to be read */
  693. Xseconds,     /* timeout period for each read */
  694. Xtmode,         /* transmission mode: TRUE if text, FALSE if binary */
  695. X*checksum,     /* pointer to checksum value */
  696. X*bufctr;    /* length of actual data string in buffer */
  697. X
  698. X{
  699. X    int readfd;        /* mask for select call */
  700. X    struct timeval tmout;    /* timeout structure for select */
  701. X    int numread;        /* number of chars read */
  702. X    int left;        /* number of chars left to read */
  703. X    int recfin = 0;        /* flag that EOF read */
  704. X    char inbuf[BBUFSIZ];    /* buffer for incoming packet */
  705. X    register unsigned char c;    /* character being processed */
  706. X    register unsigned short chksm;    /* working copy of checksum */
  707. X    register int bfctr;    /* working copy of bufctr */
  708. X    int j;            /* loop index */
  709. X
  710. X    tmout.tv_sec = seconds;
  711. X    tmout.tv_usec = 0;
  712. X    readfd = 1<<0;
  713. X    chksm = 0;
  714. X    bfctr = 0;
  715. X
  716. X    for (left = bufsize; left > 0;) {
  717. X
  718. X        /* read however many chars are waiting */
  719. X
  720. X        if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
  721. X            return(TIMEOUT);
  722. X
  723. X        numread = read(0, inbuf, left);
  724. X        left -= numread;
  725. X
  726. X        if (DEBUG)
  727. X            fprintf(LOGFP, "DEBUG: readbuf--read %d characters\n", numread);
  728. X
  729. X        /* now process part of packet we just read */
  730. X
  731. X        for (j =  0; j < numread; j++) 
  732. X            {  
  733. X                buff[bfctr] = c = inbuf[j] & 0xff;
  734. X
  735. X                if (CRCMODE)  /* CRC */
  736. X                    chksm = (chksm<<B) ^ crctab[(chksm>>(W-B)) ^ c];
  737. X
  738. X                else        /* checksum */
  739. X                           chksm = ((chksm+c) & 0xff);
  740. X
  741. X                /* binary mode */
  742. X                if (!tmode)
  743. X                    {  
  744. X                    bfctr++;
  745. X                           continue;
  746. X                           }
  747. X
  748. X                /* text mode */
  749. X                buff[bfctr] &= 0x7f; /* nuke bit 8 */
  750. X                if (c == CR)       /* skip CR's */
  751. X                continue;
  752. X                if (c == CTRLZ)  /* CP/M EOF char */
  753. X                    {  
  754. X                    recfin = TRUE;
  755. X                           continue;
  756. X                           }
  757. X                       if (!recfin)
  758. X                    bfctr++;
  759. X                 }    
  760. X
  761. X        /* go to sleep to save uneeded system calls while kernel
  762. X           is reading data from serial line; forget this when we
  763. X           running at 9600 bps; also fudge constant from 10000 to
  764. X           9000 to avoid sleeping too long
  765. X        */
  766. X        if (ttyspeed < 9600)
  767. X            napms ( (left<SLEEPNUM ? left:SLEEPNUM) * 9000/ttyspeed);
  768. X    }
  769. X
  770. X    *checksum = chksm;
  771. X    *bufctr = bfctr;
  772. X    return(0);
  773. X}
  774. X
  775. X/* send a byte to data stream */
  776. X
  777. Xsendbyte(data)
  778. Xchar data;
  779. X    {
  780. X    if (DEBUG)
  781. X        fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
  782. X
  783. X    if (write(1, &data, 1) != 1)      /* write the byte (assume it goes NOW; no flushing needed) */
  784. X        error ("Write error on stream", TRUE);
  785. X    return;
  786. X    }
  787. X
  788. X/* send a buffer to data stream */
  789. Xwritebuf(buffer, nbytes)
  790. Xchar *buffer;
  791. Xint  nbytes;
  792. X    {
  793. X    if (DEBUG)
  794. X        fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
  795. X
  796. X    if (write(1, buffer, nbytes) != nbytes)        /* write the buffer (assume no TIOCFLUSH needed) */
  797. X        error ("Write error on stream", TRUE);
  798. X    return;
  799. X    }
  800. X
  801. X/*
  802. X * "nap" for specified time -- VERY 4.2BSD specific
  803. X */
  804. X
  805. Xnapms (milliseconds)
  806. Xint    milliseconds;
  807. X{
  808. X    struct    timeval    timeout;
  809. X    int readfd;
  810. X
  811. X    if (milliseconds == 0)
  812. X        return;
  813. X    if (DEBUG)
  814. X        fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
  815. X    timeout.tv_sec = 0;
  816. X    timeout.tv_usec = milliseconds * 1000;
  817. X    readfd = 0;
  818. X
  819. X    (void) select(1, &readfd, (int *)0, (int *)0, &timeout);
  820. X}
  821. X
  822. X/* set and restore tty modes for XMODEM transfers */
  823. X/* These routines are 4.2/v7(?) specific */
  824. X
  825. Xstruct sgttyb ttys, ttysnew;    /* for stty terminal mode calls */
  826. Xstruct stat statbuf;        /* for terminal message on/off control */
  827. X
  828. Xint wason;            /* holds status of tty read write/modes */
  829. Xchar *tty;            /* current tty name */
  830. X
  831. X
  832. Xsetmodes()
  833. X    {
  834. X    char *ttyname();
  835. X
  836. X    extern onintr();
  837. X
  838. X    sleep(2);            /* let the output appear */
  839. X    if (ioctl(0,TIOCGETP,&ttys)<0)  /* get tty params [V7] */
  840. X        error("Can't get TTY Parameters", TRUE);
  841. X
  842. X    tty = ttyname(0);  /* identify current tty */
  843. X    
  844. X    /* transfer current modes to new structure */
  845. X    ttysnew.sg_ispeed = ttys.sg_ispeed;    /* copy input speed */
  846. X    ttysnew.sg_ospeed = ttys.sg_ospeed;    /* copy output speed */
  847. X    ttysnew.sg_erase  = ttys.sg_erase;    /* copy erase flags */
  848. X    ttysnew.sg_flags  = ttys.sg_flags;    /* copy flags */
  849. X     ttysnew.sg_kill   = ttys.sg_kill;    /* copy std terminal flags */
  850. X
  851. X    ttysnew.sg_flags |= RAW;    /* set for RAW Mode */
  852. X    ttysnew.sg_flags &= ~ECHO;  /* set for no echoing */
  853. X    ttysnew.sg_flags &= ~XTABS;  /* set for no tab expansion */
  854. X    ttysnew.sg_flags &= ~LCASE;  /* set for no upper-to-lower case xlate */
  855. X    ttysnew.sg_flags |= ANYP;  /* set for ANY Parity */
  856. X    ttysnew.sg_flags &= ~NL3;  /* turn off ALL 3s - new line */
  857. X    ttysnew.sg_flags &= ~TAB2; /* turn off tab 3s */
  858. X    ttysnew.sg_flags &= ~CR3;  /* turn off CR 3s */
  859. X    ttysnew.sg_flags &= ~FF1;  /* turn off FF 3s */
  860. X    ttysnew.sg_flags &= ~BS1;  /* turn off BS 3s */
  861. X    ttysnew.sg_flags &= ~TANDEM;  /* turn off flow control */
  862. X
  863. X    /* set new paramters */
  864. X    if (ioctl(0,TIOCSETP,&ttysnew) < 0)
  865. X        error("Can't set new TTY Parameters", TRUE);
  866. X
  867. X    if (stat(tty, &statbuf) < 0)  /* get tty status */ 
  868. X        error("Can't get your TTY Status", TRUE);
  869. X
  870. X    if (statbuf.st_mode & 022)    /* Need to turn messages off */
  871. X        if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
  872. X            error("Can't change  TTY mode", TRUE);
  873. X        else 
  874. X            wason = TRUE;
  875. X    else 
  876. X        wason = FALSE;
  877. X
  878. X    /* set up signal catcher to restore tty state if we are KILLed */
  879. X
  880. X    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  881. X        signal(SIGTERM, onintr);
  882. X    }
  883. X
  884. X/* restore normal tty modes */
  885. X
  886. Xrestoremodes(errcall)
  887. Xint errcall;
  888. X    {
  889. X    if (wason)
  890. X        if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
  891. X            error("Can't change TTY mode", FALSE);
  892. X    if (ioctl(0,TIOCSETP,&ttys) < 0)
  893. X        { if (!errcall)
  894. X           error("RESET - Can't restore normal TTY Params", FALSE);
  895. X        else
  896. X             printf("RESET - Can't restore normal TTY Params\n");
  897. X        }
  898. X    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  899. X        signal(SIGTERM, SIG_DFL);
  900. X    return;
  901. X    }
  902. X
  903. X
  904. X
  905. X
  906. X/* signal catcher */
  907. Xonintr()
  908. X    {
  909. X    error("Kill signal; bailing out", TRUE);
  910. X    }
  911. X
  912. X/* create string with a timestamp for log file */
  913. X
  914. Xchar *stamptime()
  915. X{
  916. X    char *asctime();        /* stuff to get timestamp */
  917. X    struct tm *localtime(), *tp;
  918. X    struct timeval tv;
  919. X    struct timezone tz;
  920. X
  921. X    gettimeofday (&tv, &tz);        /* fill in timestamp */
  922. X    tp = localtime ((time_t *)&tv.tv_sec);
  923. X    return(asctime(tp));
  924. X}
  925. X
  926. X
  927. X
  928. X/* get tty speed for time estimates */
  929. X
  930. Xgetspeed()
  931. X    {
  932. X    static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800,
  933. X            2400, 4800, 9600, 19200, 0};
  934. X    if (ioctl(0,TIOCGETP,&ttys) < 0)    /* get tty structure */
  935. X        error("Can't get TTY parameters", FALSE);
  936. X
  937. X    ttyspeed = speedtbl[ttys.sg_ispeed];
  938. X    logitarg ("Line speed = %d bits per second\n", ttyspeed);
  939. X    }
  940. X
  941. !Funky!Stuff!
  942. exit
  943.  
  944.