1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <auth.h> 5 6 char *dest = "system"; 7 int mountflag = MREPL; 8 9 void error(char *); 10 void rpc(int, int); 11 void post(char*, int); 12 void mountfs(char*, int); 13 14 void 15 usage(void) 16 { 17 fprint(2, "usage: %s [-abcCm] [net!]host [srvname [mtpt]]\n", argv0); 18 fprint(2, " or %s -e [-abcCm] command [srvname [mtpt]]\n", argv0); 19 20 exits("usage"); 21 } 22 23 void 24 ignore(void *a, char *c) 25 { 26 USED(a); 27 fprint(2, "%s\n", c); 28 if(strcmp(c, "alarm") == 0){ 29 fprint(2, "srv: timeout establishing connection to %s\n", dest); 30 exits("timeout"); 31 } 32 if(strstr(c, "write on closed pipe") == 0){ 33 fprint(2, "write on closed pipe\n"); 34 noted(NCONT); 35 } 36 noted(NDFLT); 37 } 38 39 int 40 connectcmd(char *cmd) 41 { 42 int p[2]; 43 44 if(pipe(p) < 0) 45 return -1; 46 switch(fork()){ 47 case -1: 48 fprint(2, "fork failed: %r\n"); 49 _exits("exec"); 50 case 0: 51 rfork(RFNOTEG); 52 dup(p[0], 0); 53 dup(p[0], 1); 54 close(p[1]); 55 execl("/bin/rc", "rc", "-c", cmd, nil); 56 fprint(2, "exec failed: %r\n"); 57 _exits("exec"); 58 default: 59 close(p[0]); 60 return p[1]; 61 } 62 } 63 64 void 65 main(int argc, char *argv[]) 66 { 67 int fd, doexec; 68 char srv[64], mtpt[64]; 69 char dir[1024]; 70 char err[ERRMAX]; 71 char *p, *p2; 72 int domount, reallymount, try, sleeptime; 73 74 notify(ignore); 75 76 domount = 0; 77 reallymount = 0; 78 doexec = 0; 79 sleeptime = 0; 80 81 ARGBEGIN{ 82 case 'a': 83 mountflag |= MAFTER; 84 domount = 1; 85 reallymount = 1; 86 break; 87 case 'b': 88 mountflag |= MBEFORE; 89 domount = 1; 90 reallymount = 1; 91 break; 92 case 'c': 93 mountflag |= MCREATE; 94 domount = 1; 95 reallymount = 1; 96 break; 97 case 'C': 98 mountflag |= MCACHE; 99 domount = 1; 100 reallymount = 1; 101 break; 102 case 'e': 103 doexec = 1; 104 break; 105 case 'm': 106 domount = 1; 107 reallymount = 1; 108 break; 109 case 'q': 110 domount = 1; 111 reallymount = 0; 112 break; 113 case 'r': 114 /* deprecated -r flag; ignored for compatibility */ 115 break; 116 case 's': 117 sleeptime = atoi(EARGF(usage())); 118 break; 119 default: 120 usage(); 121 break; 122 }ARGEND 123 124 if((mountflag&MAFTER)&&(mountflag&MBEFORE)) 125 usage(); 126 127 switch(argc){ 128 case 1: /* calculate srv and mtpt from address */ 129 p = strrchr(argv[0], '/'); 130 p = p ? p+1 : argv[0]; 131 snprint(srv, sizeof(srv), "/srv/%.28s", p); 132 p2 = strchr(p, '!'); 133 p2 = p2 ? p2+1 : p; 134 snprint(mtpt, sizeof(mtpt), "/n/%.28s", p2); 135 break; 136 case 2: /* calculate mtpt from address, srv given */ 137 snprint(srv, sizeof(srv), "/srv/%.28s", argv[1]); 138 p = strrchr(argv[0], '/'); 139 p = p ? p+1 : argv[0]; 140 p2 = strchr(p, '!'); 141 p2 = p2 ? p2+1 : p; 142 snprint(mtpt, sizeof(mtpt), "/n/%.28s", p2); 143 break; 144 case 3: /* srv and mtpt given */ 145 domount = 1; 146 reallymount = 1; 147 snprint(srv, sizeof(srv), "/srv/%.28s", argv[1]); 148 snprint(mtpt, sizeof(mtpt), "%.28s", argv[2]); 149 break; 150 default: 151 usage(); 152 } 153 154 try = 0; 155 dest = *argv; 156 Again: 157 try++; 158 159 if(access(srv, 0) == 0){ 160 if(domount){ 161 fd = open(srv, ORDWR); 162 if(fd >= 0) 163 goto Mount; 164 remove(srv); 165 } 166 else{ 167 fprint(2, "srv: %s already exists\n", srv); 168 exits(0); 169 } 170 } 171 172 alarm(10000); 173 if(doexec) 174 fd = connectcmd(dest); 175 else{ 176 dest = netmkaddr(dest, 0, "9fs"); 177 fd = dial(dest, 0, dir, 0); 178 } 179 if(fd < 0) { 180 fprint(2, "srv: dial %s: %r\n", dest); 181 exits("dial"); 182 } 183 alarm(0); 184 185 if(sleeptime){ 186 fprint(2, "sleep..."); 187 sleep(sleeptime*1000); 188 } 189 190 post(srv, fd); 191 192 Mount: 193 if(domount == 0 || reallymount == 0) 194 exits(0); 195 196 if(amount(fd, mtpt, mountflag, "") < 0){ 197 err[0] = 0; 198 errstr(err, sizeof err); 199 if(strstr(err, "Hangup") || strstr(err, "hungup") || strstr(err, "timed out")){ 200 remove(srv); 201 if(try == 1) 202 goto Again; 203 } 204 fprint(2, "srv %s: mount failed: %s\n", dest, err); 205 exits("mount"); 206 } 207 exits(0); 208 } 209 210 void 211 post(char *srv, int fd) 212 { 213 int f; 214 char buf[128]; 215 216 fprint(2, "post...\n"); 217 f = create(srv, OWRITE, 0666); 218 if(f < 0){ 219 sprint(buf, "create(%s)", srv); 220 error(buf); 221 } 222 sprint(buf, "%d", fd); 223 if(write(f, buf, strlen(buf)) != strlen(buf)) 224 error("write"); 225 } 226 227 void 228 error(char *s) 229 { 230 fprint(2, "srv %s: %s: %r\n", dest, s); 231 exits("srv: error"); 232 } 233