srv.c 4.3 KB

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