home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / rmt / rmt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-19  |  5.5 KB  |  236 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)rmt.c    5.6 (Berkeley) 6/1/90";
  42. #endif /* not lint */
  43.  
  44. /*
  45.  * rmt
  46.  */
  47. #include <stdio.h>
  48. #include <sgtty.h>
  49. #include <sys/types.h>
  50. #include <sys/socket.h>
  51. #include <sys/mtio.h>
  52. #include <errno.h>
  53. #include <string.h>
  54.  
  55. int    tape = -1;
  56.  
  57. char    *record;
  58. int    maxrecsize = -1;
  59. char    *checkbuf();
  60.  
  61. #define    SSIZE    64
  62. char    device[SSIZE];
  63. char    count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
  64.  
  65. char    resp[BUFSIZ];
  66.  
  67. long    lseek();
  68.  
  69. FILE    *debug;
  70. #define    DEBUG(f)    if (debug) fprintf(debug, f)
  71. #define    DEBUG1(f,a)    if (debug) fprintf(debug, f, a)
  72. #define    DEBUG2(f,a1,a2)    if (debug) fprintf(debug, f, a1, a2)
  73.  
  74. main(argc, argv)
  75.     int argc;
  76.     char **argv;
  77. {
  78.     int rval;
  79.     char c;
  80.     int n, i, cc;
  81.  
  82.     argc--, argv++;
  83.     if (argc > 0) {
  84.         debug = fopen(*argv, "w");
  85.         if (debug == 0)
  86.             exit(1);
  87.         (void) setbuf(debug, (char *)0);
  88.     }
  89. top:
  90.     errno = 0;
  91.     rval = 0;
  92.     if (read(0, &c, 1) != 1)
  93.         exit(0);
  94.     switch (c) {
  95.  
  96.     case 'O':
  97.         if (tape >= 0)
  98.             (void) close(tape);
  99.         getstring(device); getstring(mode);
  100.         DEBUG2("rmtd: O %s %s\n", device, mode);
  101.         tape = open(device, atoi(mode));
  102.         if (tape < 0)
  103.             goto ioerror;
  104.         goto respond;
  105.  
  106.     case 'C':
  107.         DEBUG("rmtd: C\n");
  108.         getstring(device);        /* discard */
  109.         if (close(tape) < 0)
  110.             goto ioerror;
  111.         tape = -1;
  112.         goto respond;
  113.  
  114.     case 'L':
  115.         getstring(count); getstring(pos);
  116.         DEBUG2("rmtd: L %s %s\n", count, pos);
  117.         rval = lseek(tape, (long) atoi(count), atoi(pos));
  118.         if (rval < 0)
  119.             goto ioerror;
  120.         goto respond;
  121.  
  122.     case 'W':
  123.         getstring(count);
  124.         n = atoi(count);
  125.         DEBUG1("rmtd: W %s\n", count);
  126.         record = checkbuf(record, n);
  127.         for (i = 0; i < n; i += cc) {
  128.             cc = read(0, &record[i], n - i);
  129.             if (cc <= 0) {
  130.                 DEBUG("rmtd: premature eof\n");
  131.                 exit(2);
  132.             }
  133.         }
  134.         rval = write(tape, record, n);
  135.         if (rval < 0)
  136.             goto ioerror;
  137.         goto respond;
  138.  
  139.     case 'R':
  140.         getstring(count);
  141.         DEBUG1("rmtd: R %s\n", count);
  142.         n = atoi(count);
  143.         record = checkbuf(record, n);
  144.         rval = read(tape, record, n);
  145.         if (rval < 0)
  146.             goto ioerror;
  147.         (void) sprintf(resp, "A%d\n", rval);
  148.         (void) write(1, resp, strlen(resp));
  149.         (void) write(1, record, rval);
  150.         goto top;
  151.  
  152.     case 'I':
  153.         getstring(op); getstring(count);
  154.         DEBUG2("rmtd: I %s %s\n", op, count);
  155.         { struct mtop mtop;
  156.           mtop.mt_op = atoi(op);
  157.           mtop.mt_count = atoi(count);
  158.           if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
  159.             goto ioerror;
  160.           rval = mtop.mt_count;
  161.         }
  162.         goto respond;
  163.  
  164.     case 'S':        /* status */
  165.         DEBUG("rmtd: S\n");
  166.         { struct mtget mtget;
  167.           if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
  168.             goto ioerror;
  169.           rval = sizeof (mtget);
  170.           (void) sprintf(resp, "A%d\n", rval);
  171.           (void) write(1, resp, strlen(resp));
  172.           (void) write(1, (char *)&mtget, sizeof (mtget));
  173.           goto top;
  174.         }
  175.  
  176.     default:
  177.         DEBUG1("rmtd: garbage command %c\n", c);
  178.         exit(3);
  179.     }
  180. respond:
  181.     DEBUG1("rmtd: A %d\n", rval);
  182.     (void) sprintf(resp, "A%d\n", rval);
  183.     (void) write(1, resp, strlen(resp));
  184.     goto top;
  185. ioerror:
  186.     error(errno);
  187.     goto top;
  188. }
  189.  
  190. getstring(bp)
  191.     char *bp;
  192. {
  193.     int i;
  194.     char *cp = bp;
  195.  
  196.     for (i = 0; i < SSIZE; i++) {
  197.         if (read(0, cp+i, 1) != 1)
  198.             exit(0);
  199.         if (cp[i] == '\n')
  200.             break;
  201.     }
  202.     cp[i] = '\0';
  203. }
  204.  
  205. char *
  206. checkbuf(record, size)
  207.     char *record;
  208.     int size;
  209. {
  210.     extern char *malloc();
  211.  
  212.     if (size <= maxrecsize)
  213.         return (record);
  214.     if (record != 0)
  215.         free(record);
  216.     record = malloc(size);
  217.     if (record == 0) {
  218.         DEBUG("rmtd: cannot allocate buffer space\n");
  219.         exit(4);
  220.     }
  221.     maxrecsize = size;
  222.     while (size > 1024 &&
  223.            setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
  224.         size -= 1024;
  225.     return (record);
  226. }
  227.  
  228. error(num)
  229.     int num;
  230. {
  231.  
  232.     DEBUG2("rmtd: E %d (%s)\n", num, strerror(num));
  233.     (void) sprintf(resp, "E%d\n%s\n", num, strerror(num));
  234.     (void) write(1, resp, strlen(resp));
  235. }
  236.