1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)dumprmt.c 5.1 (Berkeley) 06/05/85"; 9 #endif not lint 10 11 #include <sys/param.h> 12 #include <sys/mtio.h> 13 #include <sys/ioctl.h> 14 #include <sys/socket.h> 15 #include <sys/inode.h> 16 17 #include <netinet/in.h> 18 19 #include <stdio.h> 20 #include <pwd.h> 21 #include <netdb.h> 22 #include <dumprestor.h> 23 24 #define TS_CLOSED 0 25 #define TS_OPEN 1 26 27 static int rmtstate = TS_CLOSED; 28 int rmtape; 29 int rmtconnaborted(); 30 char *rmtpeer; 31 32 extern int ntrec; /* blocking factor on tape */ 33 34 rmthost(host) 35 char *host; 36 { 37 38 rmtpeer = host; 39 signal(SIGPIPE, rmtconnaborted); 40 rmtgetconn(); 41 if (rmtape < 0) 42 return (0); 43 return (1); 44 } 45 46 rmtconnaborted() 47 { 48 49 fprintf(stderr, "rdump: Lost connection to remote host.\n"); 50 exit(1); 51 } 52 53 rmtgetconn() 54 { 55 static struct servent *sp = 0; 56 struct passwd *pw; 57 char *name = "root"; 58 int size; 59 60 if (sp == 0) { 61 sp = getservbyname("shell", "tcp"); 62 if (sp == 0) { 63 fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 64 exit(1); 65 } 66 } 67 pw = getpwuid(getuid()); 68 if (pw && pw->pw_name) 69 name = pw->pw_name; 70 rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "/etc/rmt", 0); 71 #ifdef notdef /* broken */ 72 size = ntrec * TP_BSIZE; 73 while (size > TP_BSIZE && 74 setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 75 size -= TP_BSIZE; 76 #endif notdef 77 } 78 79 rmtopen(tape, mode) 80 char *tape; 81 int mode; 82 { 83 char buf[256]; 84 85 sprintf(buf, "O%s\n%d\n", tape, mode); 86 rmtcall(tape, buf); 87 rmtstate = TS_OPEN; 88 } 89 90 rmtclose() 91 { 92 93 if (rmtstate != TS_OPEN) 94 return; 95 rmtcall("close", "C\n"); 96 rmtstate = TS_CLOSED; 97 } 98 99 rmtread(buf, count) 100 char *buf; 101 int count; 102 { 103 char line[30]; 104 int n, i, cc; 105 extern errno; 106 107 sprintf(line, "R%d\n", count); 108 n = rmtcall("read", line); 109 if (n < 0) { 110 errno = n; 111 return (-1); 112 } 113 for (i = 0; i < n; i += cc) { 114 cc = read(rmtape, buf+i, n - i); 115 if (cc <= 0) { 116 rmtconnaborted(); 117 } 118 } 119 return (n); 120 } 121 122 rmtwrite(buf, count) 123 char *buf; 124 int count; 125 { 126 char line[30]; 127 128 sprintf(line, "W%d\n", count); 129 write(rmtape, line, strlen(line)); 130 write(rmtape, buf, count); 131 return (rmtreply("write")); 132 } 133 134 rmtwrite0(count) 135 int count; 136 { 137 char line[30]; 138 139 sprintf(line, "W%d\n", count); 140 write(rmtape, line, strlen(line)); 141 } 142 143 rmtwrite1(buf, count) 144 char *buf; 145 int count; 146 { 147 148 write(rmtape, buf, count); 149 } 150 151 rmtwrite2() 152 { 153 int i; 154 155 return (rmtreply("write")); 156 } 157 158 rmtseek(offset, pos) 159 int offset, pos; 160 { 161 char line[80]; 162 163 sprintf(line, "L%d\n%d\n", offset, pos); 164 return (rmtcall("seek", line)); 165 } 166 167 struct mtget mts; 168 169 struct mtget * 170 rmtstatus() 171 { 172 register int i; 173 register char *cp; 174 175 if (rmtstate != TS_OPEN) 176 return (0); 177 rmtcall("status", "S\n"); 178 for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 179 *cp++ = rmtgetb(); 180 return (&mts); 181 } 182 183 rmtioctl(cmd, count) 184 int cmd, count; 185 { 186 char buf[256]; 187 188 if (count < 0) 189 return (-1); 190 sprintf(buf, "I%d\n%d\n", cmd, count); 191 return (rmtcall("ioctl", buf)); 192 } 193 194 rmtcall(cmd, buf) 195 char *cmd, *buf; 196 { 197 198 if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 199 rmtconnaborted(); 200 return (rmtreply(cmd)); 201 } 202 203 rmtreply(cmd) 204 char *cmd; 205 { 206 register int c; 207 char code[30], emsg[BUFSIZ]; 208 209 rmtgets(code, sizeof (code)); 210 if (*code == 'E' || *code == 'F') { 211 rmtgets(emsg, sizeof (emsg)); 212 msg("%s: %s\n", cmd, emsg, code + 1); 213 if (*code == 'F') { 214 rmtstate = TS_CLOSED; 215 return (-1); 216 } 217 return (-1); 218 } 219 if (*code != 'A') { 220 msg("Protocol to remote tape server botched (code %s?).\n", 221 code); 222 rmtconnaborted(); 223 } 224 return (atoi(code + 1)); 225 } 226 227 rmtgetb() 228 { 229 char c; 230 231 if (read(rmtape, &c, 1) != 1) 232 rmtconnaborted(); 233 return (c); 234 } 235 236 rmtgets(cp, len) 237 char *cp; 238 int len; 239 { 240 241 while (len > 1) { 242 *cp = rmtgetb(); 243 if (*cp == '\n') { 244 cp[1] = 0; 245 return; 246 } 247 cp++; 248 len--; 249 } 250 msg("Protocol to remote tape server botched (in rmtgets).\n"); 251 rmtconnaborted(); 252 } 253