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