home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / g / gtak212.zip / 1.10 / rtape_sv.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  7KB  |  277 lines

  1. /*****************************************************************************
  2.  * $Id: rtape_sv.c,v 1.2 1992/09/02 20:09:06 ak Exp $
  3.  *****************************************************************************
  4.  * $Log: rtape_sv.c,v $
  5.  * Revision 1.2  1992/09/02  20:09:06  ak
  6.  * Version AK200
  7.  * - Tape access
  8.  * - Quick file access
  9.  * - OS/2 extended attributes
  10.  * - Some OS/2 fixes
  11.  * - Some fixes of Kai Uwe Rommel
  12.  *
  13.  * Revision 1.1.1.1  1992/09/02  19:22:43  ak
  14.  * Original GNU Tar 1.10 with some filenames changed for FAT compatibility.
  15.  *
  16.  * Revision 1.1  1992/09/02  19:22:42  ak
  17.  * Initial revision
  18.  *
  19.  *****************************************************************************/
  20.  
  21. static char *rcsid = "$Id: rtape_sv.c,v 1.2 1992/09/02 20:09:06 ak Exp $";
  22.  
  23. /*
  24.  * Copyright (c) 1983 Regents of the University of California.
  25.  * All rights reserved.
  26.  *
  27.  * Redistribution and use in source and binary forms are permitted
  28.  * provided that the above copyright notice and this paragraph are
  29.  * duplicated in all such forms and that any documentation,
  30.  * advertising materials, and other materials related to such
  31.  * distribution and use acknowledge that the software was developed
  32.  * by the University of California, Berkeley.  The name of the
  33.  * University may not be used to endorse or promote products derived
  34.  * from this software without specific prior written permission.
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  36.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  37.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  38.  */
  39.  
  40. #ifndef lint
  41. char copyright[] =
  42. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  43.  All rights reserved.\n";
  44. #endif /* not lint */
  45.  
  46. #ifndef lint
  47. static char sccsid[] = "@(#)rmt.c    5.4 (Berkeley) 6/29/88";
  48. #endif /* not lint */
  49.  
  50. /* JF added #ifdef about SO_RCVBUF in attempt to make this run on more
  51.    machines.  Maybe it'll work */
  52. /*
  53.  * rmt
  54.  */
  55. #include <stdio.h>
  56. #include <sgtty.h>
  57. #include <sys/types.h>
  58. #include <sys/socket.h>
  59. #include <sys/mtio.h>
  60. #include <errno.h>
  61.  
  62. #if defined (i386) && defined (AIX)
  63. #include <fcntl.h>
  64. #endif
  65.  
  66. int    tape = -1;
  67.  
  68. char    *record;
  69. int    maxrecsize = -1;
  70. char    *checkbuf();
  71.  
  72. #define    SSIZE    64
  73. char    device[SSIZE];
  74. char    count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
  75.  
  76. extern    errno;
  77. char    *sys_errlist[];
  78. char    resp[BUFSIZ];
  79.  
  80. long    lseek();
  81.  
  82. FILE    *debug;
  83. #define    DEBUG(f)    if (debug) fprintf(debug, f)
  84. #define    DEBUG1(f,a)    if (debug) fprintf(debug, f, a)
  85. #define    DEBUG2(f,a1,a2)    if (debug) fprintf(debug, f, a1, a2)
  86.  
  87. main(argc, argv)
  88.     int argc;
  89.     char **argv;
  90. {
  91.     int rval;
  92.     char c;
  93.     int n, i, cc;
  94.  
  95.     argc--, argv++;
  96.     if (argc > 0) {
  97.         debug = fopen(*argv, "w");
  98.         if (debug == 0)
  99.             exit(1);
  100.         (void) setbuf(debug, (char *)0);
  101.     }
  102. top:
  103.     errno = 0;
  104.     rval = 0;
  105.     if (read(0, &c, 1) != 1)
  106.         exit(0);
  107.     switch (c) {
  108.  
  109.     case 'O':
  110.         if (tape >= 0)
  111.             (void) close(tape);
  112.         getstring(device); getstring(mode);
  113.         DEBUG2("rmtd: O %s %s\n", device, mode);
  114. #if defined (i386) && defined (AIX)
  115.         /* This is alleged to fix a byte ordering problem. */
  116.         /* I'm quite suspicious if it's right. -- mib */
  117.         {
  118.           int oflag = atoi (mode);
  119.           int nflag = 0;
  120.           if ((oflag & 3) == 0)
  121.             nflag |= O_RDONLY;
  122.           if (oflag & 1)
  123.             nflag |= O_WRONLY;
  124.           if (oflag & 2)
  125.             nflag |= O_RDWR;
  126.           if (oflag & 0x0008)
  127.             nflag |= O_APPEND;
  128.           if (oflag & 0x0200)
  129.             nflag |= O_CREAT;
  130.           if (oflag & 0x0400)
  131.             nflag |= O_TRUNC;
  132.           if (oflag & 0x0800)
  133.             nflag |= O_EXCL;
  134.           tape = open (device, nflag, 0666);
  135.         }
  136. #else        
  137.         tape = open(device, atoi(mode),0666);
  138. #endif
  139.         if (tape < 0)
  140.             goto ioerror;
  141.         goto respond;
  142.  
  143.     case 'C':
  144.         DEBUG("rmtd: C\n");
  145.         getstring(device);        /* discard */
  146.         if (close(tape) < 0)
  147.             goto ioerror;
  148.         tape = -1;
  149.         goto respond;
  150.  
  151.     case 'L':
  152.         getstring(count); getstring(pos);
  153.         DEBUG2("rmtd: L %s %s\n", count, pos);
  154.         rval = lseek(tape, (long) atoi(count), atoi(pos));
  155.         if (rval < 0)
  156.             goto ioerror;
  157.         goto respond;
  158.  
  159.     case 'W':
  160.         getstring(count);
  161.         n = atoi(count);
  162.         DEBUG1("rmtd: W %s\n", count);
  163.         record = checkbuf(record, n);
  164.         for (i = 0; i < n; i += cc) {
  165.             cc = read(0, &record[i], n - i);
  166.             if (cc <= 0) {
  167.                 DEBUG("rmtd: premature eof\n");
  168.                 exit(2);
  169.             }
  170.         }
  171.         rval = write(tape, record, n);
  172.         if (rval < 0)
  173.             goto ioerror;
  174.         goto respond;
  175.  
  176.     case 'R':
  177.         getstring(count);
  178.         DEBUG1("rmtd: R %s\n", count);
  179.         n = atoi(count);
  180.         record = checkbuf(record, n);
  181.         rval = read(tape, record, n);
  182.         if (rval < 0)
  183.             goto ioerror;
  184.         (void) sprintf(resp, "A%d\n", rval);
  185.         (void) write(1, resp, strlen(resp));
  186.         (void) write(1, record, rval);
  187.         goto top;
  188.  
  189.     case 'I':
  190.         getstring(op); getstring(count);
  191.         DEBUG2("rmtd: I %s %s\n", op, count);
  192.         { struct mtop mtop;
  193.           mtop.mt_op = atoi(op);
  194.           mtop.mt_count = atoi(count);
  195.           if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
  196.             goto ioerror;
  197.           rval = mtop.mt_count;
  198.         }
  199.         goto respond;
  200.  
  201.     case 'S':        /* status */
  202.         DEBUG("rmtd: S\n");
  203.         { struct mtget mtget;
  204.           if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
  205.             goto ioerror;
  206.           rval = sizeof (mtget);
  207.           (void) sprintf(resp, "A%d\n", rval);
  208.           (void) write(1, resp, strlen(resp));
  209.           (void) write(1, (char *)&mtget, sizeof (mtget));
  210.           goto top;
  211.         }
  212.  
  213.     default:
  214.         DEBUG1("rmtd: garbage command %c\n", c);
  215.         exit(3);
  216.     }
  217. respond:
  218.     DEBUG1("rmtd: A %d\n", rval);
  219.     (void) sprintf(resp, "A%d\n", rval);
  220.     (void) write(1, resp, strlen(resp));
  221.     goto top;
  222. ioerror:
  223.     error(errno);
  224.     goto top;
  225. }
  226.  
  227. getstring(bp)
  228.     char *bp;
  229. {
  230.     int i;
  231.     char *cp = bp;
  232.  
  233.     for (i = 0; i < SSIZE; i++) {
  234.         if (read(0, cp+i, 1) != 1)
  235.             exit(0);
  236.         if (cp[i] == '\n')
  237.             break;
  238.     }
  239.     cp[i] = '\0';
  240. }
  241.  
  242. char *
  243. checkbuf(record, size)
  244.     char *record;
  245.     int size;
  246. {
  247.     extern char *malloc();
  248.  
  249.     if (size <= maxrecsize)
  250.         return (record);
  251.     if (record != 0)
  252.         free(record);
  253.     record = malloc(size);
  254.     if (record == 0) {
  255.         DEBUG("rmtd: cannot allocate buffer space\n");
  256.         exit(4);
  257.     }
  258.     maxrecsize = size;
  259. #ifdef SO_RCVBUF
  260.     while (size > 1024 &&
  261.            setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
  262.         size -= 1024;
  263. #else
  264.     size= 1+((size-1)%1024);
  265. #endif
  266.     return (record);
  267. }
  268.  
  269. error(num)
  270.     int num;
  271. {
  272.  
  273.     DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
  274.     (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
  275.     (void) write(1, resp, strlen (resp));
  276. }
  277.