home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-10 | 21.3 KB | 649 lines | [TEXT/MPS ] |
- This is version 3.10.
-
- --------------------------------------------------------------------------------
-
- This is version 3.9 (circa 11/90) of the xmodem program which incorporates
- a few bugfixes (one important!) and some enhancements: 1) status messages
- when running xmodem through Sun's tip program ("p" flag); 2) delayed
- startup (via the "w" flag); 3) ability to turn off EOT verification (via
- "e" flag); 4) ability to allow CAN-CAN abort in the midst of a file
- transfer (via "n" flag); 5) some help for MODEM-7 transfers (via the "cm"
- flag combination and 6) YMODEM-G support (via the "g" flag). See
- update.doc for details.
-
- --------------------------------------------------------------------------------
-
- This is version 3.8 (circa 11/88) of the xmodem program which incorporates
- minor enhancements over version 3.7 which incoporates minor enhancements
- over version 3.6. See update.doc.
-
- --------------------------------------------------------------------------------
-
- This is version 3.6 (finished 4/88) of the xmodem program which includes a
- few bugfixes and some enhancements (requested by Macintosh users)
- stimulated by the xmodem release through comp.sources.unix. See the file
- update.doc for details.
-
- --------------------------------------------------------------------------------
-
- This is version 3.4 (finished 10/87) of the xmodem program, a full-featured
- XMODEM implementation for 4.3BSD. Since the previous release (version
- 3.2, see volume 7 of the archives), substantial improvements have been
- made. See the file update.doc for details. Also, some attempt has been
- made to support SysV Unix systems; see below.
-
- As far as I am concerned, this program has reached the end of its evolution.
- Newer protocols (such as ZMODEM) will not be incorporated into xmodem. Check
- out Chuck Forsberg's rz/sz programs if you are interested in ZMODEM.
-
- --------------------------------------------------------------------------------
-
- The xmodem program implements the Christensen (XMODEM) file transfer
- protocol for moving files between 4.2/4.3BSD Unix systems and microcomputers.
- The XMODEM/CRC protocol, the MODEM7 batch protocol, the XMODEM-1K
- block protocol and the YMODEM batch protocol are all supported by xmodem.
- For details of the protocols, see the document edited by Chuck Forsberg titled
- XMODEM/YMODEM Protocol Reference (the latest version is dated 6-18-88).
-
- This program runs on 4.2/4.3BSD systems ONLY. It has been tested on VAXes
- and Suns against the MEX-PC program from Niteowl Software and the ZCOMM and
- DSZ programs from Omen Technology.
-
- I have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty structures,
- gettimeofday system call, etc.) confined to the source file getput.c; but I
- make no guarantees. Also, I have made no attempt to keep variable names
- under 7 characters. A version of getput.c that MAY work on Sys V Unix
- systems is included.
-
- --------------------------------------------------------------------------------
-
- Thanks to Emmet Gray (ihnp4!uiucuxc!fthood!egray) and John Rupley
- (arizona!rupley!root) for the following notes about converting xmodem to Sys V.
- Since I don't have a Sys V system to test a Sys V version, I won't even try.
-
- 1) Change the includes in xmodem.h from <sys/time.h> to <time.h>
- and from <sgtty.h> to <termio.h>
-
- 2) Convert the occurrences of rindex to strrchr in batch.c
-
- 3) Substitute getput.sysv.c for getput.c
-
- A further "gotcha" regarding Sys V is contained in the following message :
-
- From: Bill Stubblebine <hplsdls!was@hp-lsd.UUCP>
- Date: Sat, 25 Jun 88 13:36:20 mdt
- To: grandi@noao.arizona.edu
- Subject: xmodem3.6 bug, fix and THANKS!!
-
- 1:30 PM MDT
- June 25, 1988
-
- First, thanks for posting a really useful program, xmodem 3.6.
-
- I installed the xmodem program on an HP 9000 Series 350 workstation,
- running HP-UX version 6.01 (AT&T System V compatible) to talk to my
- CP/M system at home. MODEM7 batch is particularly useful.
-
- I'd like to report a bug I found and the fix I developed in the source
- file getput.sysv.c so that you can include it in future releases.
-
- I've reproduced the relevant portion of getput.sysv.c, modified to fix
- the bug, at the end of this file. See the routine getspeed() starting
- at line 382. Getspeed() derives the serial port speed from the
- c_cflag ioctl parameter, for use in estimating transmission times.
-
- I suspected something was wrong when xmodem kept reporting 1200 baud
- modem connections as 1800 baud in the log file, but the transfers
- still worked OK at 1200 baud. However, I also have a Courier HST 9600
- baud modem at home, and when I tried 9600 baud xmodem transfers,
- xmodem would core dump on the UNIX host.
-
- On line 386 of getput.sysv.c, in the procedure getspeed(), an array is
- declared containing numerical constants representing the various baud
- rates supported by the host terminal interface. The appropriate baud
- rate constant is selected by the statements in lines 392-394, which
- mask the c_cflag baud rate bitfield to index into the speedtbl[]
- array.
-
- There are two problems here. The first problem is that speedtbl[] is
- missing some valid baud rate entries, as the modified declaration
- shows. I got the entries for the modified declaration from the
- termio(7) manpage in my System V user's manual. The missing entries
- throw off the indexing arithmetic. Notice, for example, that the
- missing entry 900 was responsible for mapping the c_cflag bits for
- 1200 baud to the 1800 baud constant.
-
- Original declaration:
- static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- 1200, 1800, 2400, 4800, 9600, 19200, 0};
-
- Modified declaration:
- static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- 900, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 19200, 38400, 0};
- ^^^ ^^^^ ^^^^ ^^^^^ ^^^^^
-
- The second problem didn't show up until I used 9600 baud. The c_cflag
- bitfield value for 9600 baud is 16 decimal (020 octal). The masking
- constant in lines 392-394 was originally 017 octal, which masked the
- 9600 baud bitfield to 0, indexing to the speedtbl[] value of 0. Speed
- calculations using a baudrate of 0 caused floating point exceptions
- leading to the host core dumps at 9600 baud.
-
- I changed the mask value from 017 octal to 037 octal (which is
- actually the size of the c_cflag baudrate field), and changed the
- limit test in line 392 from 14 to 18, the new correct number of
- elements in the speedtbl[] array.
-
- I'm not familiar with 4.2BSD, but I noticed that getput.c, the 4.2BSD
- version of the I/O routines, contains virtually the same code for
- determining the baudrate as that in getput.sysv.c. It may be OK for
- 4.2BSD, but definitely not for System V.
-
- The modified code now works great at all baud rates! Thanks again for
- posting the program.
-
- Bill Stubblebine
- Hewlett-Packard Logic Systems Div.
- 8245 N. Union Blvd.
- Colorado Springs, Co. 80918
- ARPA: was%hp-lsd@hplabs.hp.com
- UUCP: {hplabs,hpfcla}!{hpldola,hp-lsd}!was
-
- --------------------------------------------------------------------------------
-
- A common request to me concerns running xmodem through tip in order to do
- XMODEM or YMODEM transfers. I have discovered that SunOS has a nice
- feature in tip (accessed through ~C) that connects a named program to a
- remote machine. It turns out that 4.3BSD tip has a similar (but
- undocumented) feature, but far less convenient: SunOS tip connects file
- descriptor 0 of the program to the remote line input and file descriptor 1
- to remote line output while 4.3BSD connects up file descriptors 3 and 4!
-
- If you would like to use xmodem through 4.3BSD tip, the following message
- should be of interest (note that the patches given below are against an old
- version of the source):
-
- To: grandi@noao.edu (Steve Grandi CCS)
- Subject: Re: xmodem
- Date: Tue, 02 Jan 90 12:34:58 -0500
- From: Benson I. Margulies <benson@odi.com>
-
-
- Yes, I would like to receive the changes!
-
- Steve, grandi@noao.edu
-
- OK, here are the diffs. I've tested them in receive mode,
- but I haven't been able to verify that they work for sending.
- The reason why is a long sob story.
-
- It would be good to do two additional things:
-
- 1) add some \r's to the messages printed.
- 2) when in tip mode, print more messages on stdout
- to report progress, like a . every 100 blocks.
-
- RCS file: RCS/xmodem.c,v
- retrieving revision 1.1
- retrieving revision 1.2
- diff -c -r1.1 -r1.2
- *** /tmp/,RCSt1a02154 Tue Jan 2 12:33:12 1990
- --- /tmp/,RCSt2a02154 Tue Jan 2 12:33:12 1990
- ***************
- *** 52,57 ****
- --- 52,60 ----
- MDM7BAT = FALSE; /* no MODEM7 batch mode */
- YMDMBAT = FALSE; /* no YMODEM batch mode */
- TOOBUSY = FALSE; /* not too busy for sleeping in packet read */
- + INFD = 0;
- + OUTFD = 1;
- + FDS_DISTINCT = 0;
-
- fprintf(stderr, "XMODEM Version %d.%d", VERSION/10, VERSION%10);
- fprintf(stderr, " -- UNIX-Microcomputer Remote File Transfer Facility\n");
- ***************
- *** 101,106 ****
- --- 104,115 ----
- case 's' : SENDFLAG = TRUE; /* send file */
- XMITTYPE = gettype(argv[1][index++]);
- break;
- + case 'p': /* TIP */
- + case 'P':
- + INFD = 3;
- + OUTFD = 4;
- + FDS_DISTINCT = TRUE;
- + break;
- default : fprintf(stderr, "Invalid Flag %c ignored\n", flag);
- break;
- }
- ***************
- *** 120,133 ****
- LOGFP = fopen(fname, "w"); /* new LOG file */
- if (!LOGFP)
- error("Fatal - Can't Open Log File", FALSE);
-
- fprintf(LOGFP,"\n++++++++ %s", stamptime());
- fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
- fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
- ! for (index=2; index<argc; ++index)
- ! fprintf(LOGFP, " %s", argv[index]);
- fprintf(LOGFP, "\n");
- ! }
-
- getspeed(); /* get tty-speed for time estimates */
-
- --- 129,147 ----
- LOGFP = fopen(fname, "w"); /* new LOG file */
- if (!LOGFP)
- error("Fatal - Can't Open Log File", FALSE);
- + setlinebuf(LOGFP);
-
- fprintf(LOGFP,"\n++++++++ %s", stamptime());
- +
- fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
- +
- fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
- !
- ! for (index=2; index<argc; ++index) {
- ! fprintf(LOGFP, " %s", argv[index]);
- ! }
- fprintf(LOGFP, "\n");
- ! }
-
- getspeed(); /* get tty-speed for time estimates */
-
- ===================================================================
- RCS file: RCS/xmodem.h,v
- retrieving revision 1.1
- retrieving revision 1.2
- diff -c -r1.1 -r1.2
- *** /tmp/,RCSt1a02154 Tue Jan 2 12:33:13 1990
- --- /tmp/,RCSt2a02154 Tue Jan 2 12:33:14 1990
- ***************
- *** 10,16 ****
- #define logit(string) if(LOGFLAG)fprintf(LOGFP,string)
- #define logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
-
- ! #define VERSION 36 /* Version Number */
- #define FALSE 0
- #define TRUE 1
-
- --- 10,16 ----
- #define logit(string) if(LOGFLAG)fprintf(LOGFP,string)
- #define logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
-
- ! #define VERSION 37 /* Version Number */
- #define FALSE 0
- #define TRUE 1
-
- ***************
- *** 73,78 ****
- --- 73,81 ----
- int YMDMBAT; /* YMODEM batch protocol */
- int TOOBUSY; /* turn off sleeping in packet read routine */
- int CHECKLENGTH; /* Are we truncating a file to a YMODEM length? */
- + int INFD; /* file descriptor for protocol reading */
- + int OUTFD; /* file descriptor for protocol reading */
- + int FDS_DISTINCT; /* in,out fd's not 0 and 1 */
-
-
- /* CRC-16 constants. From Usenet contribution by Mark G. Mendel,
- ===================================================================
- RCS file: RCS/getput.c,v
- retrieving revision 1.1
- retrieving revision 1.2
- diff -c -r1.1 -r1.2
- *** /tmp/,RCSt1a02154 Tue Jan 2 12:33:14 1990
- --- /tmp/,RCSt2a02154 Tue Jan 2 12:33:15 1990
- ***************
- *** 4,9 ****
- --- 4,10 ----
- */
-
- #include "xmodem.h"
- + #include <sys/types.h>
-
- /*
- *
- ***************
- *** 103,113 ****
- /* get a byte from data stream -- timeout if "seconds" elapses */
- /* This routine is VERY 4.2 specific */
-
- int
- readbyte(seconds)
- int seconds;
- {
- - int readfd;
- char c;
- struct timeval tmout;
-
- --- 104,122 ----
- /* get a byte from data stream -- timeout if "seconds" elapses */
- /* This routine is VERY 4.2 specific */
-
- + int select_input (tmout)
- + struct timeval * tmout;
- + {
- + fd_set readfd; /* mask for select call */
- + FD_ZERO(&readfd);
- + FD_SET(INFD, &readfd);
- + return select(getdtablesize(), &readfd, (int *)0, (int *)0, tmout);
- + }
- +
- int
- readbyte(seconds)
- int seconds;
- {
- char c;
- struct timeval tmout;
-
- ***************
- *** 114,125 ****
- tmout.tv_sec = seconds;
- tmout.tv_usec = 0;
-
- - readfd = 1<<0;
-
- ! if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
- ! return(TIMEOUT);
-
- ! read(0, &c, 1);
-
- if (DEBUG)
- fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
- --- 123,133 ----
- tmout.tv_sec = seconds;
- tmout.tv_usec = 0;
-
-
- ! if (select_input(&tmout) == 0)
- ! return(TIMEOUT);
-
- ! read(INFD, &c, 1);
-
- if (DEBUG)
- fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
- ***************
- *** 138,151 ****
- /* set up a usec timeout on stdin */
- tmout.tv_sec = 0;
- tmout.tv_usec = 1;
- ! readfd = 1<<0;
-
- /* any characters pending?; return if none */
- ! if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
- ! return;
-
- /* read the characters to flush them (assume there are fewer than BBUFSIZ */
- ! (void) read(0, inbuf, BBUFSIZ);
- }
- --- 146,159 ----
- /* set up a usec timeout on stdin */
- tmout.tv_sec = 0;
- tmout.tv_usec = 1;
- ! readfd = 1<<INFD;
-
- /* any characters pending?; return if none */
- ! if (select_input(&tmout) == 0)
- ! return;
-
- /* read the characters to flush them (assume there are fewer than BBUFSIZ */
- ! (void) read(INFD, inbuf, BBUFSIZ);
- }
- ***************
- *** 170,181 ****
- long recvsectcnt; /* running sector count (128 byte sectors) */
-
- {
- - int readfd; /* mask for select call */
- - struct timeval tmout; /* timeout structure for select */
- int numread; /* number of chars read */
- int left; /* number of chars left to read */
- int recfin = FALSE; /* flag that EOF read */
- char inbuf[BBUFSIZ]; /* buffer for incoming packet */
- register unsigned char c; /* character being processed */
- register unsigned short chksm; /* working copy of checksum */
- register int bfctr; /* working copy of bufctr */
- --- 178,188 ----
- long recvsectcnt; /* running sector count (128 byte sectors) */
-
- {
- int numread; /* number of chars read */
- int left; /* number of chars left to read */
- int recfin = FALSE; /* flag that EOF read */
- char inbuf[BBUFSIZ]; /* buffer for incoming packet */
- + struct timeval tmout; /* timeout structure for select */
- register unsigned char c; /* character being processed */
- register unsigned short chksm; /* working copy of checksum */
- register int bfctr; /* working copy of bufctr */
- ***************
- *** 184,190 ****
-
- tmout.tv_sec = seconds;
- tmout.tv_usec = 0;
- - readfd = 1<<0;
- chksm = 0;
- bfctr = 0;
-
- --- 191,196 ----
- ***************
- *** 192,201 ****
-
- /* read however many chars are waiting */
-
- ! if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
- ! return(TIMEOUT);
-
- ! numread = read(0, inbuf, left);
- left -= numread;
-
- if (DEBUG)
- --- 198,207 ----
-
- /* read however many chars are waiting */
-
- ! if (select_input(&tmout) == 0)
- ! return(TIMEOUT);
-
- ! numread = read(INFD, inbuf, left);
- left -= numread;
-
- if (DEBUG)
- ***************
- *** 275,281 ****
- if (DEBUG)
- fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
-
- ! if (write(1, &data, 1) != 1) /* write the byte (assume it goes NOW; no flushing needed) */
- error ("Write error on stream", TRUE);
- return;
- }
- --- 281,287 ----
- if (DEBUG)
- fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
-
- ! if (write(OUTFD, &data, 1) != 1) /* write the byte (assume it goes NOW; no flushing needed) */
- error ("Write error on stream", TRUE);
- return;
- }
- ***************
- *** 289,295 ****
- if (DEBUG)
- fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
-
- ! if (write(1, buffer, nbytes) != nbytes) /* write the buffer (assume no TIOCFLUSH needed) */
- error ("Write error on stream", TRUE);
- return;
- }
- --- 295,301 ----
- if (DEBUG)
- fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
-
- ! if (write(OUTFD, buffer, nbytes) != nbytes) /* write the buffer (assume no TIOCFLUSH needed) */
- error ("Write error on stream", TRUE);
- return;
- }
- ***************
- *** 302,308 ****
- int milliseconds;
- {
- struct timeval timeout;
- - int readfd;
-
- if (milliseconds == 0)
- return;
- --- 308,313 ----
- ***************
- *** 310,318 ****
- fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
- timeout.tv_sec = 0;
- timeout.tv_usec = milliseconds * 1000;
- - readfd = 0;
-
- ! (void) select(1, &readfd, (int *)0, (int *)0, &timeout);
- }
- --- 315,322 ----
- fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
- timeout.tv_sec = 0;
- timeout.tv_usec = milliseconds * 1000;
-
- ! (void) select(0, (int *)0, (int *)0, (int *)0, &timeout);
- }
- ***************
- *** 335,344 ****
- extern onintr();
-
- sleep(2); /* let the output appear */
- ! if (ioctl(0,TIOCGETP,&ttys)<0) /* get tty params [V7] */
- error("Can't get TTY Parameters", TRUE);
-
- ! tty = ttyname(0); /* identify current tty */
-
- ttysnew.sg_ispeed = ttys.sg_ispeed; /* copy input speed */
- ttysnew.sg_ospeed = ttys.sg_ospeed; /* copy input speed */
- --- 339,348 ----
- extern onintr();
-
- sleep(2); /* let the output appear */
- ! if (ioctl(INFD,TIOCGETP,&ttys)<0) /* get tty params [V7] */
- error("Can't get TTY Parameters", TRUE);
-
- ! tty = ttyname(INFD); /* identify current tty */
-
- ttysnew.sg_ispeed = ttys.sg_ispeed; /* copy input speed */
- ttysnew.sg_ospeed = ttys.sg_ospeed; /* copy input speed */
- ***************
- *** 347,358 ****
- ttysnew.sg_flags &= ~TANDEM; /* turn off flow control */
-
- /* set new paramters */
- ! if (ioctl(0,TIOCSETP,&ttysnew) < 0)
- error("Can't set new TTY Parameters", TRUE);
-
- /* Flush characters waiting for read or write */
- n = 0;
- ! if (ioctl(0,TIOCFLUSH,&n) < 0)
- error("Can't flush terminal queue", TRUE);
-
- /* get tty status */
- --- 351,362 ----
- ttysnew.sg_flags &= ~TANDEM; /* turn off flow control */
-
- /* set new paramters */
- ! if (ioctl(INFD,TIOCSETP,&ttysnew) < 0)
- error("Can't set new TTY Parameters", TRUE);
-
- /* Flush characters waiting for read or write */
- n = 0;
- ! if (ioctl(INFD,TIOCFLUSH,&n) < 0)
- error("Can't flush terminal queue", TRUE);
-
- /* get tty status */
- ***************
- *** 381,387 ****
- if (wason)
- if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
- error("Can't change TTY mode", FALSE);
- ! if (ioctl(0,TIOCSETP,&ttys) < 0)
- { if (!errcall)
- error("RESET - Can't restore normal TTY Params", FALSE);
- else
- --- 385,391 ----
- if (wason)
- if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
- error("Can't change TTY mode", FALSE);
- ! if (ioctl(INFD,TIOCSETP,&ttys) < 0)
- { if (!errcall)
- error("RESET - Can't restore normal TTY Params", FALSE);
- else
- ***************
- *** 423,429 ****
- {
- static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- 1200, 1800, 2400, 4800, 9600, 19200, 0};
- ! if (ioctl(0,TIOCGETP,&ttys) < 0) /* get tty structure */
- error("Can't get TTY parameters", FALSE);
-
- if (ttys.sg_ispeed >= 0 && ttys.sg_ispeed <= 14)
- --- 427,433 ----
- {
- static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- 1200, 1800, 2400, 4800, 9600, 19200, 0};
- ! if (ioctl(INFD,TIOCGETP,&ttys) < 0) /* get tty structure */
- error("Can't get TTY parameters", FALSE);
-
- if (ttys.sg_ispeed >= 0 && ttys.sg_ispeed <= 14)
-
- --------------------------------------------------------------------------------
-
- xmodem Program history:
-
- Descended from UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
-
- Based on XMODEM Version 1.0 by Brian Kantor, UCSD (3/84) (Don't blame him
- in any way for what follows....)
-
- Version 2.0 (CRC-16 and Modem7 batch file transfer) (5/85) (Thanks to D'Anne
- Thompson for the batch transfer code).
-
- Version 2.1 (1K packets) (7/85)
-
- Version 2.2 (general clean-ups and multi-character read speed-ups) (9/85)
-
- Version 2.3 (nap while reading packets; split into several source files) (1/86)
-
- Version 3.0 (Ymodem batch receive; associated changes) (2/86)
-
- Version 3.1 (Ymodem batch send; associated changes) (8/86)
-
- Version 3.2 (general cleanups) (9/86)
- (Released to the world (comp.sources) 1/87)
-
- Version 3.3 (general fixes and cleanups; see update.doc) (5/87)
-
- Version 3.4 (general fixes and cleanups; see update.doc) (10/87)
- (Released to the world 3/88)
-
- Version 3.5 (general fixes and cleanups; see update.doc) (3/88)
-
- Version 3.6 (general fixes and cleanups; text file translation for Mac;
- see update.doc) (4/88)
- (Released to the world (comp.sources.unix) 4/88)
-
- Version 3.7 (general fixes and cleanups; see update.doc) (5/88)
-
- Version 3.8 (general fixes and cleanups; see update.doc) (11/88)
-
- Version 3.9 (general fixes and cleanups; Sun tip support; YMODEM-G;
- see update.doc) (11/90)
- (Released to the world (comp.sources.unix) 11/90)
-
- Version 3.10 (general fixes and cleanups; see update.doc) (in progress)
-
- --------------------------------------------------------------------------------
-
- Please send bug fixes, additions and comments to:
- Steve Grandi, National Optical Astronomy Observatories (Tucson, Arizona, USA)
- grandi@noao.edu
-