rmt.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 326 行
C
326 行
# ifndef lintstatic char *sccsid = "@(#)rmt.c 4.1 (ULTRIX) 7/2/90";# endif not lint/************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * * * Jeffrey M. Fries, 3-Nov-1986 * * Added SO_KEEPALIVE to force process abortion on network connect * * loss. * * * * Jeffrey M. Fries, 7-Feb-1986 * * Added O_CREAT to open to create files that do not exist * * * * Jeffrey M. Fries, 7-Feb-1986 * * Add comments to clarify code. * * * * David L Ballenger, 22-Apr-1985 * * 0001 Rename local gets() routine to getstr() to avoid conflicts * * with the gets() from <stdio.h>. * * * * * ************************************************************************//******************************************************** * Additional Information * * This code is started up after the 'rdump' code * * requests the remote shell to start up /etc/rmt * ********************************************************//* * rmt */#include <stdio.h>#include <sgtty.h>#include <sys/types.h>#include <sys/param.h>#include <sys/ioctl.h>#include <sys/devio.h>#include <sys/mtio.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/fs.h>#include <sys/socket.h>#include <syslog.h>#include <errno.h>#define MAXRECSIZ (10*1024) /* small enuf for pdp-11's too */#define RSIZE 64int tape = -1;char record[MAXRECSIZ];char device[RSIZE];char count[RSIZE], mode[RSIZE], pos[RSIZE], op[RSIZE];extern errno;extern char *sys_errlist[];char resp[BUFSIZ];long lseek();FILE *debug;/* Main Code Entry Point */main(argc, argv) int argc; char **argv;{ int rval; char c; int n, i, cc; int on = 1; /* Set Socket keep alive */ /* This kills the process should the socket */ /* get uncleanly shut down... */ if(setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0){ openlog(argv[0], LOG_PID); syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); closelog(); } argc--, argv++; if (argc > 0) { debug = fopen(*argv, "w"); if (debug == 0) exit(1); (void) setbuf(debug, (char *)0); }/* Top of Command Wait Loop */do{ errno = 0; rval = 0; /* Sit here waiting for the next command */ if (read(0, &c, 1) != 1) exit(0); /* Handle Command */ switch (c) { /* Close Remote System Dump Device */ case 'C':if (debug) fprintf(debug, "rmtd: C\n"); getstr(device); /* discard */ if (close(tape) < 0){ error(errno); break; } tape = -1; respond(rval); break; /* Get generic tape information of Remote */ /* device using DEVIOCGET "ioctl" call */ case 'D':if (debug) fprintf(debug, "rmtd: D\n"); { struct devget devinf; getstr(device); /* discard */ if (ioctl(tape, DEVIOCGET, (char *)&devinf) < 0){ error(errno); break; } rval = sizeof (devinf); respond(rval); (void) write(1, (char *)&devinf, sizeof (devinf)); break; } /* Perform an 'ioctl' on the Remote System dump device */ case 'I': getstr(op); getstr(count);if (debug) fprintf(debug, "rmtd: I %s %s\n", op, count); { struct mtop mtop; mtop.mt_op = atoi(op); mtop.mt_count = atoi(count); if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0){ error(errno); break; } rval = mtop.mt_count; respond(rval); break; } /* Perform an 'lseek' on Remote System Dump Drive */ case 'L': getstr(count); getstr(pos);if (debug) fprintf(debug, "rmtd: L %s %s\n", count, pos); rval = lseek(tape, (long) atoi(count), atoi(pos)); if (rval < 0){ error(errno); break; } respond(rval); break; /* Open Remote System Dump Device */ case 'O': if (tape >= 0) (void) close(tape); getstr(device); getstr(mode);if (debug) fprintf(debug, "rmtd: O %s %s\n", device, mode); tape = open(device, atoi(mode)|O_CREAT,0600); if (tape < 0){ error(errno); break; } respond(rval); break; /* Get disk partition information of Remote */ /* disk device using DIOCDGTPT "ioctl" call */ case 'P': /* partition info */if (debug) fprintf(debug, "rmtd: P\n"); { struct pt pt; getstr(device); /* discard */ if (ioctl(tape, DIOCDGTPT, (char *)&pt) < 0){ error(errno); break; } rval = sizeof (pt); respond(rval); (void) write(1, (char *)&pt, sizeof (pt)); break; } /* Perform a Read from the Remote System Dump Device */ case 'R': getstr(count);if (debug) fprintf(debug, "rmtd: R %s\n", count); n = atoi(count); if (n > sizeof (record)) n = sizeof (record); rval = read(tape, record, n); if (rval < 0){ error(errno); break; } respond(rval); (void) write(1, record, rval); break; /* Get status from the Remote System dump device */ case 'S': /* status */if (debug) fprintf(debug, "rmtd: S\n"); { struct mtget mtget; if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0){ error(errno); break; } rval = sizeof (mtget); respond(rval); (void) write(1, (char *)&mtget, sizeof (mtget)); break; } /* Perform "stat" on a Remote System file */ case 'T': /* status */if (debug) fprintf(debug, "rmtd: T\n"); { struct stat stat_buf; getstr(device); /* get name of file */ if (stat(device, (char *)&stat_buf) < 0){ error(errno); break; } rval = sizeof (stat_buf); respond(rval); (void) write(1, (char *)&stat_buf, sizeof (stat_buf)); break; } /* Perform a Write to the Remote System Dump Device */ case 'W': getstr(count); n = atoi(count);if (debug) fprintf(debug, "rmtd: W %s\n", count); for (i = 0; i < n; i += cc) { cc = read(0, &record[i], n - i); if (cc <= 0) {if (debug) fprintf(debug, "rmtd: premature eof\n"); exit(1); } } rval = write(tape, record, n); if (rval < 0){ error(errno); break; } respond(rval); break; /* Error command request */ default:if (debug) fprintf(debug, "rmtd: garbage command %c\n", c); exit(1); }}while(1);}/* Send response based on requested command */respond(rval) int rval;{if (debug) fprintf(debug, "rmtd: A %d\n", rval); (void) sprintf(resp, "A%d\n", rval); (void) write(1, resp, strlen(resp)); return;}/* Extract parts of a command using '\n' as a delimiter */getstr(bp) char *bp;{ int i; char *cp = bp; for (i = 0; i < RSIZE; i++) { if (read(0, cp+i, 1) != 1) exit(0); if (cp[i] == '\n') break; } cp[i] = '\0';}/* Performed when an Error occurs on I/O Operation */error(num) int num;{if (debug) fprintf(debug, "rmtd: E %d (%s)\n", num, sys_errlist[num]); (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]); (void) write(1, resp, strlen (resp));}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?