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