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