home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / tar-1.11.8-src.tgz / tar.out / fsf / tar / src / rmt.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  7KB  |  322 lines

  1. /* Remote connection server.
  2.    Copyright (C) 1994 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GNU tar.
  5.  
  6.    GNU tar is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GNU tar is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GNU tar; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Copyright (c) 1983 Regents of the University of California.  All
  21.    rights reserved.
  22.    
  23.    Redistribution and use in source and binary forms are permitted
  24.    provided that the above copyright notice and this paragraph are
  25.    duplicated in all such forms and that any documentation, advertising
  26.    materials, and other materials related to such distribution and use
  27.    acknowledge that the software was developed by the University of
  28.    California, Berkeley.  The name of the University may not be used to
  29.    endorse or promote products derived from this software without
  30.    specific prior written permission.  THIS SOFTWARE IS PROVIDED ``AS
  31.    IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
  32.    LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33.    A PARTICULAR PURPOSE.  */
  34.  
  35. #include "system.h"
  36.  
  37. #ifndef lint
  38. static char copyright[] =
  39. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  40.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #include <sgtty.h>
  44. #include <sys/socket.h>
  45.  
  46. #ifndef EXIT_FAILURE
  47. # define EXIT_FAILURE 1
  48. #endif
  49. #ifndef EXIT_SUCCESS
  50. # define EXIT_SUCCESS 0
  51. #endif
  52.  
  53. int tape = -1;
  54.  
  55. char *record = 0;
  56. int maxrecsize = -1;
  57.  
  58. #define    STRING_SIZE    64
  59. char device[STRING_SIZE];
  60. char count[STRING_SIZE], mode[STRING_SIZE], pos[STRING_SIZE], op[STRING_SIZE];
  61.  
  62. extern char *sys_errlist[];
  63. char resp[BUFSIZ];
  64.  
  65. FILE *debug;
  66.  
  67. #define    DEBUG(File) \
  68.   if (debug) fprintf(debug, File)
  69. #define    DEBUG1(File, Arg) \
  70.   if (debug) fprintf(debug, File, Arg)
  71. #define    DEBUG2(File, Arg1, Arg2) \
  72.   if (debug) fprintf(debug, File, Arg1, Arg2)
  73.  
  74. /*---.
  75. | ?  |
  76. `---*/
  77.  
  78. static void
  79. string_error (const char *string)
  80. {
  81.   DEBUG1 ("rmtd: E 0 (%s)\n", string);
  82.   sprintf (resp, "E0\n%s\n", string);
  83.   write (1, resp, strlen (resp));
  84. }
  85.  
  86. /*---.
  87. | ?  |
  88. `---*/
  89.  
  90. static void
  91. numeric_error (int num)
  92. {
  93.   DEBUG2 ("rmtd: E %d (%s)\n", num, sys_errlist[num]);
  94.   sprintf (resp, "E%d\n%s\n", num, sys_errlist[num]);
  95.   write (1, resp, strlen (resp));
  96. }
  97.  
  98. /*---.
  99. | ?  |
  100. `---*/
  101.  
  102. static void
  103. getstring (char *bp)
  104. {
  105.   int i;
  106.   char *cp = bp;
  107.  
  108.   for (i = 0; i < STRING_SIZE; i++)
  109.     {
  110.       if (read (0, cp + i, 1) != 1)
  111.     exit (EXIT_SUCCESS);
  112.  
  113.       if (cp[i] == '\n')
  114.     break;
  115.     }
  116.   cp[i] = '\0';
  117. }
  118.  
  119. /*---.
  120. | ?  |
  121. `---*/
  122.  
  123. static void
  124. checkbuf (int size)
  125. {
  126.   if (size <= maxrecsize)
  127.     return;
  128.   if (record)
  129.     free (record);
  130.   record = malloc ((size_t) size);
  131.   if (record == 0)
  132.     {
  133.       DEBUG (_("rmtd: Cannot allocate buffer space\n"));
  134.       string_error (_("Cannot allocate buffer space"));
  135.       exit (EXIT_FAILURE);      /* status used to be 4 */
  136.     }
  137.   maxrecsize = size;
  138. #ifdef SO_RCVBUF
  139.   while (size > 1024 &&
  140.    setsockopt (0, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof (size)) < 0)
  141.     size -= 1024;
  142. #else
  143.   size = 1 + ((size - 1) % 1024);
  144. #endif
  145. }
  146.  
  147. /*---.
  148. | ?  |
  149. `---*/
  150.  
  151. const char *program_name;
  152.  
  153. int
  154. main (int argc, char *const *argv)
  155. {
  156.   int rval;
  157.   char c;
  158.   int n, i, cc;
  159.  
  160.   program_name = argv[0];
  161.   setlocale (LC_ALL, "");
  162.  
  163.   argc--, argv++;
  164.   if (argc > 0)
  165.     {
  166.       debug = fopen (*argv, "w");
  167.       if (debug == 0)
  168.     {
  169.       numeric_error (errno);
  170.       exit (EXIT_FAILURE);
  171.     }
  172.       setbuf (debug, (char *) 0);
  173.     }
  174.  
  175. top:
  176.   errno = 0;
  177.   rval = 0;
  178.   if (read (0, &c, 1) != 1)
  179.     exit (EXIT_SUCCESS);
  180.  
  181.   switch (c)
  182.     {
  183.  
  184.     case 'O':
  185.       if (tape >= 0)
  186.     close (tape);
  187.       getstring (device);
  188.       getstring (mode);
  189.       DEBUG2 ("rmtd: O %s %s\n", device, mode);
  190.  
  191. #if defined (i386) && defined (AIX)
  192.  
  193.       /* This is alleged to fix a byte ordering problem.  I'm quite
  194.      suspicious if it's right. -- mib.  */
  195.  
  196.       {
  197.     int oflag = atoi (mode);
  198.     int nflag = 0;
  199.  
  200.     if ((oflag & 3) == 0)
  201.       nflag |= O_RDONLY;
  202.     if (oflag & 1)
  203.       nflag |= O_WRONLY;
  204.     if (oflag & 2)
  205.       nflag |= O_RDWR;
  206.     if (oflag & 0x0008)
  207.       nflag |= O_APPEND;
  208.     if (oflag & 0x0200)
  209.       nflag |= O_CREAT;
  210.     if (oflag & 0x0400)
  211.       nflag |= O_TRUNC;
  212.     if (oflag & 0x0800)
  213.       nflag |= O_EXCL;
  214.     tape = open (device, nflag, 0666);
  215.       }
  216. #else
  217.       tape = open (device, atoi (mode), 0666);
  218. #endif
  219.       if (tape < 0)
  220.     goto ioerror;
  221.       goto respond;
  222.  
  223.     case 'C':
  224.       DEBUG ("rmtd: C\n");
  225.       getstring (device);    /* discard */
  226.       if (close (tape) < 0)
  227.     goto ioerror;
  228.       tape = -1;
  229.       goto respond;
  230.  
  231.     case 'L':
  232.       getstring (count);
  233.       getstring (pos);
  234.       DEBUG2 ("rmtd: L %s %s\n", count, pos);
  235.       rval = lseek (tape, (off_t) atol (count), atoi (pos));
  236.       if (rval < 0)
  237.     goto ioerror;
  238.       goto respond;
  239.  
  240.     case 'W':
  241.       getstring (count);
  242.       n = atoi (count);
  243.       DEBUG1 ("rmtd: W %s\n", count);
  244.       checkbuf (n);
  245.       for (i = 0; i < n; i += cc)
  246.     {
  247.       cc = read (0, &record[i], n - i);
  248.       if (cc <= 0)
  249.         {
  250.           DEBUG (_("rmtd: Premature eof\n"));
  251.           string_error (_("Premature end of file"));
  252.           exit (EXIT_FAILURE); /* status used to be 2 */
  253.         }
  254.     }
  255.       rval = write (tape, record, n);
  256.       if (rval < 0)
  257.     goto ioerror;
  258.       goto respond;
  259.  
  260.     case 'R':
  261.       getstring (count);
  262.       DEBUG1 ("rmtd: R %s\n", count);
  263.       n = atoi (count);
  264.       checkbuf (n);
  265.       rval = read (tape, record, n);
  266.       if (rval < 0)
  267.     goto ioerror;
  268.       sprintf (resp, "A%d\n", rval);
  269.       write (1, resp, strlen (resp));
  270.       write (1, record, rval);
  271.       goto top;
  272.  
  273.     case 'I':
  274.       getstring (op);
  275.       getstring (count);
  276.       DEBUG2 ("rmtd: I %s %s\n", op, count);
  277. #ifdef MTIOCTOP
  278.       {
  279.     struct mtop mtop;
  280.  
  281.     mtop.mt_op = atoi (op);
  282.     mtop.mt_count = atoi (count);
  283.     if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0)
  284.       goto ioerror;
  285.     rval = mtop.mt_count;
  286.       }
  287. #endif
  288.       goto respond;
  289.  
  290.     case 'S':            /* status */
  291.       DEBUG ("rmtd: S\n");
  292.       {
  293. #ifdef MTIOCGET
  294.     struct mtget mtget;
  295.  
  296.     if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0)
  297.       goto ioerror;
  298.     rval = sizeof (mtget);
  299.     sprintf (resp, "A%d\n", rval);
  300.     write (1, resp, strlen (resp));
  301.     write (1, (char *) &mtget, sizeof (mtget));
  302. #endif
  303.     goto top;
  304.       }
  305.  
  306.     default:
  307.       DEBUG1 (_("rmtd: Garbage command %c\n"), c);
  308.       string_error (_("Garbage command"));
  309.       exit (EXIT_FAILURE);    /* status used to be 3 */
  310.     }
  311.  
  312. respond:
  313.   DEBUG1 ("rmtd: A %d\n", rval);
  314.   sprintf (resp, "A%d\n", rval);
  315.   write (1, resp, strlen (resp));
  316.   goto top;
  317.  
  318. ioerror:
  319.   numeric_error (errno);
  320.   goto top;
  321. }
  322.