home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / archivers / amignutar / src / rtape_server.c < prev    next >
C/C++ Source or Header  |  1998-04-23  |  5KB  |  227 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 are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. #ifndef lint
  25. static char sccsid[] = "@(#)rmt.c    5.4 (Berkeley) 6/29/88";
  26. #endif /* not lint */
  27.  
  28. /* JF added #ifdef about SO_RCVBUF in attempt to make this run on more
  29.    machines.  Maybe it'll work */
  30. /*
  31.  * rmt
  32.  */
  33. #include <stdio.h>
  34. #include <sgtty.h>
  35. #include <sys/types.h>
  36. #include <sys/socket.h>
  37. #include <sys/mtio.h>
  38. #include <errno.h>
  39.  
  40. int    tape = -1;
  41.  
  42. char    *record;
  43. int    maxrecsize = -1;
  44. char    *checkbuf();
  45.  
  46. #define    SSIZE    64
  47. char    device[SSIZE];
  48. char    count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
  49.  
  50. extern    errno;
  51. char    *sys_errlist[];
  52. char    resp[BUFSIZ];
  53.  
  54. long    lseek();
  55.  
  56. FILE    *debug;
  57. #define    DEBUG(f)    if (debug) fprintf(debug, f)
  58. #define    DEBUG1(f,a)    if (debug) fprintf(debug, f, a)
  59. #define    DEBUG2(f,a1,a2)    if (debug) fprintf(debug, f, a1, a2)
  60.  
  61. main(argc, argv)
  62.     int argc;
  63.     char **argv;
  64. {
  65.     int rval;
  66.     char c;
  67.     int n, i, cc;
  68.  
  69.     argc--, argv++;
  70.     if (argc > 0) {
  71.         debug = fopen(*argv, "w");
  72.         if (debug == 0)
  73.             exit(1);
  74.         (void) setbuf(debug, (char *)0);
  75.     }
  76. top:
  77.     errno = 0;
  78.     rval = 0;
  79.     if (read(0, &c, 1) != 1)
  80.         exit(0);
  81.     switch (c) {
  82.  
  83.     case 'O':
  84.         if (tape >= 0)
  85.             (void) close(tape);
  86.         getstring(device); getstring(mode);
  87.         DEBUG2("rmtd: O %s %s\n", device, mode);
  88.         tape = open(device, atoi(mode),0666);
  89.         if (tape < 0)
  90.             goto ioerror;
  91.         goto respond;
  92.  
  93.     case 'C':
  94.         DEBUG("rmtd: C\n");
  95.         getstring(device);        /* discard */
  96.         if (close(tape) < 0)
  97.             goto ioerror;
  98.         tape = -1;
  99.         goto respond;
  100.  
  101.     case 'L':
  102.         getstring(count); getstring(pos);
  103.         DEBUG2("rmtd: L %s %s\n", count, pos);
  104.         rval = lseek(tape, (long) atoi(count), atoi(pos));
  105.         if (rval < 0)
  106.             goto ioerror;
  107.         goto respond;
  108.  
  109.     case 'W':
  110.         getstring(count);
  111.         n = atoi(count);
  112.         DEBUG1("rmtd: W %s\n", count);
  113.         record = checkbuf(record, n);
  114.         for (i = 0; i < n; i += cc) {
  115.             cc = read(0, &record[i], n - i);
  116.             if (cc <= 0) {
  117.                 DEBUG("rmtd: premature eof\n");
  118.                 exit(2);
  119.             }
  120.         }
  121.         rval = write(tape, record, n);
  122.         if (rval < 0)
  123.             goto ioerror;
  124.         goto respond;
  125.  
  126.     case 'R':
  127.         getstring(count);
  128.         DEBUG1("rmtd: R %s\n", count);
  129.         n = atoi(count);
  130.         record = checkbuf(record, n);
  131.         rval = read(tape, record, n);
  132.         if (rval < 0)
  133.             goto ioerror;
  134.         (void) sprintf(resp, "A%d\n", rval);
  135.         (void) write(1, resp, strlen(resp));
  136.         (void) write(1, record, rval);
  137.         goto top;
  138.  
  139.     case 'I':
  140.         getstring(op); getstring(count);
  141.         DEBUG2("rmtd: I %s %s\n", op, count);
  142.         { struct mtop mtop;
  143.           mtop.mt_op = atoi(op);
  144.           mtop.mt_count = atoi(count);
  145.           if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
  146.             goto ioerror;
  147.           rval = mtop.mt_count;
  148.         }
  149.         goto respond;
  150.  
  151.     case 'S':        /* status */
  152.         DEBUG("rmtd: S\n");
  153.         { struct mtget mtget;
  154.           if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
  155.             goto ioerror;
  156.           rval = sizeof (mtget);
  157.           (void) sprintf(resp, "A%d\n", rval);
  158.           (void) write(1, resp, strlen(resp));
  159.           (void) write(1, (char *)&mtget, sizeof (mtget));
  160.           goto top;
  161.         }
  162.  
  163.     default:
  164.         DEBUG1("rmtd: garbage command %c\n", c);
  165.         exit(3);
  166.     }
  167. respond:
  168.     DEBUG1("rmtd: A %d\n", rval);
  169.     (void) sprintf(resp, "A%d\n", rval);
  170.     (void) write(1, resp, strlen(resp));
  171.     goto top;
  172. ioerror:
  173.     error(errno);
  174.     goto top;
  175. }
  176.  
  177. getstring(bp)
  178.     char *bp;
  179. {
  180.     int i;
  181.     char *cp = bp;
  182.  
  183.     for (i = 0; i < SSIZE; i++) {
  184.         if (read(0, cp+i, 1) != 1)
  185.             exit(0);
  186.         if (cp[i] == '\n')
  187.             break;
  188.     }
  189.     cp[i] = '\0';
  190. }
  191.  
  192. char *
  193. checkbuf(record, size)
  194.     char *record;
  195.     int size;
  196. {
  197.     extern char *malloc();
  198.  
  199.     if (size <= maxrecsize)
  200.         return (record);
  201.     if (record != 0)
  202.         free(record);
  203.     record = malloc(size);
  204.     if (record == 0) {
  205.         DEBUG("rmtd: cannot allocate buffer space\n");
  206.         exit(4);
  207.     }
  208.     maxrecsize = size;
  209. #ifdef SO_RCVBUF
  210.     while (size > 1024 &&
  211.            setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
  212.         size -= 1024;
  213. #else
  214.     size= 1+((size-1)%1024);
  215. #endif
  216.     return (record);
  217. }
  218.  
  219. error(num)
  220.     int num;
  221. {
  222.  
  223.     DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
  224.     (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
  225.     (void) write(1, resp, strlen (resp));
  226. }
  227.