srv.c 3.9 KB

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