home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / xmodem3.4 / patch1 < prev    next >
Encoding:
Internet Message Format  |  1988-03-13  |  16.8 KB

  1. Subject:  v13i096:  Full featured xmodem program, v3.4, Patch1
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Steve Grandi <grandi@noao.arizona.edu>
  7. Posting-number: Volume 13, Issue 96
  8. Archive-name: xmodem3.4/patch1
  9.  
  10.  
  11. Here is a message I just posted to comp.sources.bugs....
  12.  
  13. The recent posting of my xmodem program (v13 i093-095) had an incomplete
  14. first shar file.  Here are the missing pieces.  Also, the second shar seems
  15. to have a hiccup (an extra CR) in the first two lines which results in a
  16. spurious, but harmless, error message.
  17.  
  18. Steve Grandi, National Optical Astronomy Observatories, Tucson AZ, 602-325-9228
  19. UUCP: {arizona,decvax,hao,ihnp4}!noao!grandi  or  uunet!noao.arizona.edu!grandi 
  20. Internet: grandi@noao.arizona.edu    SPAN/HEPNET: 5356::GRANDI or DRACO::GRANDI
  21.  
  22. ***************************************************************************
  23.  
  24. : This is a shar archive.  Extract with sh, not csh.
  25. echo x - xmodem.h
  26. sed -e 's/^X//' > xmodem.h << '!Funky!Stuff!'
  27. X#include <ctype.h>
  28. X#include <stdio.h>
  29. X#include <sys/types.h>
  30. X#include <sys/stat.h>
  31. X#include <sys/time.h>
  32. X#include <sgtty.h>
  33. X#include <signal.h>
  34. X
  35. X/* define macros to print messages in log file */
  36. X#define  logit(string) if(LOGFLAG)fprintf(LOGFP,string)
  37. X#define  logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
  38. X
  39. X#define         VERSION    34    /* Version Number */
  40. X#define      FALSE      0
  41. X#define      TRUE       1
  42. X
  43. X
  44. X/*  ASCII Constants  */
  45. X#define      SOH      001 
  46. X#define         STX    002
  47. X#define         ETX    003
  48. X#define      EOT    004
  49. X#define         ENQ    005
  50. X#define      ACK      006
  51. X#define         LF        012   /* Unix LF/NL */
  52. X#define         CR        015  
  53. X#define      NAK      025
  54. X#define         SYN    026
  55. X#define         CAN    030
  56. X#define         ESC    033
  57. X
  58. X/*  XMODEM Constants  */
  59. X#define      TIMEOUT      -1
  60. X#define      ERRORMAX      10    /* maximum errors tolerated while transferring a packet */
  61. X#define      WAITFIRST  1     /* seconds between startup characters in read */
  62. X#define      STERRORMAX    60    /* maximum "errors" tolerated in read startup */
  63. X#define      CRCSWMAX    30    /* maximum time to try CRC mode before switching */
  64. X#define      NAKMAX    120   /* maximum times to wait for initial NAK when sending */
  65. X#define      RETRYMAX      5     /* maximum retries to be made certain handshaking routines */
  66. X#define      KSWMAX    5     /* maximum errors before switching to 128 byte packets */
  67. X#define      EOTMAX    10    /* maximum times sender will send an EOT to end transfer */
  68. X#define      SLEEPNUM    100   /* target number of characters to collect during sleepy time */
  69. X#define         BBUFSIZ    1024  /* buffer size */
  70. X#define      NAMSIZ    11    /* length of a CP/M file name string */
  71. X#define         CTRLZ    032   /* CP/M EOF for text (usually!) */
  72. X#define      CRCCHR    'C'   /* CRC request character */
  73. X#define      KCHR    'K'   /* 1K block request character */
  74. X#define      BAD_NAME    'u'   /* Bad filename indicator */
  75. X
  76. X#define      CREATMODE    0644  /* mode for created files */
  77. X
  78. X/* GLOBAL VARIABLES */
  79. X
  80. Xint ttyspeed;        /* tty speed (bits per second) */
  81. Xunsigned char buff[BBUFSIZ];    /* buffer for data */
  82. Xint nbchr;        /* number of chars read so far for buffered read */
  83. Xlong filelength;    /* length specified in YMODEM header */
  84. Xlong fileread;        /* characters actually read so far in file */
  85. Xchar filename[256];    /* place to construct filenames */
  86. XFILE *LOGFP;        /* descriptor for LOG file */
  87. X
  88. X/* option flags and state variables */
  89. Xchar    XMITTYPE;    /* text or binary? */
  90. Xint    DEBUG;        /* keep debugging info in log? */
  91. Xint    RECVFLAG;    /* receive? */
  92. Xint    SENDFLAG;    /* send? */
  93. Xint    BATCH;        /* batch? (Now used as a state variable) */
  94. Xint    CRCMODE;    /* CRC or checksums? */
  95. Xint    DELFLAG;    /* don't delete old log file? */
  96. Xint    LOGFLAG;    /* keep log? */
  97. Xint    LONGPACK;     /* do not use long packets on transmit? */
  98. Xint    MDM7BAT;    /* MODEM7 batch protocol */
  99. Xint    YMDMBAT;    /* YMODEM batch protocol */
  100. Xint    TOOBUSY;    /* turn off sleeping in packet read routine */
  101. Xint    CHECKLENGTH;    /* Are we truncating a file to a YMODEM length? */
  102. X
  103. X
  104. X/*   CRC-16 constants.  From Usenet contribution by Mark G. Mendel, 
  105. X     Network Systems Corp.  (ihnp4!umn-cs!hyper!mark)
  106. X*/
  107. X
  108. X    /* the CRC polynomial. */
  109. X#define    P    0x1021
  110. X
  111. X    /* number of bits in CRC */
  112. X#define W    16
  113. X
  114. X    /* the number of bits per char */
  115. X#define B    8
  116. !Funky!Stuff!
  117. echo x - xmodem.c
  118. sed -e 's/^X//' > xmodem.c << '!Funky!Stuff!'
  119. X/*
  120. X *  XMODEM -- Implements the Christensen XMODEM protocol, 
  121. X *            for packetized file up/downloading.    
  122. X *
  123. X *    I have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty
  124. X *    structures, gettimeofday system call, etc.) in the source file
  125. X *    getput.c; but I make no guarantees.  Also, I have made no attempt to
  126. X *    keep variable names under 7 characters (although a cursory check
  127. X *    shows that all variables are unique within 7 first characters).
  128. X *    See the README file for some notes on SYS V adaptations.
  129. X *    The program has been successfully run on VAXes (4.3BSD) and SUN-3s
  130. X *    (2.x/3.x) against MEX-PC and ZCOMM/DSZ.
  131. X *
  132. X *   -- Based on UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
  133. X *
  134. X *  XMODEM Version 1.0  - by Brian Kantor, UCSD (3/84)
  135. X *
  136. X *  Version 2.0 (CRC-16 and Modem7 batch file transfer) -- Steve Grandi, NOAO (5/85)
  137. X *
  138. X *  Version 2.1 (1K packets) -- Steve Grandi, NOAO (7/85)
  139. X *
  140. X *  Version 2.2 (general clean-ups and multi-character read speed-ups) -- Steve Grandi, NOAO (9/85)
  141. X *
  142. X *  Version 2.3 (napping while reading packet; split into several source files) -- Steve Grandi, NOAO (1/86)
  143. X *
  144. X *  Version 3.0 (Ymodem batch receive; associated changes) -- Steve Grandi, NOAO (2/86)
  145. X *
  146. X *  Version 3.1 (Ymodem batch send; associated changes) -- Steve Grandi, NOAO (8/86)
  147. X *
  148. X *  Version 3.2 (general cleanups) -- Steve Grandi, NOAO (9/86)
  149. X *
  150. X *  Released to the world (1/87)
  151. X *
  152. X *  Version 3.3 (see update.doc) -- Steve Grandi, NOAO (5/87)
  153. X *
  154. X *  Version 3.4 (see update.doc) -- Steve Grandi, NOAO (10/87)
  155. X *
  156. X *  Released to the world (1/88)
  157. X *
  158. X *  Please send bug fixes, additions and comments to:
  159. X *    {ihnp4,hao}!noao!grandi   grandi@noao.arizona.edu
  160. X */
  161. X
  162. X#include "xmodem.h"
  163. X
  164. Xmain(argc, argv)
  165. Xint argc;
  166. Xchar **argv;
  167. X{
  168. X    char *getenv();
  169. X    FILE *fopen();
  170. X    char *unix_cpm();
  171. X    char *strcpy();
  172. X    char *strcat();
  173. X    
  174. X    char *fname = filename;        /* convenient place to stash file names */
  175. X    char *logfile = "xmodem.log";    /* Name of LOG File */
  176. X    
  177. X    char *stamptime();        /* for timestamp */
  178. X
  179. X    char *defname = "xmodem.in";    /* default file name if none given */
  180. X
  181. X    struct stat filestatbuf;    /* file status info */
  182. X
  183. X    int index;
  184. X    char flag;
  185. X    long expsect;
  186. X
  187. X    /* initialize option flags */
  188. X
  189. X    XMITTYPE = 't';        /* assume text transfer */
  190. X    DEBUG = FALSE;        /* keep debugging info in log */
  191. X    RECVFLAG = FALSE;    /* not receive */
  192. X    SENDFLAG = FALSE;    /* not send either */
  193. X    BATCH = FALSE;        /* nor batch */
  194. X    CRCMODE = FALSE;    /* use checksums for now */
  195. X    DELFLAG = FALSE;    /* don't delete old log file */
  196. X    LOGFLAG = TRUE;        /* keep log */
  197. X    LONGPACK = FALSE;     /* do not use long packets on transmit */
  198. X    MDM7BAT = FALSE;    /* no MODEM7 batch mode */
  199. X    YMDMBAT = FALSE;    /* no YMODEM batch mode */
  200. X    TOOBUSY = FALSE;    /* not too busy for sleeping in packet read */
  201. X
  202. X    printf("XMODEM Version %d.%d", VERSION/10, VERSION%10);
  203. X    printf(" -- UNIX-Microcomputer Remote File Transfer Facility\n");
  204. X
  205. X    if (argc == 1)
  206. X        {
  207. X        help();
  208. X        exit(-1);
  209. X        }
  210. X
  211. X    index = 0;        /* set index for flag loop */
  212. X
  213. X    while ((flag = argv[1][index++]) != '\0')
  214. X        switch (flag) {
  215. X        case '-' : break;
  216. X        case 'X' :
  217. X        case 'x' : DEBUG = TRUE;  /* turn on debugging log */
  218. X               break;
  219. X        case 'C' :
  220. X        case 'c' : CRCMODE = TRUE; /* enable CRC on receive */
  221. X               break;
  222. X        case 'D' :
  223. X        case 'd' : DELFLAG = TRUE;  /* delete log file */
  224. X               break;
  225. X        case 'L' :
  226. X        case 'l' : LOGFLAG = FALSE;  /* turn off log  */
  227. X               break;
  228. X        case 'm' :
  229. X        case 'M' : MDM7BAT = TRUE;  /* turn on MODEM7 batch protocol */
  230. X               BATCH   = TRUE;
  231. X               break;
  232. X        case 'y' :
  233. X        case 'Y' : YMDMBAT = TRUE;  /* turn on YMODEM batch protocol */
  234. X               BATCH   = TRUE;
  235. X               break;
  236. X        case 'k' :
  237. X        case 'K' : LONGPACK = TRUE;  /* use 1K packets on transmit */
  238. X               break;
  239. X        case 't' :
  240. X        case 'T' : TOOBUSY = TRUE;  /* turn off sleeping */
  241. X               break;
  242. X        case 'R' :
  243. X        case 'r' : RECVFLAG = TRUE;  /* receive file */
  244. X               XMITTYPE = gettype(argv[1][index++]);  /* get t/b */
  245. X               break;
  246. X        case 'S' :
  247. X        case 's' : SENDFLAG = TRUE;  /* send file */
  248. X               XMITTYPE = gettype(argv[1][index++]);
  249. X               break;
  250. X        default  : printf ("Invalid Flag %c ignored\n", flag);
  251. X               break;
  252. X       }
  253. X
  254. X    if (DEBUG)
  255. X        LOGFLAG = TRUE;
  256. X
  257. X    if (LOGFLAG)
  258. X       { 
  259. X         if ((fname = getenv("HOME")) == 0)    /* Get HOME variable */
  260. X        error("Fatal - Can't get Environment!", FALSE);
  261. X         fname = strcat(fname, "/");
  262. X         fname = strcat(fname, logfile);
  263. X         if (!DELFLAG)
  264. X        LOGFP = fopen(fname, "a");  /* append to LOG file */
  265. X         else
  266. X        LOGFP = fopen(fname, "w");  /* new LOG file */
  267. X         if (!LOGFP)
  268. X        error("Fatal - Can't Open Log File", FALSE);
  269. X
  270. X         fprintf(LOGFP,"\n++++++++  %s", stamptime());
  271. X         fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
  272. X         fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
  273. X         for (index=2; index<argc; ++index)
  274. X        fprintf(LOGFP, " %s", argv[index]);
  275. X         fprintf(LOGFP, "\n");
  276. X       }
  277. X
  278. X    getspeed();        /* get tty-speed for time estimates */
  279. X
  280. X    if (RECVFLAG && SENDFLAG)
  281. X        error("Fatal - Both Send and Receive Functions Specified", FALSE);
  282. X
  283. X    if (MDM7BAT && YMDMBAT)
  284. X        error("Fatal - Both YMODEM and MODEM7 Batch Protocols Specified", FALSE);
  285. X
  286. X    if (!RECVFLAG && !SENDFLAG)
  287. X        error("Fatal - Either Send or Receive Function must be chosen!",FALSE);
  288. X    
  289. X    if (SENDFLAG && argc==2)
  290. X        error("Fatal - No file specified to send",FALSE);
  291. X
  292. X    if (RECVFLAG && argc==2)
  293. X        {
  294. X        /* assume we really want CRC-16 in batch, unless we specify MODEM7 mode */ 
  295. X        CRCMODE = MDM7BAT ? FALSE : TRUE;
  296. X        printf("Ready for BATCH RECEIVE");
  297. X        printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  298. X        printf("Send several Control-X characters to cancel\n");
  299. X        logit("Batch Receive Started");
  300. X        logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  301. X        strcpy(fname, defname);
  302. X        }
  303. X
  304. X    if (RECVFLAG && argc>2)
  305. X        {
  306. X        if(open(argv[2], 0) != -1)  /* check for overwriting */
  307. X            {
  308. X            logit("Warning -- Target File Exists and is Being Overwritten\n");
  309. X            printf("Warning -- Target File Exists and is Being Overwritten\n");
  310. X            }
  311. X        printf("Ready to RECEIVE File %s", argv[2]);
  312. X        printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  313. X        printf("Send several Control-X characters to cancel\n");
  314. X        logitarg("Receiving in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  315. X        strcpy(fname,argv[2]);
  316. X        }
  317. X
  318. X    if (RECVFLAG)
  319. X        {  
  320. X        setmodes();        /* set tty modes for transfer */
  321. X
  322. X        while(rfile(fname) != FALSE);  /* receive files */
  323. X
  324. X        restoremodes(FALSE);    /* restore normal tty modes */
  325. X
  326. X        sleep(2);        /* give other side time to return to terminal mode */
  327. X        exit(0);
  328. X        }
  329. X
  330. X    if (SENDFLAG && BATCH) 
  331. X        {
  332. X        if (YMDMBAT)
  333. X            {
  334. X            printf("Ready to YMODEM BATCH SEND");
  335. X            printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  336. X            logit("YMODEM Batch Send Started");
  337. X            logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  338. X            }
  339. X        else if (MDM7BAT)
  340. X            {
  341. X            printf("Ready to MODEM7 BATCH SEND");
  342. X            printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  343. X            logit("MODEM7 Batch Send Started");
  344. X            logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  345. X            }
  346. X        printf("Send several Control-X characters to cancel\n");
  347. X
  348. X        setmodes();
  349. X        for (index=2; index<argc; index++) {
  350. X            if (stat(argv[index], &filestatbuf) < 0) {
  351. X                logitarg("\nFile %s not found\n", argv[index]);
  352. X                continue;
  353. X            }
  354. X            sfile(argv[index]);
  355. X        }
  356. X        sfile("");
  357. X        restoremodes(FALSE);
  358. X
  359. X        logit("Batch Send Complete\n");
  360. X        sleep(2);
  361. X        exit (0);
  362. X        }
  363. X
  364. X    if (SENDFLAG && !BATCH) 
  365. X        {
  366. X        if (stat(argv[2], &filestatbuf) < 0)
  367. X            error("Can't find requested file", FALSE);
  368. X        expsect = (filestatbuf.st_size/128)+1;
  369. X            
  370. X        printf("File %s Ready to SEND", argv[2]);
  371. X        printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  372. X        printf("Estimated File Size %ldK, %ld Sectors, %ld Bytes\n",
  373. X              (filestatbuf.st_size/1024)+1, expsect,
  374. X            filestatbuf.st_size);
  375. X        projtime(expsect, stdout);
  376. X        printf("Send several Control-X characters to cancel\n");
  377. X        logitarg("Sending in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
  378. X
  379. X        setmodes();
  380. X        sfile(argv[2]);
  381. X        restoremodes(FALSE);
  382. X
  383. X        sleep(2);
  384. X        exit(0);
  385. X        }
  386. X}
  387. !Funky!Stuff!
  388. echo x - batch.c
  389. sed -e 's/^X//' > batch.c << '!Funky!Stuff!'
  390. X/*
  391. X *  Various routines for batch tranfer
  392. X */
  393. X
  394. X#include "xmodem.h"
  395. X
  396. X/* make sure filename sent or received in YMODEM batch is canonical.
  397. X * Turn Unix '/' into CP/M ':' and translate to all lower case.
  398. X * Remove trailing dot in incoming name.
  399. X */
  400. X
  401. Xunixify (name)
  402. Xchar *name;
  403. X    {
  404. X    char *ptr;
  405. X    for (ptr=name; *ptr; ++ptr)
  406. X        {
  407. X        if (*ptr == '/')
  408. X            *ptr = ':';
  409. X        if (isupper (*ptr))
  410. X            *ptr |= 040;
  411. X        }
  412. X    ptr--;
  413. X    if (*ptr == '.')
  414. X        *ptr = '\0';
  415. X    }
  416. X
  417. Xcpmify (name)
  418. Xchar *name;
  419. X    {
  420. X    char *ptr;
  421. X    for (ptr=name; *ptr; ++ptr)
  422. X        {
  423. X        if (*ptr == ':')
  424. X            *ptr = '/';
  425. X        if (isupper (*ptr))
  426. X            *ptr |= 040;
  427. X        }
  428. X    }
  429. X
  430. X
  431. X/* convert a CP/M file name received in a MODEM7 batch transfer
  432. X * into a unix file name mapping '/' into ':', converting to all
  433. X * upper case and adding dot in proper place.  
  434. X * Use "filename" to hold name.
  435. X * Code stolen from D. Thompson's (IRTF) xmodem.c
  436. X */
  437. X
  438. Xchar *cpm_unix (string)
  439. Xunsigned char *string;
  440. X{
  441. X    register int i;
  442. X    unsigned char *iptr, temp;
  443. X    register char *optr;
  444. X
  445. X    if (*string == '\0')
  446. X        error("Null file name in MODEM7 batch receive", TRUE);
  447. X
  448. X    for (iptr=string; (temp = *iptr) ; ) {
  449. X        temp &= 0177;            /* strips bit 7 */
  450. X        if (isupper(temp))
  451. X            temp |= 040;        /* set bit 5 for lower case */
  452. X        if (temp == '/') 
  453. X            temp=':';        /* map / into : */
  454. X        *iptr++ = temp;
  455. X    }
  456. X
  457. X    /* put in main part of name */
  458. X    iptr=string;
  459. X    optr=filename;
  460. X    for (i=0; i<8; i++) {
  461. X        if (*iptr != ' ')
  462. X            *optr++ = *iptr++;
  463. X    }
  464. X
  465. X    /* add dot if necessary */
  466. X    if (string[8] != ' ' || string[9] != ' ' || string[10] != ' ')
  467. X        *optr++ = '.';
  468. X
  469. X    /* put in extension */
  470. X    iptr = &string[8];
  471. X    for (i=0; i<3; i++) {
  472. X        if (*iptr != ' ')
  473. X            *optr++ = *iptr++;
  474. X    }
  475. X
  476. X    *optr++ = '\000';
  477. X    return (filename);
  478. X}
  479. X
  480. X/* Send 11 character CP/M filename for MODEM7 batch transmission
  481. X * Returns -1 for a protocol error; 0 if successful
  482. X * NOTE: we tromp a little on the argument string!
  483. X * code stolen from D. Thompson's (IRTF) xmodem.c
  484. X */
  485. X
  486. Xsend_name(name)
  487. Xchar *name;
  488. X{
  489. X    register int cksum;
  490. X    register char *ptr;
  491. X
  492. X    xmdebug("send_name");
  493. X
  494. X    /* append cp/m EOF */
  495. X    name[NAMSIZ] = CTRLZ;
  496. X    name[NAMSIZ+1] = '\000';
  497. X
  498. X    /* create checksum */
  499. X    ptr = name;
  500. X    cksum = 0;
  501. X    while (*ptr)
  502. X        cksum += *ptr++;
  503. X    cksum &= 0x00FF;
  504. X
  505. X    /* send filename */
  506. X
  507. X    sendbyte(ACK);
  508. X    ptr = name;
  509. X    sendbyte(*ptr++);
  510. X
  511. X    while (*ptr) {
  512. X
  513. X            switch (readbyte(15)) {
  514. X
  515. X            case ACK: break;
  516. X
  517. X            case TIMEOUT: {
  518. X                logit("Timeout while sending MODEM7 filename\n");
  519. X                sendbyte(BAD_NAME);
  520. X                return (-1);
  521. X            }
  522. X
  523. X            default: {
  524. X                logit("Error while sending MODEM7 filename\n");
  525. X                sendbyte(BAD_NAME);
  526. X                return (-1);
  527. X            }
  528. X        }    
  529. X
  530. X        sendbyte (*ptr++);
  531. X    }
  532. X
  533. X    /* Check checksum returned by other side against my value */
  534. X    if (readbyte(16) != cksum) {
  535. X        logit("Bad checksum while sending MODEM7 filename\n");
  536. X        sendbyte(BAD_NAME);
  537. X        return (-1);
  538. X    }
  539. X
  540. X    sendbyte(ACK);
  541. X    return (0);
  542. X}
  543. X
  544. X/* Convert Unix filename to 11 character CP/M file name (8 char name,
  545. X * 3 char extension, dot in between is not included).
  546. X * map ':' into '/'; Use filename to hold name.
  547. X * code stolen from D. Thompson's (IRTF) xmodem.c
  548. X */
  549. X
  550. Xchar *unix_cpm(string)
  551. Xchar *string;
  552. X{
  553. X    register char *iptr, *optr, temp;
  554. X    int i;
  555. X
  556. X    char *rindex();
  557. X    char *strcpy();
  558. X
  559. X    /* blank 11 character name */
  560. X    (void) strcpy (filename,"           ");
  561. X
  562. X    /* strip off any path name */
  563. X    if ((iptr = rindex(string,'/')))
  564. X        iptr++;
  565. X    else
  566. X        iptr=string;
  567. X
  568. X    /* skip leading '.'s */
  569. X    while (*iptr == '.')
  570. X        iptr++;
  571. X
  572. X    /* copy main part of name */
  573. X    optr = filename;
  574. X    i = 8;
  575. X    while ((i--) && (*iptr) && (*iptr != '.'))
  576. X        *optr++ = *iptr++;
  577. X
  578. X    /* advance to unix extension, or end of unix name */
  579. X    while ((*iptr != '.') && (*iptr))
  580. X        iptr++;
  581. X
  582. X    /* skip over the  '.' */
  583. X    while (*iptr == '.')
  584. X        iptr++;
  585. X
  586. X    /* copy extension */
  587. X    optr = &filename[8];
  588. X    i=3;
  589. X    while ((i--) && (*iptr) && (*iptr != '.'))
  590. X        *optr++ = *iptr++;
  591. X
  592. X    filename[NAMSIZ] = '\000';
  593. X
  594. X    /* Fuss with name */
  595. X    for (iptr=filename; (temp = *iptr) ;) {
  596. X        temp &= 0177;            /* strip bit 7 (parity bit) */
  597. X        if (islower(temp))
  598. X            temp &= ~040;        /* make upper case */
  599. X        if (temp == ':')
  600. X            temp ='/';        /* map ':' into '/' */
  601. X        *iptr++ = temp;
  602. X    }
  603. X
  604. X    if (DEBUG)
  605. X        fprintf (LOGFP, "DEBUG: File %s sent as %s\n", string, filename);
  606. X
  607. X    return(filename);
  608. X}
  609. !Funky!Stuff!
  610. exit
  611.  
  612.