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