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