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