srv.c 3.8 KB

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