;+
; NAME:
;	ZOPEN, ZCLOSE
;
; PURPOSE:
;	open/close a file that is compressed and/or is on a remote machine
;
; CATEGORY:
;	Input/Output
;
; CALLING SEQUENCE:
;	unit =  ZOPEN(Filename)
;	ZCLOSE,Unit
;
; INPUTS:
;	Filename Name of file to open, e.g.
;		localfile.dat			regular file
;		remotehost:~/DATA/file.dat	file on remote machine
;		/scr/compressedfile.Z		compress-ed file
;		remotehost:compressedfile.gz	remote gzip-ed file
;	Unit	(ZCLOSE) The logical unit number returned by ZOPEN
;
; KEYWORD PARAMETERS:
;	WRITE	(ZOPEN) /WRITE to specify output rather than input
;
; OUTPUTS:
;	ZOPEN return a logical unit number to use for I/O.
;
; RESTRICTIONS:
;	Cant handle ON_IOERROR or ERROR.
;	Naturally you cannot seek or backspace on this file. If the file
;	specified is a normal file on the local machine, then for efficiency
;	it is opened as a normal file, so in that case you can.
;	Writing is completely untested! (Perhaps not to be recommended
;	since the rsh's spawned for the READ case persisted in hanging
;	around for ever until I used "rsh -n".)
;	Writing is completely untested! << No longer true? DLM has been
;	using it for output? But only locally?
;
; PROCEDURE:
;	Spawn an rsh and/or (un)compress or g(un)zip.
;
; EXAMPLE:
;	lun = zopen('kiawe:/scr1/mcclymon/StokesData/B930428.dat.Z')
;	READU,lun,data
;	zclose,lun
;
; MODIFICATION HISTORY:
;	ANM 1992	written
;	DLM 1994.10.12	Added capability for gzip files. On output, compress
;			is used if the extension is .Z, gzip if it ends in gz.
;			On input, gunzip is always used since it can handle
;			both types.
;	ANM 951027	Found reading compressed files didnt work!
;			Changed compress/gzip to uncompress/gunzip for reading.
;	ANM 951029	Changed to use uncompress instead of gunzip for
;			reading .Z files. Lots of machines that have compress
;			dont have gzip.
;-

PRO zclose,unit ; need to free_lun if it was spawned
CLOSE,unit & FREE_LUN,unit
END

FUNCTION zopen,file,WRITE=write
; Read (or write) a file across the network and/or compressed.
; Returns unit number to use.

type = 0
IF KEYWORD_SET(write) THEN type = type+1
; see if the file is compressed
x= STRMID(file,STRLEN(file)-2,2)
IF (x EQ '.Z') THEN BEGIN
  packer = 'compress' & IF type EQ 0 THEN packer = 'uncompress'
  type = type+2
ENDIF ELSE IF (x EQ 'gz') THEN BEGIN
  packer = 'gzip' & IF type EQ 0 THEN packer = 'gunzip'
  type = type+2
ENDIF
; see if filename has remote machine name in it
i = STRPOS(file,':')
IF i GE 0 THEN BEGIN
  j = STRMID(file,0,i) ; are machine names always lowercase alphabetic?
  ; NOTE: byte('a') returns a one-element array, so
  ;	byte(j) lt byte('a')
  ; truncates the comparision to 1 element. Need to force byte('a') to be
  ; a scalar for the comparison to be done for each element of j.
  IF MIN( ( BYTE(j) GE (BYTE('a'))(0) AND BYTE(j) LE (BYTE('z'))(0) ) $
	  OR (BYTE(j) EQ (BYTE('.')))(0) ) THEN type = type+4
ENDIF

; open the file
CASE type OF
0: OPENR,unit,file,/GET_LUN	; do normal open for efficiency
1: OPENW,unit,file,/GET_LUN
2: SPAWN,UNIT=unit,packer+' -c <'+file ; local file (allow filename expn)
3: SPAWN,UNIT=unit,packer+' -c >'+file
4: cmd = ['cat','<'] ; remote uncompressed file
5: cmd = ['cat','>']
6: cmd = [packer,'-c','<'] ; remote compressed file
7: cmd = [packer,'-c','>']
ENDCASE

rsh='rsh' & IF (type MOD 2) EQ 0 THEN rsh = [rsh,'-n'] ; *** try this ***

IF type GE 4 THEN $ ; NOSHELL to avoid expanding filename on local machine
  SPAWN,UNIT=unit,/NOSHELL,[rsh,STRMID(file,0,i),cmd,STRMID(file,i+1,999)]
RETURN,unit
END