summaryrefslogtreecommitdiffstats
path: root/funtools/util/gcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'funtools/util/gcat.c')
-rw-r--r--funtools/util/gcat.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/funtools/util/gcat.c b/funtools/util/gcat.c
new file mode 100644
index 0000000..3b26332
--- /dev/null
+++ b/funtools/util/gcat.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory
+ */
+
+/*
+ *
+ * gcat -- cat-like program using gio with byte-swapping support
+ *
+ */
+
+#include <gio.h>
+
+#define BUFSIZE 4096
+
+extern char *optarg;
+extern int optind;
+
+#ifdef ANSI_FUNC
+static void swap2(char *to, char *from, size_t nbytes)
+#else
+static void swap2(to, from, nbytes)
+ char *to;
+ char *from;
+ size_t nbytes;
+#endif
+{
+ char c;
+ size_t i;
+ for(i=0; i < nbytes; i += 2, (to += 2), (from += 2)){
+ c = *from;
+ *(to) = *(from+1);
+ *(to+1) = c;
+ }
+}
+
+#ifdef ANSI_FUNC
+static void swap4(char *to, char *from, size_t nbytes)
+#else
+static void swap4(to, from, nbytes)
+ char *to;
+ char *from;
+ size_t nbytes;
+#endif
+{
+ char c;
+ size_t i;
+ for(i=0; i < nbytes; i += 4, (to += 4), (from += 4)){
+ c = *from;
+ *to = *(from+3);
+ *(to+3) = c;
+ c = *(from+1);
+ *(to+1) = *(from+2);
+ *(to+2) = c;
+ }
+}
+
+#ifdef ANSI_FUNC
+static void swap8(char *to, char *from, size_t nbytes)
+#else
+static void swap8(to, from, nbytes)
+ char *to;
+ char *from;
+ size_t nbytes;
+#endif
+{
+ char c;
+ size_t i;
+ for(i=0; i < nbytes; i += 8, (to += 8), (from += 8)){
+ c = *(from+0);
+ *(to+0) = *(from+7);
+ *(to+7) = c;
+ c = *(from+1);
+ *(to+1) = *(from+6);
+ *(to+6) = c;
+ c = *(from+2);
+ *(to+2) = *(from+5);
+ *(to+5) = c;
+ c = *(from+3);
+ *(to+3) = *(from+4);
+ *(to+4) = c;
+ }
+}
+
+
+#ifdef ANSI_FUNC
+static void usage(char *s)
+#else
+static void usage(s)
+ char *s;
+#endif
+{
+ fprintf(stderr,
+ "usage: %s <switches> [iname [oname]]\n", s);
+ fprintf(stderr, "optional switches:\n");
+ fprintf(stderr, " -b bufsize # number of records to read at once (def: %d)\n", BUFSIZE);
+ fprintf(stderr, " -e elsize # size of an individual record (def: 1)\n");
+ fprintf(stderr, " -s elsize # swap bytes in a record of this size (def: no swapping)\n");
+ fprintf(stderr, " -v # verbose messages as data is transferred\n");
+ fprintf(stderr, "examples:\n");
+ fprintf(stderr, "# copy named files\n");
+ fprintf(stderr, "%s foo foo2\n", s);
+ fprintf(stderr, "# or copy file to socket 1234 on this host\n");
+ fprintf(stderr, "%s foo '$host:1234'\n", s);
+ fprintf(stderr, "# or copy from a socket on this host to another host\n");
+ fprintf(stderr, "%s '$host:1234' 'remotehost:2345'\n", s);
+ exit(0);
+}
+
+#ifdef ANSI_FUNC
+int
+main (int argc, char **argv)
+#else
+int main(argc, argv)
+ int argc;
+ char **argv;
+#endif
+{
+ int c;
+ int got;
+ int args;
+ int ntot=0;
+ int doswap=0;
+ int elsize=1;
+ int verbose=0;
+ int bufsize=BUFSIZE;
+ char *ibuf=NULL;
+ char *obuf=NULL;
+ char *iname=NULL;
+ char *oname=NULL;
+ GIO igio;
+ GIO ogio;
+
+ /* exit on gio errors */
+ setgerror(2);
+
+ /* we want the args in the same order in which they arrived, and
+ gnu getopt sometimes changes things without this */
+ putenv("POSIXLY_CORRECT=true");
+
+ /* process switch arguments */
+ while ((c = getopt(argc, argv, "b:e:hs:v")) != -1){
+ switch(c){
+ case 'h':
+ usage(argv[0]);
+ return 0;
+ case 'b':
+ bufsize = atoi(optarg);
+ break;
+ case 'e':
+ elsize = atoi(optarg);
+ break;
+ case 's':
+ elsize = atoi(optarg);
+ switch(elsize){
+ case 1:
+ doswap = 0;
+ break;
+ case 2:
+ case 4:
+ case 8:
+ doswap = 1;
+ break;
+ default:
+ gerror(stderr, "ERROR: invalid swap size argument: %d\n", elsize);
+ break;
+ }
+ break;
+ case 'v':
+ verbose++;
+ break;
+ }
+ }
+
+ /* process remaining command line arguments(i.e. file names) */
+ args = argc - optind;
+ switch(args){
+ case 0:
+ iname = "stdin";
+ oname = "stdout";
+ break;
+ case 1:
+ iname = argv[optind+0];
+ oname = "stdout";
+ break;
+ case 2:
+ iname = argv[optind+0];
+ oname = argv[optind+1];
+ break;
+ default:
+ usage(argv[0]);
+ exit(1);
+ }
+
+ /* sanity checks */
+ if( bufsize <= 0 ) gerror(stderr, "bufsize must be positive\n", bufsize);
+ if( elsize <= 0 ) gerror(stderr, "elsize must be positive\n", elsize);
+
+ /* allocate space */
+ ibuf = xcalloc(elsize, bufsize);
+ if( doswap )
+ obuf = xcalloc(elsize, bufsize);
+ else
+ obuf = ibuf;
+
+ /* open the input and output files */
+ if( !(igio = gopen(iname, "r")) )
+ gerror(stderr, "can't gopen input file: %s\n", iname);
+ if( !(ogio = gopen(oname, "w")) )
+ gerror(stderr, "can't gopen output file: %s\n", oname);
+
+ /* read/write all bytes */
+ while( 1 ){
+ /* read next buffer's worth */
+ got = gread(igio, ibuf, elsize, bufsize);
+ if( !got )
+ break;
+ else if( got < 0 ){
+ gerror(stderr, "error reading input file\n");
+ break;
+ }
+ /* swap bytes, if necessary */
+ if( doswap ){
+ switch(elsize){
+ case 2:
+ swap2(obuf, ibuf, elsize*got);
+ break;
+ case 4:
+ swap4(obuf, ibuf, elsize*got);
+ break;
+ case 8:
+ swap8(obuf, ibuf, elsize*got);
+ break;
+ default:
+ gerror(stderr, "invalid swap size: %d\n", elsize);
+ break;
+ }
+
+ }
+ /* verbose display */
+ if( verbose >= 2 ){
+ if( doswap ){
+ fprintf(stderr, "transferring %d swapped %d-byte records\n",
+ got, elsize);
+ }
+ else if( elsize > 1 ){
+ fprintf(stderr, "transferring %d %d-byte records\n",
+ got, elsize);
+ }
+ else{
+ fprintf(stderr, "transferring %d bytes\n", got);
+ }
+ }
+ /* write buffer's worth */
+ if( gwrite(ogio, obuf, elsize, got) != (unsigned int)got ){
+ gerror(stderr, "error writing output file\n");
+ }
+ ntot += got;
+ }
+
+ /* verbose display */
+ if( verbose ){
+ if( doswap ){
+ fprintf(stderr, "transfer from %s to %s: %d swapped %d-byte records\n",
+ iname, oname, ntot, elsize);
+ }
+ else if( elsize > 1 ){
+ fprintf(stderr, "transfer from %s to %s: %d %d-byte records\n",
+ iname, oname, ntot, elsize);
+ }
+ else{
+ fprintf(stderr, "transfer from %s to %s: %d bytes\n",
+ iname, oname, ntot);
+ }
+ }
+
+ /* close files */
+ gclose(igio);
+ gclose(ogio);
+
+ /* clean up */
+ if( ibuf ) xfree(ibuf );
+ if( doswap && obuf ) xfree(obuf);
+ return 0;
+}