listen1.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. int verbose;
  5. int trusted;
  6. void
  7. usage(void)
  8. {
  9. fprint(2, "usage: listen1 [-tv] address cmd args...\n");
  10. exits("usage");
  11. }
  12. void
  13. becomenone(void)
  14. {
  15. int fd;
  16. fd = open("#c/user", OWRITE);
  17. if(fd < 0 || write(fd, "none", strlen("none")) < 0)
  18. sysfatal("can't become none: %r");
  19. close(fd);
  20. if(newns("none", nil) < 0)
  21. sysfatal("can't build namespace: %r");
  22. }
  23. char*
  24. remoteaddr(char *dir)
  25. {
  26. static char buf[128];
  27. char *p;
  28. int n, fd;
  29. snprint(buf, sizeof buf, "%s/remote", dir);
  30. fd = open(buf, OREAD);
  31. if(fd < 0)
  32. return "";
  33. n = read(fd, buf, sizeof(buf));
  34. close(fd);
  35. if(n > 0){
  36. buf[n] = 0;
  37. p = strchr(buf, '!');
  38. if(p)
  39. *p = 0;
  40. return buf;
  41. }
  42. return "";
  43. }
  44. void
  45. main(int argc, char **argv)
  46. {
  47. char data[60], dir[40], ndir[40];
  48. int ctl, nctl, fd;
  49. ARGBEGIN{
  50. default:
  51. usage();
  52. case 't':
  53. trusted = 1;
  54. break;
  55. case 'v':
  56. verbose = 1;
  57. break;
  58. }ARGEND
  59. if(argc < 2)
  60. usage();
  61. if(!verbose){
  62. close(1);
  63. fd = open("/dev/null", OWRITE);
  64. if(fd != 1){
  65. dup(fd, 1);
  66. close(fd);
  67. }
  68. }
  69. if(!trusted)
  70. becomenone();
  71. print("listen started\n");
  72. ctl = announce(argv[0], dir);
  73. if(ctl < 0)
  74. sysfatal("announce %s: %r", argv[0]);
  75. for(;;){
  76. nctl = listen(dir, ndir);
  77. if(nctl < 0)
  78. sysfatal("listen %s: %r", argv[0]);
  79. switch(rfork(RFFDG|RFPROC|RFNOWAIT|RFENVG|RFNAMEG|RFNOTEG)){
  80. case -1:
  81. reject(ctl, ndir, "host overloaded");
  82. close(nctl);
  83. continue;
  84. case 0:
  85. fd = accept(ctl, ndir);
  86. if(fd < 0){
  87. fprint(2, "accept %s: can't open %s/data: %r", argv[0], ndir);
  88. _exits(0);
  89. }
  90. print("incoming call for %s from %s in %s\n", argv[0], remoteaddr(ndir), ndir);
  91. fprint(nctl, "keepalive");
  92. close(ctl);
  93. close(nctl);
  94. putenv("net", ndir);
  95. sprint(data, "%s/data", ndir);
  96. bind(data, "/dev/cons", MREPL);
  97. dup(fd, 0);
  98. dup(fd, 1);
  99. dup(fd, 2);
  100. close(fd);
  101. exec(argv[1], argv+1);
  102. fprint(2, "exec: %r");
  103. exits(nil);
  104. default:
  105. close(nctl);
  106. break;
  107. }
  108. }
  109. exits(nil);
  110. }