rmt.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. #ifndef lint
  18. char copyright[] =
  19. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  20. All rights reserved.\n";
  21. #endif /* not lint */
  22. /*
  23. * rmt
  24. */
  25. #include <stdio.h>
  26. #include <sgtty.h>
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #ifdef HAVE_SYS_GENTAPE_H /* e.g., ISC UNIX */
  30. #include <sys/gentape.h>
  31. #else
  32. #ifdef M_UNIX
  33. #include <sys/tape.h>
  34. #else
  35. #include <sys/mtio.h>
  36. #endif
  37. #endif
  38. #include <errno.h>
  39. #if defined (_I386) && defined (_AIX)
  40. #include <fcntl.h>
  41. #endif
  42. #ifdef HAVE_UNISTD_H
  43. #include <unistd.h>
  44. #else
  45. long lseek ();
  46. #endif
  47. #ifdef STDC_HEADERS
  48. #include <string.h>
  49. #include <stdlib.h>
  50. #else
  51. extern char *malloc ();
  52. #endif
  53. int tape = -1;
  54. char *record;
  55. int maxrecsize = -1;
  56. char *checkbuf ();
  57. void getstring ();
  58. void error ();
  59. #define SSIZE 64
  60. char device[SSIZE];
  61. char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
  62. extern errno;
  63. extern char *sys_errlist[];
  64. char resp[BUFSIZ];
  65. FILE *debug;
  66. #define DEBUG(f) if (debug) fprintf(debug, f)
  67. #define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
  68. #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
  69. int
  70. main (argc, argv)
  71. int argc;
  72. char **argv;
  73. {
  74. int rval;
  75. char c;
  76. int n, i, cc;
  77. argc--, argv++;
  78. if (argc > 0)
  79. {
  80. debug = fopen (*argv, "w");
  81. if (debug == 0)
  82. exit (1);
  83. (void) setbuf (debug, (char *) 0);
  84. }
  85. top:
  86. errno = 0;
  87. rval = 0;
  88. if (read (0, &c, 1) != 1)
  89. exit (0);
  90. switch (c)
  91. {
  92. case 'O':
  93. if (tape >= 0)
  94. (void) close (tape);
  95. getstring (device);
  96. getstring (mode);
  97. DEBUG2 ("rmtd: O %s %s\n", device, mode);
  98. #if defined (i386) && defined (AIX)
  99. /* This is alleged to fix a byte ordering problem. */
  100. /* I'm quite suspicious if it's right. -- mib */
  101. {
  102. int oflag = atoi (mode);
  103. int nflag = 0;
  104. if ((oflag & 3) == 0)
  105. nflag |= O_RDONLY;
  106. if (oflag & 1)
  107. nflag |= O_WRONLY;
  108. if (oflag & 2)
  109. nflag |= O_RDWR;
  110. if (oflag & 0x0008)
  111. nflag |= O_APPEND;
  112. if (oflag & 0x0200)
  113. nflag |= O_CREAT;
  114. if (oflag & 0x0400)
  115. nflag |= O_TRUNC;
  116. if (oflag & 0x0800)
  117. nflag |= O_EXCL;
  118. tape = open (device, nflag, 0666);
  119. }
  120. #else
  121. tape = open (device, atoi (mode), 0666);
  122. #endif
  123. if (tape < 0)
  124. goto ioerror;
  125. goto respond;
  126. case 'C':
  127. DEBUG ("rmtd: C\n");
  128. getstring (device); /* discard */
  129. if (close (tape) < 0)
  130. goto ioerror;
  131. tape = -1;
  132. goto respond;
  133. case 'L':
  134. getstring (count);
  135. getstring (pos);
  136. DEBUG2 ("rmtd: L %s %s\n", count, pos);
  137. rval = lseek (tape, (long) atoi (count), atoi (pos));
  138. if (rval < 0)
  139. goto ioerror;
  140. goto respond;
  141. case 'W':
  142. getstring (count);
  143. n = atoi (count);
  144. DEBUG1 ("rmtd: W %s\n", count);
  145. record = checkbuf (record, n);
  146. for (i = 0; i < n; i += cc)
  147. {
  148. cc = read (0, &record[i], n - i);
  149. if (cc <= 0)
  150. {
  151. DEBUG ("rmtd: premature eof\n");
  152. exit (2);
  153. }
  154. }
  155. rval = write (tape, record, n);
  156. if (rval < 0)
  157. goto ioerror;
  158. goto respond;
  159. case 'R':
  160. getstring (count);
  161. DEBUG1 ("rmtd: R %s\n", count);
  162. n = atoi (count);
  163. record = checkbuf (record, n);
  164. rval = read (tape, record, n);
  165. if (rval < 0)
  166. goto ioerror;
  167. (void) sprintf (resp, "A%d\n", rval);
  168. (void) write (1, resp, strlen (resp));
  169. (void) write (1, record, rval);
  170. goto top;
  171. case 'I':
  172. getstring (op);
  173. getstring (count);
  174. DEBUG2 ("rmtd: I %s %s\n", op, count);
  175. #ifdef MTIOCTOP
  176. {
  177. struct mtop mtop;
  178. mtop.mt_op = atoi (op);
  179. mtop.mt_count = atoi (count);
  180. if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0)
  181. goto ioerror;
  182. rval = mtop.mt_count;
  183. }
  184. #endif
  185. goto respond;
  186. case 'S': /* status */
  187. DEBUG ("rmtd: S\n");
  188. {
  189. #ifdef MTIOCGET
  190. struct mtget mtget;
  191. if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0)
  192. goto ioerror;
  193. rval = sizeof (mtget);
  194. (void) sprintf (resp, "A%d\n", rval);
  195. (void) write (1, resp, strlen (resp));
  196. (void) write (1, (char *) &mtget, sizeof (mtget));
  197. #endif
  198. goto top;
  199. }
  200. default:
  201. DEBUG1 ("rmtd: garbage command %c\n", c);
  202. exit (3);
  203. }
  204. respond:
  205. DEBUG1 ("rmtd: A %d\n", rval);
  206. (void) sprintf (resp, "A%d\n", rval);
  207. (void) write (1, resp, strlen (resp));
  208. goto top;
  209. ioerror:
  210. error (errno);
  211. goto top;
  212. }
  213. void
  214. getstring (bp)
  215. char *bp;
  216. {
  217. int i;
  218. char *cp = bp;
  219. for (i = 0; i < SSIZE; i++)
  220. {
  221. if (read (0, cp + i, 1) != 1)
  222. exit (0);
  223. if (cp[i] == '\n')
  224. break;
  225. }
  226. cp[i] = '\0';
  227. }
  228. char *
  229. checkbuf (record, size)
  230. char *record;
  231. int size;
  232. {
  233. if (size <= maxrecsize)
  234. return (record);
  235. if (record != 0)
  236. free (record);
  237. record = malloc (size);
  238. if (record == 0)
  239. {
  240. DEBUG ("rmtd: cannot allocate buffer space\n");
  241. exit (4);
  242. }
  243. maxrecsize = size;
  244. #ifdef SO_RCVBUF
  245. while (size > 1024 &&
  246. setsockopt (0, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof (size)) < 0)
  247. size -= 1024;
  248. #else
  249. size = 1 + ((size - 1) % 1024);
  250. #endif
  251. return (record);
  252. }
  253. void
  254. error (num)
  255. int num;
  256. {
  257. DEBUG2 ("rmtd: E %d (%s)\n", num, sys_errlist[num]);
  258. (void) sprintf (resp, "E%d\n%s\n", num, sys_errlist[num]);
  259. (void) write (1, resp, strlen (resp));
  260. }