summaryrefslogtreecommitdiffstats
path: root/funtools/util/gio.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2016-10-26 21:13:00 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2016-10-26 21:13:00 (GMT)
commitda2e3d212171bbe64c1af39114fd067308656990 (patch)
tree9601f7ed15fa1394762124630c12a792bc073ec2 /funtools/util/gio.c
parent76b109ad6d97d19ab835596dc70149ef379f3733 (diff)
downloadblt-da2e3d212171bbe64c1af39114fd067308656990.zip
blt-da2e3d212171bbe64c1af39114fd067308656990.tar.gz
blt-da2e3d212171bbe64c1af39114fd067308656990.tar.bz2
rm funtools for update
Diffstat (limited to 'funtools/util/gio.c')
-rw-r--r--funtools/util/gio.c2314
1 files changed, 0 insertions, 2314 deletions
diff --git a/funtools/util/gio.c b/funtools/util/gio.c
deleted file mode 100644
index b3dd109..0000000
--- a/funtools/util/gio.c
+++ /dev/null
@@ -1,2314 +0,0 @@
-/*
- * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory
- */
-
-/*
- *
- * GIO -- generalized I/O to disk files, streams, and memory
- *
- */
-
-#include <gio.h>
-#include <find.h>
-#include <word.h>
-#include <zlib.h>
-
-/*
- *
- * Private Routines
- *
- */
-
-#define GBUFSZ 32768
-static char _gtbuf[GBUFSZ];
-
-static char _gerrors[GBUFSZ];
-static int _gerror = -1;
-
-static char _gwarnings[GBUFSZ];
-static int _gwarning = -1;
-
-static int _gcrnl = 1;
-
-/*
- *
- * gext -- return extension from a file (without bracket extension)
- *
- */
-#ifdef ANSI_FUNC
-static char *
-gext(char *fname)
-#else
-static char *gext(fname)
- char *fname;
-#endif
-{
- char *s, *t=NULL;
- char *file;
-
- if( !fname || !*fname )
- return(NULL);
- /* make a working copy */
- file = xstrdup(fname);
- /* remove the bracket extension */
- if( (s=strchr(file, '[')) ){
- *s = '\0';
- }
- /* look for a file extension */
- if( (s = strrchr(file, '.')) ){
- strncpy(_gtbuf, s, GBUFSZ-2);
- _gtbuf[GBUFSZ-1] = '\0';
- t = _gtbuf;
- }
- /* free working copy */
- if( file ) xfree(file);
- /* return extension */
- return(t);
-}
-
-
-/*
- *
- * gnew -- create a new GIO structure
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gnew (void)
-#else
-static GIO gnew()
-#endif
-{
- GIO gio;
- gio = (GIO)xcalloc(1, sizeof(GFile));
- gio->ifd = -1;
- gio->ofd = -1;
- return(gio);
-}
-
-/*
- *
- * gfree -- destroy a GIO structure
- *
- */
-#ifdef ANSI_FUNC
-static void
-gfree (GIO gio)
-#else
-static void gfree(gio)
- GIO gio;
-#endif
-{
- if( gio == NULL )
- return;
- if( gio->name )
- xfree(gio->name);
- if( gio->mode )
- xfree(gio->mode);
- if( gio->crbuf )
- xfree(gio->crbuf);
- xfree((void *)gio);
-}
-
-
-/*
- *
- * gmemseek -- memory "seek" of data
- *
- */
-#ifdef ANSI_FUNC
-static off_t
-gmemseek (GIO gio, off_t offset, int whence)
-#else
-static off_t gmemseek(gio, offset, whence)
- GIO gio;
- off_t offset;
- int whence;
-#endif
-{
- int offset2;
-
- switch(whence){
- case 0:
- offset2 = offset;
- break;
- case 1:
- offset2 = gio->cur + offset;
- break;
- case 2:
- offset2 = gio->len + offset;
- break;
- default:
- return(-1);
- }
- if( offset2 >= gio->len ){
- if( gio->extend ){
- gio->len = offset2 + 1;
- gio->buf = (char *)xrealloc(gio->buf, gio->len);
- gio->cur = offset2;
- return(0);
- }
- else{
- return(-1);
- }
- } else {
- gio->cur = offset2;
- return(0);
- }
-}
-
-/*
- *
- * gmemread -- memory "read" of data
- *
- */
-#ifdef ANSI_FUNC
-static void *
-gmemread (GIO gio, void *buf, size_t size, size_t n, size_t *got)
-#else
-static void *gmemread(gio, buf, size, n, got)
- GIO gio;
- void *buf;
- size_t size;
- size_t n;
- size_t *got;
-#endif
-{
- char *obuf;
-
- /* sanity checks */
- if( (gio==NULL) || (gio->buf == NULL) )
- return((void *)NULL);
- if( !strchr(gio->mode, 'r') && !strstr(gio->mode, "w+") ){
- gerror(stderr,
- "illegal read operation on write-only data (%s)\n", gio->name);
- return((void *)NULL);
- }
- /* see how much we can grab to "EOF" */
- if( size <= 0 ) size = 1;
- *got = MIN(size*n, ((gio->len - gio->cur)/size)*size);
- /* copy bytes, if a buffer was supplied */
- if( buf ){
- obuf = buf;
- memmove(obuf, &(gio->buf[gio->cur]), *got);
- }
- else{
- obuf = &(gio->buf[gio->cur]);
- }
- /* bump position pointer */
- gio->cur += *got;
- /* convert got to elements */
- *got /= size;
- /* return buffer */
- return(obuf);
-}
-
-/*
- *
- * gmemwrite -- memory "write" of data
- *
- */
-#ifdef ANSI_FUNC
-static int
-gmemwrite (GIO gio, char *buf, size_t size, size_t n)
-#else
-static int gmemwrite(gio, buf, size, n)
- GIO gio;
- char *buf;
- size_t size;
- size_t n;
-#endif
-{
- size_t n2;
- int len;
-
- /* sanity checks */
- if( (gio==NULL) || (gio->buf == NULL) )
- return(0);
- if( !strchr(gio->mode, 'w') && !strstr(gio->mode, "r+") ){
- gerror(stderr,
- "illegal write operation on read-only data (%s)\n", gio->name);
- return(0);
- }
- len = size*n;
- /* make sure we have enough space */
- if( gio->cur + len >= gio->len ){
- if( gio->extend ){
- gio->len += MAX(len, GIO_BUFINC);
- if( (gio->buf = (char *)xrealloc(gio->buf, gio->len)) != NULL )
- n2 = len;
- /* could not grab space -- try just a bit to recover */
- else{
- gerror(stderr, "could not realloc space for memory write\n");
- n2 = 0;
- }
- }
- else{
- n2 = gio->len - gio->cur;
- }
- }
- else
- n2 = len;
- /* copy bytes */
- memmove(&(gio->buf[gio->cur]), buf, n2);
- /* bump pointer */
- gio->cur += n2;
- return(n/size);
-}
-
-#if HAVE_MINGW32==0
-/*
- *
- * gexec -- open a connected subprocess with bidirectional
- * IPC channels, implemented with pipes for this version
- *
- */
-#ifdef ANSI_FUNC
-static int
-gexec(GIO gio, char *cmd, char *mode)
-#else
-static int gexec(gio, cmd, mode)
- GIO gio;
- char *cmd;
- char *mode;
-#endif
-{
- int pin[2], pout[2];
- int maxforks = 3;
- char *argv[4096];
-
- /* start out pessimisticaly */
- gio->ifd = -1;
- gio->ofd = -1;
-
- /* open pipes */
- pipe(pin);
- if( pipe(pout) != 0){
- return(-1);
- }
-
- /* Create child process. The child inherits the open stdio files.
- * The fork can fail if swap space is full or if we have too many processes.
- */
- while ((gio->pid = fork()) == -1) {
- if (--maxforks == 0) {
- close(pin[0]); close(pin[1]);
- close(pout[0]); close(pout[1]);
- return(-1);
- }
- sleep (2);
- }
- if(gio->pid == 0) {
- /* New child process. Make child think the pipe is its stdin/out.
- */
- close(pin[0]);
- close(pout[1]);
- close(0); dup (pout[0]); close(pout[0]);
- close(1); dup (pin[1]); close(pin[1]);
-
- /* run through shell so that we expand shell meta characters */
- argv[0] = "sh";
- argv[1] = "-c";
- argv[2] = cmd;
- argv[3] = NULL;
-
- /* Exec the new process. Will not return if successful. */
- execvp(argv[0], (void *)argv);
-
- /* If we get here the new process could not be executed for some
- * reason. Shutdown, calling _exit to avoid flushing parent's
- * io buffers.
- */
- _exit(1);
- } else {
- /* Existing, parent process. */
- close(pin[1]);
- close(pout[0]);
- if( strchr(mode, 'r') )
- gio->ifd = pin[0];
- else{
- close(pin[0]);
- }
- if( strchr(mode, 'w') )
- gio->ofd = pout[1];
- else{
- close(pout[1]);
- }
- }
- /* clean up and return */
- return(0);
-}
-
-/*
- *
- * gopenpipe -- open a command pipe
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopenpipe (char *name, char *mode)
-#else
-static GIO gopenpipe(name, mode)
- char *name;
- char *mode;
-#endif
-{
- GIO gio;
- char *s;
-
- /* allocate the new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* skip past prefix */
- s = name;
- if( !strncasecmp(s, "pipe:", 5) ) s += 5;
- while( isspace((int)*s) ) s++;
-
- /* start the piped process */
- if( gexec(gio, s, mode) != 0 ){
- gclose(gio);
- return(NULL);
- }
-
- /* fill in the record */
- gio->name = xstrdup(s);
- gio->mode = xstrdup(mode);
- gio->type = GIO_PIPE;
- gio->extend = 0;
- return(gio);
-}
-#endif
-
-/*
- *
- * giohostip -- convert ascii host into ip number
- *
- */
-#ifdef ANSI_FUNC
-static unsigned int
-giohostip (char *xhost)
-#else
-static unsigned int giohostip(xhost)
- char *xhost;
-#endif
-{
- struct hostent *hostent;
- unsigned int ip;
- char temp[SZ_LINE];
-
- /* null input means current host */
- if( (xhost == NULL) || (*xhost == '\0') || !strncmp(xhost, "$host", 5) ){
- gethostname(temp, SZ_LINE);
- } else {
- strcpy(temp, xhost);
- }
-
- /* special check */
- if( !strcmp(temp, "$localhost") ){
- return(0x7F000001);
- }
-
- /*
- * Try looking by address (i.e., host is something like "128.84.253.1").
- * Do this first because it's much faster (no trip to the DNS)
- */
- if( (int)(ip = inet_addr(temp)) != -1 ){
- return(ntohl(ip));
- }
-
- /*
- * Try looking it up by name. If successful, the IP address is in
- * hostent->h_addr_list[0]
- */
- if( (hostent = gethostbyname(temp)) != NULL ){
- memcpy(&ip, hostent->h_addr_list[0], (size_t)hostent->h_length);
- return(ntohl(ip));
- }
-
- /* could not convert */
- return(0);
-}
-
-/*
- *
- * gioparseipport -- parse ascii string into a host and port
- *
- */
-#ifdef ANSI_FUNC
-static int
-gioparseipport (char *host, unsigned int *ip, unsigned short *port)
-#else
-static int gioparseipport(host, ip, port)
- char *host;
- unsigned int *ip;
- unsigned short *port;
-#endif
-{
- char *s1, *p1, *p2;
- int got;
-
- /* start out pessimistically */
- *ip = 0;
- *port = 0;
-
- /* make sure we have something to work with */
- if( !host || !*host )
- return(0);
-
- /* we null out ':' (so that what comes before is the host name) and
- bump past it to point to the port */
- s1 = xstrdup(host);
- if( !(p1 = (char *)strchr(s1, ':')) ){
- got = 0;
- goto done;
- }
- *p1 = '\0';
- p1++;
-
- /* get port */
- p2 = NULL;
- *port = (unsigned short)strtol(p1, &p2, 0);
- /* check for bad port number -- we lose */
- if( *port <=0 || (p1 == p2) ){
- *port = 0;
- got = 0;
- goto done;
- }
-
- /* convert ip string (might be null) to an ip address */
- if( (*ip = giohostip(s1)) == 0 ){
- *port = 0;
- got = 0;
- }
- else{
- got = 1;
- }
-
-done:
- xfree(s1);
- return(got);
-}
-
-/*
- *
- * gopensocket -- open a socket for reading and/or writing
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopensocket (char *name, char *mode)
-#else
-static GIO gopensocket(name, mode)
- char *name;
- char *mode;
-#endif
-{
- char *s;
- char tbuf[SZ_LINE];
- int fd=-1;
- int fd2=-1;
- int status;
- int tries;
- int reuse_addr=1;
- int doaccept=-1;
- unsigned int ip;
- unsigned short port;
- socklen_t slen;
- struct sockaddr_in sock_in;
- struct timeval tv;
- fd_set readfds;
- GIO gio;
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* skip past prefix */
- s = name;
- if( !strncasecmp(s, "socket:", 7) ) s += 7;
- while( isspace((int)*s) ) s++;
-
- /* if $host is the socket, we might also be specifying whether we
- connect ($host_c[onnect]) or accept ($host_a[ccept]). This allows
- either end to initiate the connection */
- if( !strncasecmp(s, "$host_a", 7) ){
- doaccept = 1;
- s = strchr(s,':');
- }
- else if( !strncasecmp(s, "$host_c", 7) ){
- doaccept = 0;
- s = strchr(s,':');
- }
- while( isspace((int)*s) ) s++;
-
- /* get host and port number */
- if( !gioparseipport(s, &ip, &port) )
- goto error;
-
- if( doaccept < 0 ){
- /* see whether we accept or connect */
- if( ip != giohostip(NULL) ){
- doaccept = 0;
- }
- else{
- if( strchr(mode, 'w') ){
- doaccept = 0;
- }
- else{
- doaccept = 1;
- }
- }
- }
-
- /* open socket for reading, i.e., reading 'stdin' from another host */
- if( doaccept ){
- /* set up listening socket, which will accept connection */
- if( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
- goto error;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (char *)&reuse_addr, sizeof(reuse_addr));
- memset((char *)&sock_in, 0, sizeof(sock_in));
- sock_in.sin_family = AF_INET;
- sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
- sock_in.sin_port = htons(port);
- /* bind to a port */
- if( bind(fd, (struct sockaddr *)&sock_in, sizeof(sock_in)) < 0 )
- goto error;
- /* listen for connections */
- if( listen(fd, 5) < 0 )
- goto error;
- /* use select() to wait for a connect, so that we can timeout */
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
- tv.tv_sec = GIO_TIMEOUT;
- tv.tv_usec = 0;
- if( select(fd+1, &readfds, NULL, NULL, &tv) <=0)
- goto error;
- /* accept connection -- the goal of our striving */
- slen = sizeof(struct sockaddr_in);
- if((fd2=accept(fd, (struct sockaddr *)&sock_in, &slen)) <0)
- goto error;
- /* done with the listening socket */
- close(fd);
- /* make sure we close on exec */
- xfcntl(fd2, F_SETFD, FD_CLOEXEC);
- setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR,
- (char *)&reuse_addr, sizeof(reuse_addr));
- /* make sure the right fd is set properly */
- if( strchr(mode, 'r') ) gio->ifd = fd2;
- if( strchr(mode, 'w') ) gio->ofd = fd2;
- }
- /* open socket for writing, i.e., writing to 'stdout' on another host */
- else{
- tries = GIO_RETRIES;
- /* if we opened a socket for reading, use the next port for writing */
- if( gio->ifd >=0 )
- port++;
-again:
- if( (fd2 = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
- gerror(stderr, "can't open socket (%s)\n", name);
- gfree(gio);
- return(NULL);
- }
- memset((char *)&sock_in, 0, sizeof(sock_in));
- sock_in.sin_family = AF_INET;
- sock_in.sin_addr.s_addr = htonl(ip);
- sock_in.sin_port = htons(port);
- /* try connecting to the specified socket */
- status=connect(fd2, (struct sockaddr *)&sock_in, sizeof(sock_in));
- /* handle error */
- if( status != 0 ){
- close(fd2);
- /* if the other process is not ready, we can wait a bit */
- if( (errno == ECONNREFUSED) && (--tries >0) ){
- gsleep(10);
- goto again;
- }
- else{
- goto error;
- }
- }
- /* make sure we close on exec */
- xfcntl(fd2, F_SETFD, FD_CLOEXEC);
- setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR,
- (char *)&reuse_addr, sizeof(reuse_addr));
- /* make sure the right fd is set properly */
- if( strchr(mode, 'r') ) gio->ifd = fd2;
- if( strchr(mode, 'w') ) gio->ofd = fd2;
- }
-
- /* fill in the record */
- gio->name = xstrdup(s);
- gio->mode = xstrdup(mode);
- gio->type = GIO_SOCKET;
- gio->extend = 0;
- /* return the good news */
- return(gio);
-
-error:
- snprintf(tbuf, SZ_LINE-1, "in %s: %s\n", name, strerror(errno));
- gerror(stderr, tbuf);
- if( fd >=0 ) close(fd);
- return(NULL);
-}
-
-/*
- *
- * gopenstdio -- open stdin or stdout
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopenstdio (char *name, char *mode)
-#else
-static GIO gopenstdio(name, mode)
- char *name;
- char *mode;
-#endif
-{
- GIO gio;
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- if( !strncasecmp(name, "stdout", 6) ||
- (!strncmp(name, "-", 1) && strchr(mode, 'w')) ){
- if( strchr(mode, 'r') ){
- gerror(stderr, "can't open STDOUT for reading\n");
- gfree(gio);
- return(NULL);
- }
- else{
- /* fill in the record */
- gio->name = xstrdup("stdout");
- gio->mode = xstrdup(mode);
- gio->type = GIO_STREAM;
- gio->extend = 0;
- gio->fp = stdout;
- }
- }
- /* look for stdin */
- else if( !strncasecmp(name, "stdin", 5) ||
- (!strncmp(name, "-", 1) && strchr(mode, 'r')) ){
- if( strchr(mode, 'w') ){
- gerror(stderr, "can't open STDIN for writing\n");
- gfree(gio);
- return(NULL);
- }
- else{
- /* fill in the record */
- gio->name = xstrdup("stdin");
- gio->mode = xstrdup(mode);
- gio->type = GIO_STREAM;
- gio->extend = 0;
- gio->fp = stdin;
- }
- }
- else{
- gerror(stderr, "invalid stdout specification (%s)\n", name);
- gfree(gio);
- return(NULL);
- }
- /* return the good news */
- return(gio);
-}
-
-#ifdef HAVE_SYS_SHM_H
-/*
- *
- * gopenshm -- open shared memory for reading or writing
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopenshm (char *name, char *mode)
-#else
-static GIO gopenshm(name, mode)
- char *name;
- char *mode;
-#endif
-{
- GIO gio;
- int shmid=-1;
- int shmkey=-1;
- int shmflg=0;
- int shmlen=0;
- int smode=0;
- char *shmaddr=NULL;
- char *shmbuf;
- char *s, *t;
- struct shmid_ds buf;
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* skip past prefix */
- s = name;
- if( !strncasecmp(s, "shm:", 4) ) s += 4;
- while( isspace((int)*s) ) s++;
-
- /* fill in the record */
- gio->name = xstrdup(s);
- gio->mode = xstrdup(mode);
- gio->type = GIO_SHM;
- gio->extend = 0;
-
- /* parse the shared memory specification */
- if( !s || !*s ){
- gerror(stderr, "missing shared memory specification\n");
- goto error;
- }
- /* @ => shmkey, otherwise shmid */
- if( *s == '@' ){
- s++;
- if( !strncasecmp(s, "IPC_PRIVATE", 11) ){
- shmkey = IPC_PRIVATE;
- s += 11;
- }
- else{
- shmkey = strtol(s, &t, 0);
- s = t;
- }
- }
- else{
- shmid = strtol(s, &t, 0);
- s = t;
- }
-
- /* get length parameter, if necessary */
- if( *s == ':' ){
- s++;
- shmlen = strtol(s, &t, 0);
- s = t;
- }
-
- /* convert key to id, if necessary */
- if( shmid == -1 ){
- if( shmkey != -1 ){
- /* create if segment des not exist */
- if( strstr(mode, "w+") ){
- smode = 0664|IPC_CREAT;
- }
- /* open for reading and/or writing */
- else{
- if( strchr(mode, 'w') )
- smode |= 0600;
- if( strchr(mode, 'r') )
- smode |= 0400;
- }
- /* get shared memory area identifier */
- shmid = shmget(shmkey, shmlen, smode);
- }
- else{
- gerror(stderr, "invalid shared memory key (%s)\n", name);
- goto error;
- }
- /* at this point, we better have one */
- if( shmid == -1 ){
- gerror(stderr, "invalid shared memory id (%s)\n", name);
- goto error;
- }
- }
-
- /* get (optional) max len we are allowed to access (def: whole segment) */
- if( shmctl(shmid, IPC_STAT, &buf) == 0 ){
- if( (shmlen <= 0) || ((size_t)shmlen > buf.shm_segsz) ){
- shmlen = buf.shm_segsz;
- }
- }
- else{
- gerror(stderr, "can't determine memory mapping length (%s)\n", name);
- goto error;
- }
-
- /* finally ... map shared memory containing data */
- shmbuf = (char *)shmat(shmid, shmaddr, shmflg);
- if( shmbuf == (char *)-1){
- gerror(stderr, "can't map shared memory image (%s)\n", name);
- goto error;
- }
-
- /* set the access parameters */
- gio->buf = shmbuf;
- gio->len = shmlen;
- gio->cur = 0;
- gio->shmid = shmid;
- /* return the good news */
- return(gio);
-
-error:
- gfree(gio);
- return(NULL);
-}
-#endif
-
-#ifdef HAVE_SYS_MMAN_H
-/*
- *
- * gopenmmap -- open memory mapped file for reading or writing
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopenmmap (char *name, char *mode)
-#else
-static GIO gopenmmap(name, mode)
- char *name;
- char *mode;
-#endif
-{
- GIO gio;
- int prot;
- int flags;
- int len;
- char *buf;
- char *s;
- struct stat statbuf;
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* skip past prefix */
- s = name;
- if( !strncasecmp(s, "mmap:", 5) ) s += 5;
- while( isspace((int)*s) ) s++;
-
- /* fill in the record */
- gio->name = xstrdup(s);
- gio->mode = xstrdup(mode);
- gio->type = GIO_MMAP;
-
- /* open the file */
- gio->fp = fopen(s, gio->mode);
- if( gio->fp == NULL ){
- gerror(stderr, "can't open data file (%s)\n", s);
- goto error;
- }
- fstat(fileno(gio->fp), &statbuf);
- len = statbuf.st_size;
- prot = 0;
- if( strchr(mode, 'r') ) prot |= PROT_READ;
- if( strchr(mode, 'w') ) prot |= PROT_WRITE;
- flags = MAP_PRIVATE;
- buf = mmap(NULL, len, prot, flags, fileno(gio->fp), 0);
- fclose(gio->fp);
- if( buf == NULL ){
- gerror(stderr, "can't mmap data file (%s)\n", s);
- goto error;
- }
- gio->buf = (void *)buf;
- gio->len = len;
- gio->cur = 0;
- if( strchr(mode, 'w') )
- gio->extend = 1;
- else
- gio->extend = 0;
- /* return the good news */
- return(gio);
-
-error:
- gfree(gio);
- return(NULL);
-}
-#endif
-
-/*
- *
- * gopengzip -- open gzip'ed for reading or writing
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopengzip (char *name, char *mode)
-#else
-static GIO gopengzip(name, mode)
- char *name;
- char *mode;
-#endif
-{
- GIO gio;
- char *s;
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* skip past prefix */
- s = name;
- if( !strncasecmp(s, "gzip:", 5) ) s += 5;
- while( isspace((int)*s) ) s++;
-
- /* fill in the record */
- gio->name = xstrdup(s);
- gio->mode = xstrdup(mode);
- gio->type = GIO_GZIP;
- gio->extend = 1;
-
- /* open stdin specially */
- if( !strncasecmp(name, "stdin", 5) ||
- (!strncmp(name, "-", 1) && strchr(mode, 'r')) ){
- gio->gz = (void *)gzdopen(dup(fileno(stdin)), gio->mode);
- }
- /* open stdout specially */
- else if( !strncasecmp(name, "stdout", 6) ||
- (!strncmp(name, "-", 1) && strchr(mode, 'w')) ){
- gio->gz = (void *)gzdopen(dup(fileno(stdout)), gio->mode);
- }
- /* open the file */
- else{
- gio->gz = (void *)gzopen(s, gio->mode);
- }
- if( gio->gz == NULL ){
- gerror(stderr, "can't open gzip'ed data file (%s)\n", s);
- goto error;
- }
- else{
- return(gio);
- }
-
-error:
- gfree(gio);
- return(NULL);
-}
-
-
-#ifdef ANSI_FUNC
-static void *
-_ggets (GIO gio, char *obuf, int len)
-#else
-static void *_ggets(gio, obuf, len)
- GIO gio;
- char *obuf;
- int len;
-#endif
-{
- int i, j, l;
- char *s=NULL;
- char *t=NULL;
-
- /* existence of crbuf => we already determined that the data uses cr
- instead of newline for end of line */
- if( gio->crbuf ){
- /* make sure we have a large enough buffer */
- if( len > gio->crlen ){
- gio->crbuf = xrealloc(gio->crbuf, len);
- gio->crlen = len;
- }
- /* grab from existing buffer, reading from file when necessary */
- for(i=0, j=0; i<(len-1);){
- /* did we reach the end of the cr buffer? */
- if( gio->crbuf[j] == '\0' ){
- /* yes, try to get more */
- if( !(s=fgets(gio->crbuf, gio->crlen, gio->fp)) ) break;
- /* reset cr buffer pointer to beginning */
- j = 0;
- /* continue processing at beginning of buffer */
- continue;
- }
- /* transfer character from cr buffer to output */
- obuf[i] = gio->crbuf[j];
- /* look for CR as end of line */
- if( obuf[i] == '\r' ){
- /* change it to a new-line */
- obuf[i++] = '\n';
- /* shift rest of start of cr buffer */
- memmove(gio->crbuf, &(gio->crbuf[j+1]), strlen(&(gio->crbuf[j+1]))+1);
- /* bump cr bbuf pointer */
- j++;
- break;
- }
- else{
- /* bump pointers to both buffers */
- i++; j++;
- }
- }
- obuf[i] = '\0';
- return((void *)obuf);
- }
- /* hopefully we have a nice, new-line delimited file */
- else{
- /* get next line, the usual way */
- s = fgets(obuf, len, gio->fp);
- /* return if we don't want t check, have no data, or already checked */
- if( !_gcrnl || !s || gio->crlen ) return s;
- /* if we did not get a new-line at the end, we either have a very long
- line, or we have a cr-delimited file */
- l = strlen(s);
- /* look for standard new-line */
- if( s[l-1] == '\n' ){
- /* found one -- flag that we have checked this file and return */
- gio->crlen=len;
- return s;
- }
- /* look for cr */
- if( !(t=strchr(s, '\r')) ){
- /* no new-line and no cr -- we'll have to check the next line as well */
- return s;
- }
- /* its cr-delimited */
- gio->crbuf = xmalloc(len);
- gio->crlen=len;
- /* copy everything after the cr to a save buffer */
- memmove(gio->crbuf, t+1, (s+l)-t);
- /* change cr to new-line */
- *t = '\n';
- /* null terminate */
- *(t+1) = '\0';
- return (void *)obuf;
- }
-}
-
-/*
- *
- * gopenfile -- open ordinary file for reading or writing
- *
- */
-#ifdef ANSI_FUNC
-static GIO
-gopenfile (char *name, char *mode)
-#else
-static GIO gopenfile(name, mode)
- char *name;
- char *mode;
-#endif
-{
- char *s;
- GIO gio;
-
-#if HAVE_MINGW32
- /* binary mode for mingw */
- _fmode = _O_BINARY;
-#endif
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* skip past prefix */
- s = name;
- if( !strncasecmp(s, "file:", 5) ) s += 5;
- if( !strncasecmp(s, "unfile:", 7) ){
- gio->unbuffered = 1;
- s += 7;
- }
- while( isspace((int)*s) ) s++;
-
- /* fill in the record */
- gio->name = xstrdup(s);
- gio->type = GIO_DISK;
- gio->extend = 1;
- gio->mode = xstrdup(mode);
-
- /* open the file */
- gio->fp = fopen(s, gio->mode);
- if( gio->fp == NULL ){
- gerror(stderr, "can't open data file (%s)\n", s);
- goto error;
- }
- else{
- return(gio);
- }
-
-error:
- gfree(gio);
- return(NULL);
-}
-
-/*
- *
- * Public Routines
- *
- */
-
-/*
- *
- * gopen -- open a file or a stream
- *
- */
-#ifdef ANSI_FUNC
-GIO
-gopen (char *fname, char *mode)
-#else
-GIO gopen(fname, mode)
- char *fname;
- char *mode;
-#endif
-{
- GIO gio;
- unsigned int ip;
- unsigned short port;
- off_t len=0;
- char name[SZ_LINE];
- char *buf=NULL;
- char *tname=NULL;
- char *s, *t;
-
- /* make sure we have a valid fname */
- if( (fname==NULL) || (*fname=='\0') )
- return(NULL);
-
- /* escape clause so that we can NOT convert cr to nl in ggets */
- if( (s=getenv("GCRNL")) ){
- if( istrue(s) )
- _gcrnl = 1;
- else if( isfalse(s) )
- _gcrnl = 0;
- }
-
- /* make a temp file name */
- tname = xstrdup(fname);
- /* remove the bracket extension for everything except pipes */
- if( strncasecmp(tname, "pipe:", 5) ){
- if( (s=strchr(tname, '[')) ) *s = '\0';
- }
-
- /* expand environment variables to get working filename */
- ExpandEnv (tname, name, SZ_LINE-1);
-
- /* look for an explicit file */
- if( !strncasecmp(name, "file:", 5) ||
- !strncasecmp(name, "unfile:", 7) || strchr(mode, 'u') )
- gio = gopenfile(name, mode);
- /* look for stdio */
- else if( (!strncasecmp(name, "stdin", 5) ||
- !strncasecmp(name, "stdout", 6)) &&
- !(gext(name) && !strcmp(gext(name),".gz")) )
- gio = gopenstdio(name, mode);
- else if( (*name == '-') && ((*(name+1) == '\0') || (*(name+1) == '[')) )
- gio = gopenstdio(name, mode);
-#if HAVE_MINGW32==0
- /* look for command pipe */
- else if( !strncasecmp(name, "pipe:", 5) || strchr(mode, 'p') )
- gio = gopenpipe(name, mode);
-#endif
-#ifdef HAVE_SYS_MMAN_H
- /* look for a mapped file */
- else if( !strncasecmp(name, "mmap:", 5) || strchr(mode, 'm') )
- gio = gopenmmap(name, mode);
-#endif
-#ifdef HAVE_SYS_SHM_H
- /* look for shared memory segment */
- else if( !strncasecmp(name, "shm:", 4) || strchr(mode, 's') )
- gio = gopenshm(name, mode);
-#endif
- /* look for data in memory (ordinary buffer) */
- else if( !strncasecmp(name, "mem:", 4) ||
- !strncasecmp(name, "buf:", 4) || strchr(mode, 'b') ){
- s = name;
- if( !strncasecmp(name, "mem:", 4) || !strncasecmp(name, "buf:", 4) )
- s += 4;
- buf = (char *)strtoul(s, &t, 0);
- if( *t != ':' ){
- gerror(stderr, "illegal memory buffer specification (%s)\n", name);
- gio = NULL;
- }
- else{
- len = (off_t)strtoul(++t, NULL, 0);
- gio = gmemopen(buf, len, mode);
- }
- }
- /* look for a socket, in the form machine:port */
- else if( gioparseipport(name, &ip, &port) )
- gio = gopensocket(name, mode);
- /* look for gzip'ed file */
- else if( !strncasecmp(name, "gzip:", 5) ||
- (gext(name) && !strcmp(gext(name),".gz")) )
- gio = gopengzip(name, mode);
- /* if all else fails, its an ordinary file */
- else
- gio = gopenfile(name, mode);
-
- /* free working space */
- if( tname ) xfree(tname);
-
- /* return results */
- return(gio);
-}
-
-/*
- *
- * gmemopen -- open memory for reading or writing
- *
- */
-#ifdef ANSI_FUNC
-GIO
-gmemopen (char *buf, off_t len, char *mode)
-#else
-GIO gmemopen(buf, len, mode)
- char *buf;
- off_t len;
- char *mode;
-#endif
-{
- GIO gio;
-
- /* allocate a new struct */
- if( (gio = gnew()) == NULL )
- return(NULL);
-
- /* fill in the record */
- gio->name = xstrdup("MEMORY");
- gio->mode = xstrdup(mode);
- gio->type = GIO_MEMORY;
-
- /* process open type */
- if( strchr(mode, 'w') ){
- if( (buf!=NULL) && (len>0) ){
- gio->buf = (void *)buf;
- gio->len = len;
- }
- else{
- gio->buf = (char *)xmalloc(GIO_BUFINC);
- gio->len = GIO_BUFINC;
- }
- gio->cur = 0;
- gio->extend = 1;
- } else {
- gio->buf = (void *)buf;
- gio->len = len;
- gio->cur = 0;
- gio->extend = 0;
- }
-
- /* return the news */
- return(gio);
-}
-
-/*
- *
- * _gread -- read bytes from a data I/O structure
- *
- */
-#ifdef ANSI_FUNC
-void *
-_gread (GIO gio, char *buf, size_t size, size_t n, size_t *got)
-#else
-void *_gread(gio, buf, size, n, got)
- GIO gio;
- char *buf;
- size_t size;
- size_t n;
- size_t *got;
-#endif
-{
- char *obuf;
- char *tptr;
- int get;
- int tgot;
-
- /* got nothing yet */
- *got = 0;
-
- /* sanity checks */
- if( gio==NULL )
- return(NULL);
- if( !strchr(gio->mode, 'r') && !strstr(gio->mode, "w+") ){
- gerror(stderr,
- "illegal read operation on write-only data (%s)\n", gio->name);
- return(NULL);
- }
-
- /* try to read */
- switch(gio->type){
- case GIO_DISK:
- if( buf )
- obuf = buf;
- else
- obuf = (char *)xmalloc(size*n);
- if( gio->unbuffered ){
- for(tptr=obuf, get=size*n; get>0; get -= tgot){
- tgot = read(fileno(gio->fp), tptr, get);
- if( tgot <0 ) {
- *got = tgot;
- break;
- }
- if( tgot == 0 ){
- break;
- }
- else{
- *got += tgot;
- tptr += tgot;
- }
- }
- if( *got >0 )
- *got /= size;
- }
- else{
- *got = fread(obuf, size, n, gio->fp);
- }
- if( *got <= 0 ){
- if( !buf )
- xfree(obuf);
- obuf = NULL;
- }
- return(obuf);
- case GIO_STREAM:
- if( buf )
- obuf = buf;
- else
- obuf = (char *)xmalloc(size*n);
- *got = fread(obuf, size, n, gio->fp);
- if( *got <= 0 ){
- if( !buf )
- xfree(obuf);
- obuf = NULL;
- }
- return(obuf);
- case GIO_MEMORY:
- return(gmemread(gio, buf, size, n, got));
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- return(gmemread(gio, buf, size, n, got));
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- return(gmemread(gio, buf, size, n, got));
-#endif
- case GIO_PIPE:
- if( buf )
- obuf = buf;
- else
- obuf = (char *)xmalloc(size*n);
- if( gio->ifd >=0 ){
- for(tptr=obuf, get=size*n; get>0; get -= tgot){
- tgot = read(gio->ifd, tptr, get);
- if( tgot <0 ) {
- *got = tgot;
- break;
- }
- else if( tgot ==0 ) {
- break;
- }
- else{
- *got += tgot;
- tptr += tgot;
- }
- }
- if( *got > 0 )
- *got /= size;
- }
- if( *got <= 0 ){
- if( !buf )
- xfree(obuf);
- obuf = NULL;
- }
- else{
- gio->cur += *got;
- }
- return(obuf);
- case GIO_SOCKET:
- if( buf )
- obuf = buf;
- else
- obuf = (char *)xmalloc(size*n);
- if( gio->ifd >=0 ){
- for(tptr=obuf, get=size*n; get>0; get -= tgot){
- tgot = recv(gio->ifd, tptr, get, 0);
- if( tgot <0 ) {
- *got = tgot;
- break;
- }
- else if( tgot == 0 ) {
- break;
- }
- else{
- *got += tgot;
- tptr += tgot;
- }
- }
- if( *got > 0 )
- *got /= size;
- }
- if( *got <= 0 ){
- if( !buf )
- xfree(obuf);
- obuf = NULL;
- }
- else{
- gio->cur += *got;
- }
- return(obuf);
- case GIO_GZIP:
- if( buf )
- obuf = buf;
- else
- obuf = (char *)xmalloc(size*n);
- *got = gzread(gio->gz, obuf, size * n);
- if( *got <= 0 ){
- if( !buf )
- xfree(obuf);
- obuf = NULL;
- }
- if( *got >0 )
- *got /= size;
- return(obuf);
- default:
- return(NULL);
- }
-}
-
-/*
- *
- * gread -- read bytes from a data I/O structure
- *
- */
-#ifdef ANSI_FUNC
-size_t
-gread (GIO gio, char *buf, size_t size, size_t n)
-#else
-size_t gread(gio, buf, size, n)
- GIO gio;
- char *buf;
- size_t size;
- size_t n;
-#endif
-{
- size_t got;
- if( buf == NULL )
- return(0);
- _gread(gio, buf, size, n, &got);
- return (got);
-}
-
-/*
- *
- * gwrite -- write bytes to a structure
- *
- */
-#ifdef ANSI_FUNC
-size_t
-gwrite (GIO gio, char *buf, size_t size, size_t n)
-#else
-size_t gwrite(gio, buf, size, n)
- GIO gio;
- char *buf;
- size_t size;
- size_t n;
-#endif
-{
- int got=0;
-
- /* sanity checks */
- if( gio==NULL )
- return(0);
- if( !strchr(gio->mode, 'w') && !strchr(gio->mode, 'a') &&
- !strstr(gio->mode, "r+") ){
- gerror(stderr,
- "illegal write operation on read-only data (%s)\n", gio->name);
- return(0);
- }
-
- switch(gio->type){
- case GIO_DISK:
- if( gio->unbuffered ){
- got = write(fileno(gio->fp), buf, size*n);
- if( got > 0 ) got /= size;
- }
- else{
- got = fwrite(buf, size, n, gio->fp);
- }
- break;
- case GIO_STREAM:
- got = fwrite(buf, size, n, gio->fp);
- break;
- case GIO_MEMORY:
- got = gmemwrite(gio, buf, size, n);
- break;
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- got = gmemwrite(gio, buf, size, n);
- break;
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- got = gmemwrite(gio, buf, size, n);
- break;
-#endif
- case GIO_PIPE:
- if( gio->ofd >= 0 ){
- got = write(gio->ofd, buf, size * n);
- if( got > 0 ){
- gio->cur += got;
- got /= size;
- }
- }
- break;
- case GIO_SOCKET:
- if( gio->ofd >= 0 ){
- got = send(gio->ofd, buf, size * n, 0);
- if( got > 0 ){
- gio->cur += got;
- got /= size;
- }
- }
- break;
- case GIO_GZIP:
- got = gzwrite(gio->gz, buf, size*n);
- if( got >=0 ) got /= size;
- break;
- default:
- break;
- }
- return(got);
-}
-
-#ifdef ANSI_FUNC
-void *
-ggets (GIO gio, char *buf, int len)
-#else
-void *ggets(gio, buf, len)
- GIO gio;
- char *buf;
- int len;
-#endif
-{
- int i=0;
- int got;
- char *obuf=NULL;
-
- /* sanity checks */
- if( !gio )
- return NULL;
- if( !strchr(gio->mode, 'r') && !strstr(gio->mode, "w+") ){
- gerror(stderr,
- "illegal read operation on write-only data (%s)\n", gio->name);
- return NULL;
- }
-
- /* allocate buffer, if necessary */
- if( buf )
- obuf = buf;
- else
- obuf = (char *)xmalloc(len);
-
- /* start out clean */
- *obuf = '\0';
-
- switch(gio->type){
- case GIO_STREAM:
- _ggets(gio, obuf, len);
- if( !obuf || !*obuf ){
- if( !buf ) xfree(obuf);
- obuf = NULL;
- }
- return obuf;
- case GIO_DISK:
- if( !gio->unbuffered ){
- _ggets(gio, obuf, len);
- if( !obuf || !*obuf ){
- if( !buf ) xfree(obuf);
- obuf = NULL;
- }
- return obuf;
- }
- default:
- /* grab characters up to a new-line or max len */
- while( i < (len-1) ){
- got = gread(gio, &(obuf[i]), sizeof(char), 1);
- if( got < 0 ){
- i = 0;
- break;
- }
- else if( got == 0 )
- break;
- else if( obuf[i] == '\n' ){
- i++;
- break;
- }
- else if( (obuf[i] == '\r') && _gcrnl ){
- obuf[i] = '\n';
- i++;
- break;
- }
- else{
- i++;
- }
- }
- obuf[i] = '\0';
- if( i == 0 ){
- if( !buf ) xfree(obuf);
- obuf = NULL;
- }
- return((void *)obuf);
- }
-}
-
-#ifdef __STDC__
-int
-gprintf(GIO gio, char *format, ...)
-{
- int got;
- va_list args;
- va_start(args, format);
-#else
-int gprintf(va_alist) va_dcl
-{
- GIO gio
- char *format;
- int got;
- va_list args;
-
- va_start(args);
- gio = va_arg(args, GIO);
- format = va_arg(args, char *);
-#endif
- got = vsnprintf(_gtbuf, GBUFSZ, format, args);
- if( got > GBUFSZ ){
- gerror(stderr, "gprintf string too long (%d > %d)\n", got, GBUFSZ);
- return -1;
- }
- else{
- return gwrite(gio, _gtbuf, sizeof(char), strlen(_gtbuf));
- }
-}
-
-/*
- *
- * gflush -- flush I/O
- *
- */
-#ifdef ANSI_FUNC
-int
-gflush (GIO gio)
-#else
-int gflush(gio)
- GIO gio;
-#endif
-{
- /* sanity checks */
- if( gio==NULL )
- return(-1);
-
- switch(gio->type){
- case GIO_DISK:
- if( gio->unbuffered )
- return(0);
- else
- return(fflush(gio->fp));
- case GIO_STREAM:
- return(fflush(gio->fp));
- case GIO_MEMORY:
- return(0);
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- return(0);
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- return(0);
-#endif
- case GIO_PIPE:
- return(0);
- case GIO_SOCKET:
- return(0);
- case GIO_GZIP:
- return(0);
- default:
- return(-1);
- }
-}
-
-/*
- *
- * gseek -- set current pointer position in a "file"
- *
- */
-#ifdef ANSI_FUNC
-off_t
-gseek (GIO gio, off_t offset, int whence)
-#else
-off_t gseek(gio, offset, whence)
- GIO gio;
- off_t offset;
- int whence;
-#endif
-{
- off_t opos;
- /* sanity checks */
- if( gio==NULL )
- return(-1);
-
- switch(gio->type){
- case GIO_DISK:
- if( gio->unbuffered )
- return(lseek(fileno(gio->fp), offset, whence));
- else{
-#if USE_FSEEKO
- opos = ftello(gio->fp);
- if( fseeko(gio->fp, offset, whence) == 0 ){
- return(opos);
- }
- else{
- return(-1);
- }
-#else
- opos = ftell(gio->fp);
- if( fseek(gio->fp, (long)offset, whence) == 0 ){
- return(opos);
- }
- else{
- return(-1);
- }
-#endif
- }
- case GIO_STREAM:
- if( whence == SEEK_CUR )
- return( gskip(gio, offset) );
- else{
-#if USE_FSEEKO
- opos = ftello(gio->fp);
- if( fseeko(gio->fp, offset, whence) == 0 ){
- return(opos);
- }
- else{
- return(-1);
- }
-#else
- opos = ftell(gio->fp);
- if( fseek(gio->fp, (long)offset, whence) == 0 ){
- return(opos);
- }
- else{
- return(-1);
- }
-#endif
- }
- case GIO_MEMORY:
- return(gmemseek(gio, offset, whence));
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- return(gmemseek(gio, offset, whence));
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- return(gmemseek(gio, offset, whence));
-#endif
- case GIO_PIPE:
- if( whence == SEEK_CUR )
- return( gskip(gio, offset) );
- else
- return(-1);
- case GIO_SOCKET:
- if( whence == SEEK_CUR )
- return( gskip(gio, offset) );
- else
- return(-1);
- case GIO_GZIP:
- return(gzseek(gio->gz, offset, whence));
- default:
- return(-1);
- }
-}
-
-/*
- *
- * gtell -- return current pointer position in a "file"
- *
- */
-#ifdef ANSI_FUNC
-off_t
-gtell (GIO gio)
-#else
-off_t gtell(gio)
- GIO gio;
-#endif
-{
-#if USE_FTELLO
- off_t lval;
-#else
- long lval;
-#endif
- /* sanity checks */
- if( gio==NULL )
- return((off_t)-1);
-
- switch(gio->type){
- case GIO_DISK:
- if( gio->unbuffered )
- return(lseek(fileno(gio->fp), 0, SEEK_CUR));
- else
-#if USE_FTELLO
- return(ftello(gio->fp));
-#else
- return(ftell(gio->fp));
-#endif
- case GIO_STREAM:
-#if USE_FTELLO
- lval = ftello(gio->fp);
-#else
- lval = ftell(gio->fp);
-#endif
- if( lval >=0 )
- return lval;
- else
- return gio->cur;
- case GIO_MEMORY:
- return(gio->cur);
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- return(gio->cur);
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- return(gio->cur);
-#endif
- case GIO_PIPE:
- return(gio->cur);
- case GIO_SOCKET:
- return(gio->cur);
- case GIO_GZIP:
- return(gztell(gio->gz));
- default:
- return((off_t)-1);
- }
-}
-
-/*
- *
- * gskip - skip reading bytes to a file position
- *
- */
-#ifdef ANSI_FUNC
-int
-gskip (GIO gio, off_t n)
-#else
-int gskip(gio, n)
- GIO gio;
- off_t n;
-#endif
-{
- char buf[1];
-
- /* sanity checks */
- if( !gio )
- return(-1);
-
- /* nothing to do */
- if( !n )
- return 0;
-
- switch(gio->type){
- case GIO_DISK:
- if( gio->unbuffered )
- return(lseek(fileno(gio->fp), n, SEEK_CUR));
- else
-#if USE_FSEEKO
- return(fseeko(gio->fp, n, SEEK_CUR));
-#else
- return(fseek(gio->fp, (long)n, SEEK_CUR));
-#endif
- case GIO_STREAM:
- /* for stdin, read the bytes */
- if( gio->fp == stdin ){
- if( n < 0 )
- return(-1);
- while( n-- ){
- if( fread(buf, sizeof(char), 1, gio->fp) != 1 )
- return(0);
- }
- return(0);
- }
- /* who knows what will happen here */
- else{
-#if USE_FSEEKO
- return(fseeko(gio->fp, n, SEEK_CUR));
-#else
- return(fseek(gio->fp, (long)n, SEEK_CUR));
-#endif
- }
- case GIO_MEMORY:
- if( (gio->cur + n >= gio->len) || (gio->cur + n <0) ){
- return(-1);
- }
- else{
- gio->cur += n;
- return(0);
- }
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- if( (gio->cur + n >= gio->len) || (gio->cur + n <0) ){
- return(-1);
- }
- else{
- gio->cur += n;
- return(0);
- }
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- if( (gio->cur + n >= gio->len) || (gio->cur + n <0) ){
- return(-1);
- }
- else{
- gio->cur += n;
- return(0);
- }
-#endif
- case GIO_PIPE:
- if( n < 0 )
- return(-1);
- if( gio->ifd >= 0 ){
- while( n-- ){
- if( read(gio->ifd, buf, 1) != 1 )
- return(0);
- gio->cur++;
- }
- return(0);
- }
- else{
- return(-1);
- }
- case GIO_SOCKET:
- if( n < 0 )
- return(-1);
- if( gio->ifd >= 0 ){
- while( n-- ){
- if( recv(gio->ifd, buf, 1, 0) != 1 )
- return(0);
- gio->cur++;
- }
- return(0);
- }
- else{
- return(-1);
- }
- case GIO_GZIP:
- return(gzseek(gio->gz, (z_off_t)n, SEEK_CUR));
- default:
- return(-1);
- }
-}
-
-/*
- *
- * ginfo -- return information about a "file"
- *
- */
-#ifdef ANSI_FUNC
-int
-ginfo (GIO gio, char **name, int *type, off_t *cur, char **buf, int *len)
-#else
-int ginfo(gio, name, type, cur, buf, len)
- GIO gio;
- char **name;
- int *type;
- off_t *cur;
- char **buf;
- int *len;
-#endif
-{
- if( gio==NULL )
- return(-1);
- if( name )
- *name = gio->name;
- if( type )
- *type = gio->type;
- if( cur )
- *cur = gtell(gio);
- if( buf )
- *buf = gio->buf;
- if( len )
- *len = gio->len;
- return(0);
-}
-
-/*
- *
- * gfreebuf -- free allocated data buffers
- *
- */
-#ifdef ANSI_FUNC
-void
-gfreebuf (GIO gio, void *buf)
-#else
-void gfreebuf(gio, buf)
- GIO gio;
- void *buf;
-#endif
-{
- if( gio==NULL )
- return;
-
- switch(gio->type){
- case GIO_DISK:
- if( buf )
- xfree(buf);
- break;
- case GIO_STREAM:
- if( buf )
- xfree(buf);
- break;
- case GIO_MEMORY:
- break;
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- break;
-#endif
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- break;
-#endif
- case GIO_PIPE:
- if( buf )
- xfree(buf);
- break;
- case GIO_SOCKET:
- if( buf )
- xfree(buf);
- break;
- case GIO_GZIP:
- if( buf )
- xfree(buf);
- break;
- default:
- break;
- }
-}
-
-/*
- *
- * gclose -- close an I/O structure
- *
- */
-#ifdef ANSI_FUNC
-void
-gclose (GIO gio)
-#else
-void gclose(gio)
- GIO gio;
-#endif
-{
- int status;
-
- /* sanity checks */
- if( gio==NULL )
- return;
-
- switch(gio->type){
- case GIO_DISK:
- if( gio->unbuffered ){
- fclose(gio->fp);
- }
- else{
- fflush(gio->fp);
- fclose(gio->fp);
- }
- break;
- case GIO_STREAM:
- fflush(gio->fp);
- /* close stream, but don't close a stdio stream */
- if( (gio->fp != stdin) && (gio->fp != stdout) && (gio->fp != stderr) )
- fclose(gio->fp);
- break;
-#ifdef HAVE_SYS_MMAN_H
- case GIO_MMAP:
- munmap(gio->buf, gio->len);
- break;
-#endif
- case GIO_MEMORY:
- break;
-#ifdef HAVE_SYS_SHM_H
- case GIO_SHM:
- /* unmap shared memory segment */
- shmdt(gio->buf);
- /* in write+ mode, we try to destroy the shared memory as well */
- if( strstr(gio->mode, "w+") ) shmctl(gio->shmid, IPC_RMID, NULL);
- break;
-#endif
- case GIO_PIPE:
- if( gio->ifd >=0 )
- close(gio->ifd);
- if( gio->ofd >=0 )
- close(gio->ofd);
-#if HAVE_MINGW32==0
- if( gio->pid )
- waitpid(gio->pid, &status, 0);
-#endif
- break;
- case GIO_SOCKET:
- if( gio->ifd >=0 )
- close(gio->ifd);
- else if( gio->ofd >=0 )
- close(gio->ofd);
- break;
- case GIO_GZIP:
- gzclose(gio->gz);
- break;
- default:
- break;
- }
- gfree(gio);
-}
-
-/*
- *
- * gerrorstring -- return last exception string
- *
- */
-#ifdef ANSI_FUNC
-char *
-gerrorstring(void)
-#else
-char *gerrorstring()
-#endif
-{
- return(_gerrors);
-}
-
-/*
- *
- * setgerror -- set the error flag
- *
- */
-#ifdef ANSI_FUNC
-int
-setgerror(int flag)
-#else
-int setgerror(flag)
- int flag;
-#endif
-{
- int oflag;
- oflag = _gerror;
- _gerror = flag;
- return oflag;
-}
-
-/*
- *
- * gerror - error message handler
- * actions based on value of error flag:
- *
- * flag action
- * ---- ------
- * 0 store error message in _gerrors string
- * 1 store, print error message and continue
- * 2 print error message and exit
- *
- */
-#ifdef __STDC__
-void gerror(FILE *fd, char *format, ...)
-{
- char tbuf[SZ_LINE];
- va_list args;
- va_start(args, format);
-#else
-void gerror(va_alist) va_dcl
-{
- FILE *fd;
- char *format;
- char tbuf[SZ_LINE];
- va_list args;
-
- va_start(args);
- fd = va_arg(args, FILE *);
- format = va_arg(args, char *);
-#endif
- /* initialize level, if not already done */
- if( _gerror == -1 ){
- char *s;
- if( (s=getenv("GERROR")) )
- _gerror = atoi(s);
- else
- _gerror = 2;
- }
- snprintf(tbuf, SZ_LINE-1, "ERROR: %s", format);
- vsnprintf(_gerrors, SZ_LINE-1, tbuf, args);
- /* if the error flag is positive, we output immediately */
- if( (fd != NULL) && _gerror ){
- fputs(_gerrors, fd);
- fflush(fd);
- }
- /* if the error flag is set high, we exit */
- if( _gerror >= 2 )
- exit(_gerror);
-}
-
-/*
- *
- * gwarningstring -- return last exception string
- *
- */
-#ifdef ANSI_FUNC
-char *
-gwarningstring(void)
-#else
-char *gwarningstring()
-#endif
-{
- return(_gwarnings);
-}
-
-/*
- *
- * setgwarning -- set the warning flag
- *
- */
-#ifdef ANSI_FUNC
-int
-setgwarning(int flag)
-#else
-int setgwarning(flag)
- int flag;
-#endif
-{
- int oflag;
- oflag = _gwarning;
- _gwarning = flag;
- return oflag;
-}
-
-#ifdef __STDC__
-void gwarning(FILE *fd, char *format, ...)
-{
- char tbuf[SZ_LINE];
- va_list args;
- va_start(args, format);
-#else
-void gwarning(va_alist) va_dcl
-{
- FILE *fd;
- char *format;
- char tbuf[SZ_LINE];
- va_list args;
-
- va_start(args);
- fd = va_arg(args, FILE *);
- format = va_arg(args, char *);
-#endif
- /* initialize level, if not already done */
- if( _gwarning == -1 ){
- char *s;
- if( (s=getenv("GWARNING")) )
- _gwarning = atoi(s);
- else
- _gwarning = 1;
- }
- snprintf(tbuf, SZ_LINE-1, "WARNING: %s", format);
- vsnprintf(_gwarnings, SZ_LINE-1, tbuf, args);
- /* if the warning flag is positive, we output immediately */
- if( (fd != NULL) && _gwarning ){
- fputs(_gwarnings, fd);
- fflush(fd);
- }
-}
-
-#ifdef ANSI_FUNC
-void
-gsleep (int msec)
-#else
-void gsleep(msec)
- int msec;
-#endif
-{
- struct timeval tv;
- if( msec > 0 ){
- tv.tv_sec = msec / 1000;
- tv.tv_usec = (msec % 1000) * 1000;
- select(1, NULL, NULL, NULL, &tv);
- }
-}