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