home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / rfs / part6 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  56.2 KB

  1. Subject: RFS: remote file system (part 6 of 7)
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 3, Issue 82
  6. Submitted by: tektronix!tekcrl!toddb
  7.  
  8. #!/bin/sh
  9. #
  10. # RFS, a kernel-resident remote file system.  Shar 6 of 7
  11. #
  12. #
  13. # This is a shell archive, meaning:
  14. # 1. Remove everything above the #!/bin/sh line.
  15. # 2. Save the resulting text in a file.
  16. # 3. Execute the file with /bin/sh (not csh) to create the files:
  17. #    remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
  18. #    remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
  19. #    remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
  20. #    remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
  21. #    remote/usr.sys.remote
  22. #    remote/usr.sys.remote/remote_mkdata
  23. #    remote/usr.sys.remote/remotefs.h
  24. #    remote/usr.sys.remote/rmt_data_template
  25. #    remote/usr.sys.remote/rmt_exec.c
  26. #    remote/usr.sys.remote/rmt_final.c
  27. #    remote/usr.sys.remote/rmt_syscall3.c
  28. #
  29. # remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
  30. #
  31. if [ -f remote/usr.sys.VAX4.3/sys/kern_exec.c.diff ]; then 
  32.     echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/kern_exec.c.diff or ^C to quit' 
  33.     read ans 
  34.     rm -f remote/usr.sys.VAX4.3/sys/kern_exec.c.diff 
  35. fi 
  36.  
  37. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
  38. XThe following changes implement local execution of an object file that
  39. Xlives on another host.
  40. X***************
  41. X*** 27,32
  42. X  #include "acct.h"
  43. X  #include "exec.h"
  44. X  
  45. X  #ifdef vax
  46. X  #include "../vax/mtpr.h"
  47. X  #endif
  48. X
  49. X--- 27,36 -----
  50. X  #include "acct.h"
  51. X  #include "exec.h"
  52. X  
  53. X+ #ifdef REMOTEFS
  54. X+ #include "../h/errno.h"
  55. X+ #endif REMOTEFS
  56. X+ 
  57. X  #ifdef vax
  58. X  #include "../vax/mtpr.h"
  59. X  #endif
  60. X***************
  61. X*** 55,61
  62. X      int na, ne, ucp, ap, len, cc;
  63. X      int indir, uid, gid;
  64. X      char *sharg;
  65. X!     struct inode *ip;
  66. X      swblk_t bno;
  67. X      char cfname[MAXCOMLEN + 1];
  68. X  #define    SHSIZE    32
  69. X
  70. X--- 59,70 -----
  71. X      int na, ne, ucp, ap, len, cc;
  72. X      int indir, uid, gid;
  73. X      char *sharg;
  74. X! #ifdef REMOTEFS
  75. X!     struct inode *ip; /* have to take address */
  76. X!     int    remote = -1;
  77. X! #else REMOTEFS
  78. X!     register struct inode *ip;
  79. X! #endif REMOTEFS
  80. X      swblk_t bno;
  81. X      char cfname[MAXCOMLEN + 1];
  82. X  #define    SHSIZE    32
  83. X***************
  84. X*** 71,76
  85. X      ndp->ni_segflg = UIO_USERSPACE;
  86. X      ndp->ni_dirp = ((struct execa *)u.u_ap)->fname;
  87. X      if ((ip = namei(ndp)) == NULL)
  88. X          return;
  89. X      bno = 0;
  90. X      bp = 0;
  91. X
  92. X--- 80,91 -----
  93. X      ndp->ni_segflg = UIO_USERSPACE;
  94. X      ndp->ni_dirp = ((struct execa *)u.u_ap)->fname;
  95. X      if ((ip = namei(ndp)) == NULL)
  96. X+ #ifdef REMOTEFS
  97. X+         if (u.u_error == EISREMOTE)
  98. X+             remote = remote_execinfo(&ip, &uid, &gid,
  99. X+                 &exdata, ((struct execa *)u.u_ap)->fname);
  100. X+     if (u.u_error)
  101. X+ #endif REMOTEFS
  102. X          return;
  103. X      bno = 0;
  104. X      bp = 0;
  105. X***************
  106. X*** 75,80
  107. X      bno = 0;
  108. X      bp = 0;
  109. X      indir = 0;
  110. X      uid = u.u_uid;
  111. X      gid = u.u_gid;
  112. X      if (ip->i_mode & ISUID)
  113. X
  114. X--- 90,99 -----
  115. X      bno = 0;
  116. X      bp = 0;
  117. X      indir = 0;
  118. X+ 
  119. X+ #ifdef REMOTEFS
  120. X+ if (remote < 0) {
  121. X+ #endif REMOTEFS
  122. X      uid = u.u_uid;
  123. X      gid = u.u_gid;
  124. X      if (ip->i_mode & ISUID)
  125. X***************
  126. X*** 112,117
  127. X          0, 1, &resid);
  128. X      if (u.u_error)
  129. X          goto bad;
  130. X  #ifndef lint
  131. X      if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
  132. X          exdata.ex_shell[0] != '#') {
  133. X
  134. X--- 131,143 -----
  135. X          0, 1, &resid);
  136. X      if (u.u_error)
  137. X          goto bad;
  138. X+ #ifdef REMOTEFS
  139. X+ }
  140. X+ 
  141. X+ remote_again:
  142. X+ 
  143. X+ #endif REMOTEFS
  144. X+ 
  145. X  #ifndef lint
  146. X      if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
  147. X          exdata.ex_shell[0] != '#') {
  148. X***************
  149. X*** 170,176
  150. X                  bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
  151. X          }
  152. X          indir = 1;
  153. X!         iput(ip);
  154. X          ndp->ni_nameiop = LOOKUP | FOLLOW;
  155. X          ndp->ni_segflg = UIO_SYSSPACE;
  156. X          ip = namei(ndp);
  157. X
  158. X--- 196,205 -----
  159. X                  bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
  160. X          }
  161. X          indir = 1;
  162. X! #ifdef REMOTEFS
  163. X!         if (remote < 0)
  164. X! #endif REMOTEFS
  165. X!             iput(ip);
  166. X          ndp->ni_nameiop = LOOKUP | FOLLOW;
  167. X          ndp->ni_segflg = UIO_SYSSPACE;
  168. X          ip = namei(ndp);
  169. X***************
  170. X*** 174,179
  171. X          ndp->ni_nameiop = LOOKUP | FOLLOW;
  172. X          ndp->ni_segflg = UIO_SYSSPACE;
  173. X          ip = namei(ndp);
  174. X          if (ip == NULL)
  175. X              return;
  176. X          bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
  177. X
  178. X--- 203,220 -----
  179. X          ndp->ni_nameiop = LOOKUP | FOLLOW;
  180. X          ndp->ni_segflg = UIO_SYSSPACE;
  181. X          ip = namei(ndp);
  182. X+ #ifdef REMOTEFS
  183. X+         if (ip == NULL) {
  184. X+             if (u.u_error == EISREMOTE)
  185. X+                 remote = remote_execinfo(&ip, 0, 0, 0);
  186. X+             if (u.u_error)
  187. X+                 return;
  188. X+             if (ip == NULL)
  189. X+                 goto remote_again;
  190. X+         }
  191. X+         else
  192. X+             remote = -1;
  193. X+ #else REMOTEFS
  194. X          if (ip == NULL)
  195. X              return;
  196. X  #endif REMOTEFS
  197. X***************
  198. X*** 176,181
  199. X          ip = namei(ndp);
  200. X          if (ip == NULL)
  201. X              return;
  202. X          bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
  203. X              MAXCOMLEN);
  204. X          cfname[MAXCOMLEN] = '\0';
  205. X
  206. X--- 217,223 -----
  207. X  #else REMOTEFS
  208. X          if (ip == NULL)
  209. X              return;
  210. X+ #endif REMOTEFS
  211. X          bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
  212. X              MAXCOMLEN);
  213. X          cfname[MAXCOMLEN] = '\0';
  214. X***************
  215. X*** 268,274
  216. X          bdwrite(bp);
  217. X      bp = 0;
  218. X      nc = (nc + NBPW-1) & ~(NBPW-1);
  219. X!     getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid);
  220. X      if (u.u_error) {
  221. X  badarg:
  222. X          for (cc = 0; cc < nc; cc += CLSIZE*NBPG) {
  223. X
  224. X--- 310,322 -----
  225. X          bdwrite(bp);
  226. X      bp = 0;
  227. X      nc = (nc + NBPW-1) & ~(NBPW-1);
  228. X! 
  229. X! #ifdef REMOTEFS
  230. X!         getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid, remote);
  231. X! #else REMOTEFS
  232. X!         getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid);
  233. X! #endif REMOTEFS
  234. X! 
  235. X      if (u.u_error) {
  236. X  badarg:
  237. X          for (cc = 0; cc < nc; cc += CLSIZE*NBPG) {
  238. X***************
  239. X*** 376,381
  240. X  /*
  241. X   * Read in and set up memory for executed file.
  242. X   */
  243. X  getxfile(ip, ep, nargc, uid, gid)
  244. X      register struct inode *ip;
  245. X      register struct exec *ep;
  246. X
  247. X--- 424,432 -----
  248. X  /*
  249. X   * Read in and set up memory for executed file.
  250. X   */
  251. X+ #ifdef REMOTEFS
  252. X+ getxfile(ip, ep, nargc, uid, gid, remote)
  253. X+ #else REMOTEFS
  254. X  getxfile(ip, ep, nargc, uid, gid)
  255. X  #endif REMOTEFS
  256. X      register struct inode *ip;
  257. X***************
  258. X*** 377,382
  259. X   * Read in and set up memory for executed file.
  260. X   */
  261. X  getxfile(ip, ep, nargc, uid, gid)
  262. X      register struct inode *ip;
  263. X      register struct exec *ep;
  264. X      int nargc, uid, gid;
  265. X
  266. X--- 428,434 -----
  267. X  getxfile(ip, ep, nargc, uid, gid, remote)
  268. X  #else REMOTEFS
  269. X  getxfile(ip, ep, nargc, uid, gid)
  270. X+ #endif REMOTEFS
  271. X      register struct inode *ip;
  272. X      register struct exec *ep;
  273. X      int nargc, uid, gid;
  274. X***************
  275. X*** 383,388
  276. X  {
  277. X      size_t ts, ds, ids, uds, ss;
  278. X      int pagi;
  279. X  
  280. X      if (ep->a_magic == 0413)
  281. X          pagi = SPAGI;
  282. X
  283. X--- 435,443 -----
  284. X  {
  285. X      size_t ts, ds, ids, uds, ss;
  286. X      int pagi;
  287. X+ #ifdef REMOTEFS
  288. X+     int    oldtextsize;
  289. X+ #endif REMOTEFS
  290. X  
  291. X      if (ep->a_magic == 0413)
  292. X          pagi = SPAGI;
  293. X***************
  294. X*** 388,393
  295. X          pagi = SPAGI;
  296. X      else
  297. X          pagi = 0;
  298. X      if (ip->i_flag & IXMOD) {            /* XXX */
  299. X          u.u_error = ETXTBSY;
  300. X          goto bad;
  301. X
  302. X--- 443,459 -----
  303. X          pagi = SPAGI;
  304. X      else
  305. X          pagi = 0;
  306. X+ #ifdef REMOTEFS
  307. X+     if (remote >= 0) {
  308. X+         /*
  309. X+          * Prevent xalloc() from making a shared or paged text.
  310. X+          */
  311. X+         pagi = 0;
  312. X+         oldtextsize = ep->a_text;
  313. X+         ep->a_data += ep->a_text;
  314. X+         ep->a_text = 0;
  315. X+     }
  316. X+ #endif REMOTEFS
  317. X      if (ip->i_flag & IXMOD) {            /* XXX */
  318. X          u.u_error = ETXTBSY;
  319. X          goto bad;
  320. X***************
  321. X*** 452,457
  322. X      u.u_smap = u.u_csmap;
  323. X      vgetvm(ts, ds, ss);
  324. X  
  325. X      if (pagi == 0)
  326. X          u.u_error =
  327. X              rdwri(UIO_READ, ip,
  328. X
  329. X--- 518,528 -----
  330. X      u.u_smap = u.u_csmap;
  331. X      vgetvm(ts, ds, ss);
  332. X  
  333. X+ #ifdef REMOTEFS
  334. X+     if (remote >= 0)
  335. X+         u.u_error = remote_execread(remote, oldtextsize, ep);
  336. X+     else
  337. X+ #endif REMOTEFS
  338. X      if (pagi == 0)
  339. X          u.u_error =
  340. X              rdwri(UIO_READ, ip,
  341. SHAREOF
  342. chmod 664 remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
  343. #
  344. # remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
  345. #
  346. if [ -f remote/usr.sys.VAX4.3/sys/kern_exit.c.diff ]; then 
  347.     echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/kern_exit.c.diff or ^C to quit' 
  348.     read ans 
  349.     rm -f remote/usr.sys.VAX4.3/sys/kern_exit.c.diff 
  350. fi 
  351.  
  352. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
  353. XThe following changes ensure that upon exit, a process notifies any remote
  354. Xservers that may know about him, that he is indeed dead.
  355. X***************
  356. X*** 23,28
  357. X  #include "mbuf.h"
  358. X  #include "inode.h"
  359. X  #include "syslog.h"
  360. X  
  361. X  /*
  362. X   * Exit system call: pass back caller's arg
  363. X
  364. X--- 23,31 -----
  365. X  #include "mbuf.h"
  366. X  #include "inode.h"
  367. X  #include "syslog.h"
  368. X+ #ifdef REMOTEFS
  369. X+ #include "../remote/remotefs.h"
  370. X+ #endif REMOTEFS
  371. X  
  372. X  /*
  373. X   * Exit system call: pass back caller's arg
  374. X***************
  375. X*** 56,61
  376. X      vmsizmon();
  377. X  #endif
  378. X      p = u.u_procp;
  379. X      p->p_flag &= ~(STRC|SULOCK);
  380. X      p->p_flag |= SWEXIT;
  381. X      p->p_sigignore = ~0;
  382. X
  383. X--- 59,71 -----
  384. X      vmsizmon();
  385. X  #endif
  386. X      p = u.u_procp;
  387. X+ #ifdef REMOTEFS
  388. X+     /*
  389. X+      * First, release our server.
  390. X+      */
  391. X+     if (p->p_flag & SREMOTE)
  392. X+         remote_exit();
  393. X+ #endif REMOTEFS
  394. X      p->p_flag &= ~(STRC|SULOCK);
  395. X      p->p_flag |= SWEXIT;
  396. X      p->p_sigignore = ~0;
  397. SHAREOF
  398. chmod 664 remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
  399. #
  400. # remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
  401. #
  402. if [ -f remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff ]; then 
  403.     echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff or ^C to quit' 
  404.     read ans 
  405.     rm -f remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff 
  406. fi 
  407.  
  408. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
  409. XThese changes are the primary hook into the operating system for detecting
  410. Xa "remote" file.
  411. X***************
  412. X*** 149,154
  413. X      int isdotdot;            /* != 0 if current name is ".." */
  414. X      int flag;            /* op ie, LOOKUP, CREATE, or DELETE */
  415. X      off_t enduseful;        /* pointer past last used dir slot */
  416. X  
  417. X      lockparent = ndp->ni_nameiop & LOCKPARENT;
  418. X      docache = (ndp->ni_nameiop & NOCACHE) ^ NOCACHE;
  419. X
  420. X--- 149,157 -----
  421. X      int isdotdot;            /* != 0 if current name is ".." */
  422. X      int flag;            /* op ie, LOOKUP, CREATE, or DELETE */
  423. X      off_t enduseful;        /* pointer past last used dir slot */
  424. X+ #ifdef REMOTEFS
  425. X+     int remote;
  426. X+ #endif
  427. X  
  428. X      lockparent = ndp->ni_nameiop & LOCKPARENT;
  429. X      docache = (ndp->ni_nameiop & NOCACHE) ^ NOCACHE;
  430. X***************
  431. X*** 202,207
  432. X       * Check accessiblity of directory.
  433. X       */
  434. X      if ((dp->i_mode&IFMT) != IFDIR) {
  435. X          u.u_error = ENOTDIR;
  436. X          goto bad;
  437. X      }
  438. X
  439. X--- 205,226 -----
  440. X       * Check accessiblity of directory.
  441. X       */
  442. X      if ((dp->i_mode&IFMT) != IFDIR) {
  443. X+ #ifdef REMOTEFS
  444. X+         remote = isremote(dp, cp, nbp->b_un.b_addr);
  445. X+         /*
  446. X+          * If it is really local, then start again at the root.
  447. X+          */
  448. X+         if (remote < 0) {
  449. X+             iput(dp);
  450. X+             dp = rootdir;
  451. X+             ILOCK(dp);
  452. X+             dp->i_count++;
  453. X+             fs = dp->i_fs;
  454. X+             cp = nbp->b_un.b_addr;
  455. X+             goto dirloop2;
  456. X+         }
  457. X+         else if (! remote)
  458. X+ #endif REMOTEFS
  459. X          u.u_error = ENOTDIR;
  460. X          goto bad;
  461. X      }
  462. X***************
  463. X*** 642,647
  464. X                      u.u_error = EPERM;
  465. X                      goto bad;
  466. X                  }
  467. X              }
  468. X          }
  469. X          nbp->av_forw = freenamebuf;
  470. X
  471. X--- 661,677 -----
  472. X                      u.u_error = EPERM;
  473. X                      goto bad;
  474. X                  }
  475. X+ #ifdef REMOTEFS
  476. X+                 /*
  477. X+                  * don't allow anyone to remove a remote mount
  478. X+                  * point.
  479. X+                  */
  480. X+                 if (rmt_host(dp, &i)) {
  481. X+                     iput(ndp->ni_pdir);
  482. X+                     u.u_error = EBUSY;
  483. X+                     goto bad;
  484. X+                 }
  485. X+ #endif REMOTEFS
  486. X              }
  487. X          }
  488. X          nbp->av_forw = freenamebuf;
  489. SHAREOF
  490. chmod 664 remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
  491. #
  492. # remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
  493. #
  494. if [ -f remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff ]; then 
  495.     echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff or ^C to quit' 
  496.     read ans 
  497.     rm -f remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff 
  498. fi 
  499.  
  500. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
  501. XThese changes modify chdirec(), which is called by chroot() and chdir(),
  502. Xso that you can be allowed to do a chdir() to a remote mount point.
  503. XIn addition, the changes ensure that we adjust internal pointers when doing
  504. Xa chdir() OUT of a remote mount point.
  505. X
  506. X***************
  507. X*** 51,56
  508. X  chdirec(ipp)
  509. X      register struct inode **ipp;
  510. X  {
  511. X      register struct inode *ip;
  512. X      struct a {
  513. X          char    *fname;
  514. X
  515. X--- 51,59 -----
  516. X  chdirec(ipp)
  517. X      register struct inode **ipp;
  518. X  {
  519. X+ #ifdef REMOTEFS
  520. X+     int    i;
  521. X+ #endif REMOTEFS
  522. X      register struct inode *ip;
  523. X      struct a {
  524. X          char    *fname;
  525. X***************
  526. X*** 64,69
  527. X      if (ip == NULL)
  528. X          return;
  529. X      if ((ip->i_mode&IFMT) != IFDIR) {
  530. X          u.u_error = ENOTDIR;
  531. X          goto bad;
  532. X      }
  533. X
  534. X--- 67,77 -----
  535. X      if (ip == NULL)
  536. X          return;
  537. X      if ((ip->i_mode&IFMT) != IFDIR) {
  538. X+ #ifdef REMOTEFS
  539. X+         if (rmt_hostdir(ip, &i) != NULL)
  540. X+             u.u_error = remotechdir(i);
  541. X+         else
  542. X+ #endif REMOTEFS
  543. X          u.u_error = ENOTDIR;
  544. X          goto bad;
  545. X      }
  546. X***************
  547. X*** 69,74
  548. X      }
  549. X      if (access(ip, IEXEC))
  550. X          goto bad;
  551. X      IUNLOCK(ip);
  552. X      if (*ipp)
  553. X          irele(*ipp);
  554. X
  555. X--- 77,85 -----
  556. X      }
  557. X      if (access(ip, IEXEC))
  558. X          goto bad;
  559. X+ #ifdef REMOTEFS
  560. X+     remotechdir(-1);
  561. X+ #endif REMOTEFS
  562. X      IUNLOCK(ip);
  563. X      if (*ipp)
  564. X          irele(*ipp);
  565. SHAREOF
  566. chmod 664 remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
  567. #
  568. # remote/usr.sys.remote
  569. #
  570. mkdir remote/usr.sys.remote
  571. chmod 775 remote/usr.sys.remote
  572. #
  573. # remote/usr.sys.remote/remote_mkdata
  574. #
  575. if [ -f remote/usr.sys.remote/remote_mkdata ]; then 
  576.     echo -n 'Hit <return> to overwrite remote/usr.sys.remote/remote_mkdata or ^C to quit' 
  577.     read ans 
  578.     rm -f remote/usr.sys.remote/remote_mkdata 
  579. fi 
  580.  
  581. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/remote_mkdata
  582. X#!/bin/sh
  583. X# 
  584. X#  Copyright 1985, Todd Brunhoff.
  585. X# 
  586. X#  This software was written at Tektronix Computer Research Laboratories
  587. X#  as partial fulfillment of a Master's degree at the University of Denver.
  588. X#  This software is not Tektronix proprietary software and should not be
  589. X#  confused with any software product sold by Tektronix.  No warranty is
  590. X#  expressed or implied on the reliability of this software; the author,
  591. X#  the University of Denver, and Tektronix, inc. accept no liability for
  592. X#  any damage done directly or indirectly by this software.  This software
  593. X#  may be copied, modified or used in any way, without fee, provided this
  594. X#  comment remains an unaltered part of the software.
  595. X#
  596. X
  597. Xif [ ! -f "$1" ]
  598. Xthen
  599. X    echo "Usage:"
  600. X    echo "    /lib/cpp -DKERNEL ... ..../init_sysent.c | $0 ..../remotefs.h"
  601. X    exit 1
  602. Xfi
  603. X
  604. XREMOTE=$1
  605. X
  606. X#
  607. X# First, get the complete list of remote system calls and put them
  608. X# into memory for awk.
  609. X#
  610. XMEM=`sed -e '/^#define[     ]*RSYS_/!d' \
  611. X    -e 's/.*RSYS_\([^     ]*\)    \([0-9]*\)$/mem[\2]="\1";last=\2;/' \
  612. X    < $REMOTE`
  613. X#
  614. X# Then, compile a list of all system calls from a cpp expanded listing
  615. X# of sys/init_sysent.c which should be on standard input.
  616. X# The only kludge here is that we must change internal names for system
  617. X# calls:
  618. X#      internal          changed
  619. X#    name         to
  620. X#     ----------     ----------
  621. X#    rexit        exit
  622. X#    saccess        access
  623. X#
  624. Xsed    -e '1,/^struct[     ]*sysent[     ]*sysent[     ]*\[\]/d' \
  625. X    -e '/^};/,$d' \
  626. X    -e '/^#/d' \
  627. X    -e 's/    *[0-9], *//' \
  628. X    -e 's/,.*//' \
  629. X    -e 's/^rexit$/exit/' \
  630. X    -e 's/^saccess$/access/' \
  631. X    -e '/^[     ]*$/d' \
  632. X| tail +2 \
  633. X| cat -n \
  634. X| awk '
  635. XBEGIN {
  636. X    '"$MEM"'
  637. X    syscall = 0;
  638. X    column = 0;
  639. X    printf "u_char\tremote_sysmap[] = {\n"
  640. X}
  641. X{
  642. X    while (syscall < $1) {
  643. X        if (column % 2 == 0)
  644. X            printf "\t"
  645. X        printf "%-31s", "RSYS_nosys,"
  646. X        if (column % 2 == 1)
  647. X            printf "\n"
  648. X        syscall++
  649. X        column++
  650. X    }
  651. X
  652. X    if (column % 2 == 0)
  653. X        printf "\t"
  654. X    len = length($2);
  655. X    found = 0;
  656. X    for (i=0; i <= last; i++) {
  657. X        if (mem[ i ] == $2) {
  658. X            found = 1;
  659. X            break;
  660. X        }
  661. X    }
  662. X    if (found) {
  663. X        printf "RSYS_%s,", $2
  664. X        len = 25-len;
  665. X    }
  666. X    else {
  667. X        printf "RSYS_nosys,  /* %s */", $2
  668. X        len = 12 - len;
  669. X    }
  670. X    if (column % 2 == 1)
  671. X        printf "\n"
  672. X    else
  673. X        while (len-- > 0)
  674. X            printf " "
  675. X    column++;
  676. X    syscall++
  677. X} END {
  678. X    if (column % 2 == 0)
  679. X        printf "\n"
  680. X    printf "};\n"
  681. X}'
  682. SHAREOF
  683. chmod 664 remote/usr.sys.remote/remote_mkdata
  684. #
  685. # remote/usr.sys.remote/remotefs.h
  686. #
  687. if [ -f remote/usr.sys.remote/remotefs.h ]; then 
  688.     echo -n 'Hit <return> to overwrite remote/usr.sys.remote/remotefs.h or ^C to quit' 
  689.     read ans 
  690.     rm -f remote/usr.sys.remote/remotefs.h 
  691. fi 
  692.  
  693. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/remotefs.h
  694. X/*
  695. X * Copyright 1985, Todd Brunhoff.
  696. X *
  697. X * This software was written at Tektronix Computer Research Laboratories
  698. X * as partial fulfillment of a Master's degree at the University of Denver.
  699. X * This is not Tektronix proprietary software and should not be
  700. X * confused with any software product sold by Tektronix.  No warranty is
  701. X * expressed or implied on the reliability of this software; the author,
  702. X * the University of Denver, and Tektronix, inc. accept no liability for
  703. X * any damage done directly or indirectly by this software.  This software
  704. X * may be copied, modified or used in any way, without fee, provided this
  705. X * notice remains an unaltered part of the software.
  706. X *
  707. X * $Header: remotefs.h,v 2.1 86/01/05 18:17:01 toddb Exp $
  708. X *
  709. X * $Log:    remotefs.h,v $
  710. X * Revision 2.1  86/01/05  18:17:01  toddb
  711. X * Added ifdef'ed constants for pyramids: FREMOTE, SREMOTE and SNOREMOTE.
  712. X * 
  713. X * Revision 2.0  85/12/07  18:17:35  toddb
  714. X * First public release.
  715. X * 
  716. X */
  717. X#ifndef RFSDEBUG
  718. X#define debug0()
  719. X#define debug1()
  720. X#define debug2()
  721. X#define debug3()
  722. X#define debug4()
  723. X#define debug5()
  724. X#define debug6()
  725. X#define debug7()
  726. X#define debug8()
  727. X#define debug9()
  728. X#define debug10()
  729. X#define debug11()
  730. X#define debug12()
  731. X#define debug13()
  732. X#define debug14()
  733. X#define rmt_showmsg()
  734. X#else RFSDEBUG
  735. X/*
  736. X * Each of the debugging macros are defined here.  With this scheme we
  737. X * are able to turn on any portion of the debugging with very little overhead
  738. X * This appears to be better than similar schemes that test if
  739. X * remote_debug <= some-level,  because they force the software into having
  740. X * more and more debug software run as the number gets higher.
  741. X */
  742. Xextern long    remote_debug;
  743. X
  744. X#define debug0    (!(remote_debug&0x00001)) ? 0:rmt_debug /* exec info */
  745. X#define debug1    (!(remote_debug&0x00002)) ? 0:rmt_debug /* startup activity */
  746. X#define debug2    (!(remote_debug&0x00004)) ? 0:rmt_debug /* rmt_copypath() */
  747. X#define debug3    (!(remote_debug&0x00008)) ? 0:rmt_debug /* unused */
  748. X#define debug4    (!(remote_debug&0x00010)) ? 0:rmt_debug /* remote_fork */
  749. X#define debug5    (!(remote_debug&0x00020)) ? 0:rmt_debug /* remote[on|off] */
  750. X#define debug6    (!(remote_debug&0x00040)) ? 0:rmt_debug /* file descriptors */
  751. X#define debug7    (!(remote_debug&0x00080)) ? 0:rmt_debug /* isremote() */
  752. X#define debug8    (!(remote_debug&0x00100)) ? 0:rmt_debug /* file remoteness */
  753. X#define debug9    (!(remote_debug&0x00200)) ? 0:rmt_debug /* connection startup */
  754. X#define debug10    (!(remote_debug&0x00400)) ? 0:rmt_debug /* msg setup */
  755. X#define debug11    (!(remote_debug&0x00800)) ? 0:rmt_debug /* msg exceptions */
  756. X#define debug12    (!(remote_debug&0x01000)) ? 0:rmt_debug /* shutdowns */
  757. X#define debug13    (!(remote_debug&0x02000)) ? 0:rmt_debug /* path translation */
  758. X#define debug14    (!(remote_debug&0x04000)) ? 0:rmt_debug /* chdir() activity */
  759. X#define debug15    (!(remote_debug&0x08000)) ? 0:rmt_debug /* msg content */
  760. X#define debug16    (!(remote_debug&0x10000)) ? 0:rmt_debug /* msg data content */
  761. X#define debug17    (!(remote_debug&0x20000)) ? 0:rmt_debug /* unused */
  762. X#define debug18    (!(remote_debug&0x40000)) ? 0:rmt_debug /* unused */
  763. X#define debug19    (!(remote_debug&0x80000)) ? 0:rmt_debug /* unused */
  764. X
  765. X#endif RFSDEBUG
  766. X
  767. X/*
  768. X * Flags for file structures and proc structures.  These should really be
  769. X * in file.h and proc.h, but are here for now.  Note that you must have
  770. X * the fix in ino_close() if DTYPE_REMOTE is defined as 3.
  771. X */
  772. X#define        DTYPE_REMOTE        3  /* file.h: remote file descriptor */
  773. X#ifdef pyr
  774. X#define        SREMOTE        0x00080000 /* proc.h: activity has occured */
  775. X#define        SNOREMOTE    0x80000000 /* proc.h: disallow remote access */
  776. X#define        FREMOTE        04000       /* file.h: this is a remote file */
  777. X#endif pyr
  778. X#if vax || magnolia || P4400
  779. X#define        SREMOTE        0x08000000 /* proc.h: activity has occured */
  780. X#define        SNOREMOTE    0x10000000 /* proc.h: disallow remote access */
  781. X#define        FREMOTE        08000       /* file.h: this is a remote file */
  782. X#endif vax || magnolia || P4400
  783. X
  784. X/*
  785. X * Defines for the name server.
  786. X */
  787. X#define        server_alive(p)                    \
  788. X            ((p)                     \
  789. X            && (p)->p_stat != NULL            \
  790. X            && remote_ns.rn_pid == (p)->p_pid)
  791. X
  792. X#define        NM_SERVER    0    /* register as name server */
  793. X#define        NM_WHATNAME    1    /* what name does the kernel need? */
  794. X#define        NM_NAMEIS    2    /* the name is... */
  795. X#define        NM_DEBUG    3    /* turn on debugging */
  796. X
  797. X/*
  798. X * Some manifest constants.
  799. X */
  800. X#define        TRUE        1
  801. X#define        FALSE        0
  802. X#define        REMOTE_FS_SERVER    "remotefs"
  803. X#define        R_MAXSYS    NREMOTE    /* defined in param.h */
  804. X#define        R_MNTPATHLEN    30
  805. X#define        R_MAXMSG    ((MAXPATHLEN * 2) + MLEN)
  806. X#define        R_RETRY        (60*5)    /* retry time for connections */
  807. X
  808. X/*
  809. X * State of the data being sent.
  810. X */
  811. X#define        R_NOTHINGSENT    1
  812. X#define        R_DATANOTSENT    2
  813. X#define        R_MSGNOTRED    3
  814. X#define        R_DATANOTRED    4
  815. X
  816. X/*
  817. X * internal flags passed to rmt_msgfin() and rmt_datafin().
  818. X */
  819. X#define        RFLG_DATAV    0x1    /* data to remotemsg() is a vector */
  820. X#define        RFLG_RD        0x2    /* data to remotemsg() to be read */
  821. X#define        RFLG_WR        0x4    /* data to remotemsg() to be written */
  822. X#define        RFLG_INFO    0x8    /* send message only (don't receive */
  823. X
  824. X/*
  825. X * known indices of data in the message.
  826. X */
  827. X#define        R_PATHOFF    3    /* to server (Offset to 2nd path) */
  828. X#define        R_PATHSTART    4    /* to server start of actual path */
  829. X#define        R_DATA        2    /* to server */
  830. X#define        R_RETVAL    0    /* from server */
  831. X#define        R_EXECUID    1    /* from server (exec setuid) */
  832. X#define        R_EXECGID    2    /* from server (exec setgid) */
  833. X#define        R_EXECREADONLY    3    /* from server (exec text read-only) */
  834. X#define        R_EXECDATA    4    /* from server (start of exec info) */
  835. X
  836. X/*
  837. X * Maximum size for the message arg data in long words.  NOT LONGWORDS!!  This
  838. X * should be the largest of the following three sizes among all machines
  839. X * that will use the remote file system:
  840. X *
  841. X *    sizeof(struct exec) * sizeof(long) + R_EXECDATA * sizeof(long)
  842. X *    (# of stat struct members + 1) * sizeof(long)
  843. X */
  844. X#define        R_MAXARGS    18
  845. X
  846. X/*
  847. X * Maximum and minimum message length in bytes that we will ever need on a
  848. X * receive (big enough for a stat(), lstat() or fstat(), and small enough for
  849. X * a return with no other values.
  850. X */
  851. X#define        R_MINRMSG    (sizeof(struct message)-R_MAXARGS*sizeof(long))
  852. X#define        R_MAXRMSG    (sizeof(struct message))
  853. X
  854. X/*
  855. X * The maximum number of mbufs that we need to send a message with
  856. X * two paths, each 1024 characters long.  This is used only in the user
  857. X * level implementation.
  858. X */
  859. X#define        R_MAXMBUFS    (R_MINRMSG+(MAXPATHLEN*2))/MLEN
  860. X
  861. X/*
  862. X * Here, we describe incomming and outgoing messages.  Note that the number
  863. X * of cells in m_args is only for incomming messages.  An outgoing message
  864. X * may consume much more.
  865. X */
  866. Xstruct message {
  867. X    long    m_totlen;    /* length of total message (including data) */
  868. X    short    m_uid;        /* uid of client */
  869. X    short    m_pid;        /* pid of client */
  870. X    short    m_hdlen;    /* length of header (excluding data) */
  871. X    short    m_syscall;    /* syscall number */
  872. X#define        m_errno m_syscall /* errno (for server) */
  873. X    long    m_args[R_MAXARGS];/* remaining arguments or return values */
  874. X};
  875. X
  876. X/*
  877. X * This structure describes the kernel information kept for each
  878. X * connection to a remote server.
  879. X */
  880. Xstruct remoteinfo {
  881. X    char    r_mntpath[ R_MNTPATHLEN ];    /* path of mount point */
  882. X    u_char        r_close:1;    /* True if connection to be closed */
  883. X    u_char        r_received:1;    /* True if an incomming msg in r_msg */
  884. X    u_char        r_failed:1;    /* connection failed */
  885. X    u_char        r_opening:1;    /* connection in process of opening */
  886. X    u_char        r_refcnt;    /* a reference count of active use */
  887. X    short        r_sender;    /* owner of outgoing data */
  888. X    short        r_recver;    /* owner of incomming data */
  889. X    u_short        r_users;    /* count of users using this */
  890. X    u_short        r_nfile;    /* count of open files */
  891. X    u_short        r_nchdir;    /* count of chdir() to this host */
  892. X    struct mbuf    *r_name;    /* socket address of remote host */
  893. X    struct inode     *r_mntpt;    /* inode of mount point */
  894. X                    /* if null, then global */
  895. X    struct socket    *r_sock;    /* socket with active connection */
  896. X#define    r_age        r_msg.m_totlen    /* used for cacheing name lookups */
  897. X#define    r_openerr    r_msg.m_errno    /* used to relay connection errors */
  898. X    struct message    r_msg;        /* incomming message */
  899. X};
  900. X
  901. Xtypedef int            (*func)();
  902. X
  903. X/*
  904. X * This describes all info associated with each syscall.  Note that while
  905. X * the flag information is available, most syscalls don't reference it
  906. X * because they have the flag hard coded in-line.  It exists for the
  907. X * sake of routines like read and write which cannot hard code the flags
  908. X * very easily.  The follow flag is useful only for system calls that involve
  909. X * pathnames.  The before entry is to tell syscall whether to try to
  910. X * call the remote syscall routine before calling the real system call.
  911. X * The size here make each table entry a
  912. X * power of 2 in size (16 bytes) which the compiler can make faster code for.
  913. X */
  914. Xstruct syscalls {
  915. X    func    sys_gen;
  916. X    func    sys_spec;
  917. X    long    sys_flag;
  918. X    short    sys_follow;
  919. X    short    sys_before;
  920. X};
  921. Xtypedef struct syscalls        syscalls;
  922. X
  923. X/*
  924. X * This structure simply describes the process willing to act as a
  925. X * name server for the remote file system, and the information passing
  926. X * to and from it.
  927. X */
  928. Xstruct nameserver {
  929. X    struct proc    *rn_proc;    /* process registered as nameserver */
  930. X    struct mbuf    *rn_name;    /* input from name server */
  931. X    char        *rn_path;    /* path to translate */
  932. X    short        rn_pathlen;    /* length of path to translate */
  933. X    short        rn_pid;        /* pid of process (for uniqueness) */
  934. X};
  935. X
  936. X/*
  937. X * System calls
  938. X * Note that these have nothing to do with either the vax or magnolia idea
  939. X * of the system calls.  They are simply an index into the systems calls
  940. X * that we are concerned with.
  941. X */
  942. X#define    RSYS_fork    0
  943. X#define    RSYS_read    1
  944. X#define    RSYS_write    2
  945. X#define    RSYS_open    3
  946. X#define    RSYS_close    4
  947. X#define    RSYS_creat    5
  948. X#define    RSYS_link    6
  949. X#define    RSYS_unlink    7
  950. X#define    RSYS_chdir    8
  951. X#define    RSYS_mknod    9
  952. X#define    RSYS_chmod    10
  953. X#define    RSYS_chown    11
  954. X#define    RSYS_stat    12
  955. X#define    RSYS_lseek    13
  956. X#define    RSYS_access    14
  957. X#define    RSYS_lstat    15
  958. X#define    RSYS_dup    16
  959. X#define    RSYS_ioctl    17
  960. X#define    RSYS_symlink    18
  961. X#define    RSYS_readlink    19
  962. X#define    RSYS_fstat    20
  963. X#define    RSYS_dup2    21
  964. X#define    RSYS_fcntl    22
  965. X#define    RSYS_fsync    23
  966. X#define    RSYS_readv    24
  967. X#define    RSYS_writev    25
  968. X#define    RSYS_fchown    26
  969. X#define    RSYS_fchmod    27
  970. X#define    RSYS_rename    28
  971. X#define    RSYS_truncate    29
  972. X#define    RSYS_ftruncate    30
  973. X#define    RSYS_flock    31
  974. X#define    RSYS_mkdir    32
  975. X#define    RSYS_rmdir    33
  976. X#define    RSYS_utimes    34
  977. X#define    RSYS_exit    35
  978. X#define    RSYS_vfork    36
  979. X#define    RSYS_execinfo    37
  980. X#define    RSYS_execread    38
  981. X#define RSYS_execve    39
  982. X#define    RSYS_nosys    40
  983. X#define    RSYS_qlseek    41
  984. X
  985. X/*
  986. X * This macro fills in some of the information needed on every transfer
  987. X * and returns the byte (not longword) offset of the next free byte.
  988. X */
  989. X#define introduce(buf, sysnum)                        \
  990. X                ((buf)->m_pid = htons(u.u_procp->p_pid),\
  991. X                 (buf)->m_uid = htons(u.u_uid),        \
  992. X                 (buf)->m_syscall = htons(sysnum),    \
  993. X                 (R_MINRMSG))
  994. X#define introduce_1extra(buf, sysnum, x1)                \
  995. X                ((buf)->m_pid = htons(u.u_procp->p_pid),\
  996. X                 (buf)->m_uid = htons(u.u_uid),        \
  997. X                 (buf)->m_syscall = htons(sysnum),    \
  998. X                 (buf)->m_args[0] = htonl(x1),        \
  999. X                 (R_MINRMSG + sizeof(long)))
  1000. X#define introduce_2extra(buf, sysnum, x1, x2)                \
  1001. X                ((buf)->m_pid = htons(u.u_procp->p_pid),\
  1002. X                 (buf)->m_uid = htons(u.u_uid),        \
  1003. X                 (buf)->m_syscall = htons(sysnum),    \
  1004. X                 (buf)->m_args[0] = htonl(x1),        \
  1005. X                 (buf)->m_args[1] = htonl(x2),        \
  1006. X                 (R_MINRMSG + 2*sizeof(long)))
  1007. X/*
  1008. X * This macro defines whether a host is being used or not.
  1009. X * The rmtclearhosts() and rmtcopyhosts() are for expansion if someone
  1010. X * wants to use more than 32 hosts.
  1011. X */
  1012. X#define    rmthostused(rsys)        (u.u_rmtsys  &  (1<<rsys))
  1013. X#define    rmtusehost(rsys)        (u.u_rmtsys  |= (1<<rsys))
  1014. X#define    rmtunusehost(rsys)        (u.u_rmtsys  &= ~(1<<rsys))
  1015. X#define    rmtclearhosts()            (u.u_rmtsys   =  0)
  1016. X#define    rmtcopyhosts(dest,hosts)    (dest         =  hosts)
  1017. X
  1018. X#ifdef pyr
  1019. X/*
  1020. X * Pyramid changed the name on ctob and btoc
  1021. X **/
  1022. X#define    ctob(x)    ptob(x)
  1023. X#define    btoc(x)    btop(x)
  1024. X#endif
  1025. SHAREOF
  1026. chmod 444 remote/usr.sys.remote/remotefs.h
  1027. #
  1028. # remote/usr.sys.remote/rmt_data_template
  1029. #
  1030. if [ -f remote/usr.sys.remote/rmt_data_template ]; then 
  1031.     echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_data_template or ^C to quit' 
  1032.     read ans 
  1033.     rm -f remote/usr.sys.remote/rmt_data_template 
  1034. fi 
  1035.  
  1036. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_data_template
  1037. X/*
  1038. X * Copyright 1985, Todd Brunhoff.
  1039. X *
  1040. X * This software was written at Tektronix Computer Research Laboratories
  1041. X * as partial fulfillment of a Master's degree at the University of Denver.
  1042. X * This is not Tektronix proprietary software and should not be
  1043. X * confused with any software product sold by Tektronix.  No warranty is
  1044. X * expressed or implied on the reliability of this software; the author,
  1045. X * the University of Denver, and Tektronix, inc. accept no liability for
  1046. X * any damage done directly or indirectly by this software.  This software
  1047. X * may be copied, modified or used in any way, without fee, provided this
  1048. X * notice remains an unaltered part of the software.
  1049. X *
  1050. X * $Header: rmt_data_template,v 2.0 85/12/07 18:19:42 toddb Rel $
  1051. X *
  1052. X * $Log:    rmt_data_template,v $
  1053. X * Revision 2.0  85/12/07  18:19:42  toddb
  1054. X * First public release.
  1055. X * 
  1056. X */
  1057. X#include    "../h/errno.h"
  1058. X#include    "../h/param.h"
  1059. X#include    "../h/mbuf.h"
  1060. X#include    "../h/socket.h"
  1061. X#include    "../remote/remotefs.h"
  1062. X
  1063. X
  1064. Xextern int
  1065. X        rmt_access(),
  1066. X        rmt_chdir(),
  1067. X        rmt_chmod(),
  1068. X        rmt_chown(),
  1069. X        rmt_dup(),
  1070. X        rmt_dup2(),
  1071. X        rmt_error(),
  1072. X        remote_exit(),
  1073. X        rmt_fcntl(),
  1074. X        rmt_flock(),
  1075. X        remote_fork(),
  1076. X        rmt_fsync(),
  1077. X        rmt_ioctl(),
  1078. X        rmt_lseek(),
  1079. X        rmt_mknod(),
  1080. X        rmt_noop(),
  1081. X        rmt_onearg(),
  1082. X        rmt_open(),
  1083. X        rmt_readlink(),
  1084. X        rmt_stat(),
  1085. X        rmt_truncate(),
  1086. X        rmt_utimes(),
  1087. X        rmt_execinfo(),
  1088. X        rmt_execread(),
  1089. X        rmt_execve(),
  1090. X        remote_fd(),
  1091. X        remote_path1(),
  1092. X        remote_path2(),
  1093. X        rmt_datafin();
  1094. X
  1095. X/*
  1096. X * This table depends on the order of system calls as defined in
  1097. X * sys/sys/init_sysent.c, and our local map in remote_sysmap, which
  1098. X * is generated (and appended to this file) by the program mkdata.
  1099. X * The latter is a table of indices into remote_syscall[].
  1100. X * Remote_syscall[] is a table containing general and specific actions
  1101. X * for each system call, whether to follow symbolic links in namei and
  1102. X * flags that are passed to rmt_msgfin() and rmt_datafin().
  1103. X */
  1104. X
  1105. Xsyscalls    remote_syscall[] = {
  1106. X/*
  1107. X * general    specific    flags to    follow    call before
  1108. X *              rmt_fin()   symlinks    real syscall
  1109. X */
  1110. X{ remote_fork,    rmt_noop,    RFLG_INFO,    FALSE,    TRUE    }, /* RSYS_fork */
  1111. X{ remote_fd,    rmt_datafin,  RFLG_RD,    FALSE,    TRUE    }, /* RSYS_read */
  1112. X{ remote_fd,    rmt_datafin,  RFLG_WR,    FALSE,    TRUE    }, /* RSYS_write */
  1113. X{ remote_path1,    rmt_open,    0,    TRUE,    FALSE    }, /* RSYS_open */
  1114. X{ remote_fd,    rmt_onearg,  RFLG_INFO,    FALSE,    TRUE    }, /* RSYS_close */
  1115. X{ remote_path1,    rmt_open,    0,    TRUE,    FALSE    }, /* RSYS_creat */
  1116. X{ remote_path2,    rmt_noop,    0,    FALSE,    FALSE    }, /* RSYS_link */
  1117. X{ remote_path1,    rmt_onearg,    0,    FALSE,    FALSE    }, /* RSYS_unlink */
  1118. X{ remote_path1,    rmt_chdir,    0,    TRUE,    FALSE    }, /* RSYS_chdir */
  1119. X{ remote_path1,    rmt_mknod,    0,    FALSE,    FALSE    }, /* RSYS_mknod */
  1120. X{ remote_path1,    rmt_chmod,    0,    TRUE,    FALSE    }, /* RSYS_chmod */
  1121. X{ remote_path1,    rmt_chown,    0,    FALSE,    FALSE    }, /* RSYS_chown */
  1122. X{ remote_path1,    rmt_stat,    0,    TRUE,    FALSE    }, /* RSYS_stat */
  1123. X{ remote_fd,    rmt_lseek,    0,    FALSE,    TRUE    }, /* RSYS_lseek */
  1124. X{ remote_path1,    rmt_access,    0,    FALSE,    FALSE    }, /* RSYS_lstat */
  1125. X{ remote_path1,    rmt_stat,    0,    TRUE,    FALSE    }, /* RSYS_access */
  1126. X{ remote_fd,    rmt_dup,    0,    FALSE,    TRUE    }, /* RSYS_dup */
  1127. X{ remote_fd,    rmt_ioctl,    0,    FALSE,    TRUE    }, /* RSYS_ioctl */
  1128. X{ remote_path2,    rmt_noop,    0,    TRUE,    FALSE    }, /* RSYS_symlink */
  1129. X{ remote_path1,    rmt_readlink,  RFLG_RD,    FALSE,    FALSE    }, /* RSYS_readlink */
  1130. X{ remote_fd,    rmt_stat,    0,    FALSE,    TRUE    }, /* RSYS_fstat */
  1131. X{ remote_fd,    rmt_dup2,    0,    FALSE,    TRUE    }, /* RSYS_dup2 */
  1132. X{ remote_fd,    rmt_fcntl,    0,    FALSE,    TRUE    }, /* RSYS_fcntl */
  1133. X{ remote_fd,    rmt_onearg,  RFLG_INFO,    FALSE,    TRUE    }, /* RSYS_fsync */
  1134. X{ remote_fd,    rmt_datafin, RFLG_RD|RFLG_DATAV,
  1135. X                    FALSE,    TRUE    },/* RSYS_readv */
  1136. X{ remote_fd,    rmt_datafin, RFLG_WR|RFLG_DATAV,
  1137. X                    FALSE,    TRUE    },/* RSYS_writev */
  1138. X{ remote_fd,    rmt_chown,    0,    FALSE,    TRUE    }, /* RSYS_fchown */
  1139. X{ remote_fd,    rmt_chmod,    0,    FALSE,    TRUE    }, /* RSYS_fchmod */
  1140. X{ remote_path2,    rmt_noop,    0,    TRUE,    FALSE    }, /* RSYS_rename */
  1141. X{ remote_path1,    rmt_truncate,    0,    TRUE,    FALSE    }, /* RSYS_truncate */
  1142. X{ remote_fd,    rmt_truncate,    0,    FALSE,    TRUE    }, /* RSYS_ftruncate */
  1143. X{ remote_fd,    rmt_flock,    0,    FALSE,    TRUE    }, /* RSYS_flock */
  1144. X{ remote_path1,    rmt_mknod,    0,    FALSE,    FALSE    }, /* RSYS_mkdir */
  1145. X{ remote_path1,    rmt_onearg,    0,    FALSE,    FALSE    }, /* RSYS_rmdir */
  1146. X{ remote_path1,    rmt_noop,    0,    TRUE,    FALSE    }, /* RSYS_utimes */
  1147. X{ remote_exit,    rmt_noop,      RFLG_INFO,FALSE,    TRUE    }, /* RSYS_exit */
  1148. X{ remote_fork,    rmt_noop,    RFLG_INFO,    FALSE,    TRUE    }, /* RSYS_vfork */
  1149. X{ remote_path1,    rmt_execinfo,    0,    TRUE,    FALSE    }, /* RSYS_execinfo */
  1150. X{ rmt_error,    rmt_noop,    0,    FALSE,    FALSE    }, /* RSYS_execread */
  1151. X{ remote_path1,    rmt_error,    0,    TRUE,    FALSE    }, /* RSYS_execve */
  1152. X{ rmt_error,    rmt_noop,    0,    FALSE,    FALSE    }, /* RSYS_nosys */
  1153. X{ rmt_error,    rmt_noop,    0,    FALSE,    FALSE    }, /* RSYS_qlseek */
  1154. X};
  1155. X
  1156. Xstruct remoteinfo    remote_info[ R_MAXSYS ];
  1157. Xstruct remoteinfo    *remote_generic;
  1158. Xlong            remote_debug;
  1159. Xlong            remote_sysindex;
  1160. Xlong            remote_maxchunk = (1024*10);
  1161. Xstruct mbuf        *remote_path;
  1162. Xstruct nameserver    remote_ns;
  1163. X
  1164. X/*
  1165. X * The following list maps all of the actual system call numbers into our
  1166. X * idea of the system call numbers.  THIS IS GENERATED AUTOMATICALLY...
  1167. X * DO NOT MODIFY!
  1168. X */
  1169. SHAREOF
  1170. chmod 444 remote/usr.sys.remote/rmt_data_template
  1171. #
  1172. # remote/usr.sys.remote/rmt_exec.c
  1173. #
  1174. if [ -f remote/usr.sys.remote/rmt_exec.c ]; then 
  1175.     echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_exec.c or ^C to quit' 
  1176.     read ans 
  1177.     rm -f remote/usr.sys.remote/rmt_exec.c 
  1178. fi 
  1179.  
  1180. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_exec.c
  1181. X/*
  1182. X * Copyright 1985, Todd Brunhoff.
  1183. X *
  1184. X * This software was written at Tektronix Computer Research Laboratories
  1185. X * as partial fulfillment of a Master's degree at the University of Denver.
  1186. X * This is not Tektronix proprietary software and should not be
  1187. X * confused with any software product sold by Tektronix.  No warranty is
  1188. X * expressed or implied on the reliability of this software; the author,
  1189. X * the University of Denver, and Tektronix, inc. accept no liability for
  1190. X * any damage done directly or indirectly by this software.  This software
  1191. X * may be copied, modified or used in any way, without fee, provided this
  1192. X * notice remains an unaltered part of the software.
  1193. X *
  1194. X * $Header: rmt_exec.c,v 2.1 85/12/30 16:45:30 toddb Exp $
  1195. X *
  1196. X * $Log:    rmt_exec.c,v $
  1197. X * Revision 2.1  85/12/30  16:45:30  toddb
  1198. X * fixed syntax error for 4.3.
  1199. X * 
  1200. X * Revision 2.0  85/12/07  18:17:54  toddb
  1201. X * First public release.
  1202. X * 
  1203. X */
  1204. X#ifndef pyr /* Pyramid */
  1205. X#include    "../machine/reg.h"
  1206. X#include    "../machine/pte.h"
  1207. X#include    "../machine/psl.h"
  1208. X#endif
  1209. X
  1210. X#include    "../h/param.h"
  1211. X#include    "../h/systm.h"
  1212. X#include    "../h/map.h"
  1213. X#include    "../h/dir.h"
  1214. X#include    "../h/user.h"
  1215. X#include    "../h/kernel.h"
  1216. X#include    "../h/proc.h"
  1217. X#include    "../h/file.h"
  1218. X#include    "../h/uio.h"
  1219. X#include    "../remote/remotefs.h"
  1220. X#include    "../h/mbuf.h"
  1221. X#include    "../netinet/in.h"
  1222. X#include    "../h/vm.h"
  1223. X#include    "../h/errno.h"
  1224. X#ifdef BSD4_3
  1225. X#include    "../h/namei.h"
  1226. X#include    "../h/exec.h"
  1227. X#else BSD4_3
  1228. X#include    "../h/nami.h"
  1229. X#endif BSD4_3
  1230. X
  1231. X#ifdef vax
  1232. X#include "../vax/mtpr.h"
  1233. X#endif
  1234. X
  1235. Xextern struct remoteinfo    remote_info[];
  1236. Xextern long            remote_sysindex;
  1237. Xextern long            remote_maxchunk;
  1238. X
  1239. X#ifdef magnolia
  1240. X#define    DEMAND_PAGED    0513
  1241. X#define    SHARED_TEXT    0510
  1242. X#else magnolia
  1243. X#define    DEMAND_PAGED    0413
  1244. X#define    SHARED_TEXT    0410
  1245. X#endif magnolia
  1246. X
  1247. X/*
  1248. X * Get execution info for a file that is on a remote system.  At this point
  1249. X * we know that the file is remote.  We must send one request to get the
  1250. X * header and then if all is ok, we will be asked for the file to be sent over
  1251. X * en-masse.
  1252. X */
  1253. X#ifdef BSD4_3
  1254. Xremote_execinfo(ip, auid, agid, pexdata, fname)
  1255. X    struct exec    *pexdata;
  1256. X#else BSD4_3
  1257. Xremote_execinfo(ip, auid, agid, fname)
  1258. X#endif BSD4_3
  1259. X    register struct inode    **ip;
  1260. X    long    *auid, *agid;
  1261. X    register char    *fname;
  1262. X{
  1263. X    long    error,
  1264. X        sysindex = remote_sysindex,
  1265. X        uid, gid,
  1266. X        hdrsize,
  1267. X        execsize;
  1268. X    struct inode    *namei();
  1269. X    struct remoteinfo    *rp = remote_info + remote_sysindex;
  1270. X    struct message    *msg;
  1271. X
  1272. X    u.u_error = 0;
  1273. X    error = remote_path1(RSYS_execinfo);
  1274. X    if (error) {
  1275. X        /*
  1276. X         * Try again if its a local file.
  1277. X         */
  1278. X        if (error < 0 && fname) {
  1279. X#ifdef BSD4_3
  1280. X            struct nameidata *ndp = &u.u_nd;
  1281. X
  1282. X            ndp->ni_dirp = (caddr_t) fname;
  1283. X            if ((*ip = namei(ndp)) == NULL)
  1284. X#else BSD4_3
  1285. X            u.u_dirp = (caddr_t) fname;
  1286. X            if ((*ip = namei(uchar, LOOKUP, 1)) == NULL)
  1287. X#endif BSD4_3
  1288. X                if (u.u_error == 0 || u.u_error == EISREMOTE)
  1289. X                    u.u_error = ELOOP;
  1290. X            return(remote_sysindex);
  1291. X        }
  1292. X        else if (error < 0)
  1293. X            error = ENOENT;
  1294. X        u.u_error = error;
  1295. X        return(-1);
  1296. X    }
  1297. X    /*
  1298. X     * The R_RETVAL cell contains the total size of the file.  So that
  1299. X     * had better be >= the size of the header + size of text + size
  1300. X     * of data.
  1301. X     */
  1302. X    msg = &rp->r_msg;
  1303. X#ifdef BSD4_3
  1304. X    bcopy(msg->m_args+R_EXECDATA,
  1305. X        (caddr_t)pexdata, sizeof(struct exec));
  1306. X    if (pexdata->a_magic == DEMAND_PAGED)
  1307. X        hdrsize = CLBYTES;
  1308. X    else
  1309. X        hdrsize = sizeof(sizeof(struct exec));
  1310. X#else BSD4_3
  1311. X    bcopy(msg->m_args+R_EXECDATA,
  1312. X        (caddr_t)&u.u_exdata, sizeof (u.u_exdata));
  1313. X    if (u.u_exdata.ux_mag == DEMAND_PAGED)
  1314. X        hdrsize = CLBYTES;
  1315. X    else
  1316. X        hdrsize = sizeof(u.u_exdata.Ux_A);
  1317. X#endif BSD4_3
  1318. X
  1319. X    execsize = ntohl(msg->m_args[ R_RETVAL ]);
  1320. X    debug0("obj=%d,hrd=%d,error=%d,tx=%d,dat=%d\n",
  1321. X        execsize, hdrsize, u.u_error,
  1322. X#ifdef BSD4_3
  1323. X        pexdata->a_text, pexdata->a_text
  1324. X#else BSD4_3
  1325. X        u.u_exdata.ux_tsize, u.u_exdata.ux_dsize
  1326. X#endif BSD4_3
  1327. X        );
  1328. X
  1329. X#ifdef BSD4_3
  1330. X    if (pexdata->a_text + pexdata->a_data + hdrsize > execsize
  1331. X     && *((char *)pexdata) != '#') {
  1332. X        error = ENOEXEC;
  1333. X        goto bad;
  1334. X    }
  1335. X#else BSD4_3
  1336. X    if (u.u_exdata.ux_tsize + u.u_exdata.ux_dsize + hdrsize > execsize
  1337. X     && u.u_exdata.ux_shell[0] != '#') {
  1338. X        error = ENOEXEC;
  1339. X        goto bad;
  1340. X    }
  1341. X#endif BSD4_3
  1342. X
  1343. X    if ((u.u_procp->p_flag&STRC) && msg->m_args[ R_EXECREADONLY ]) {
  1344. X        error = EACCES;
  1345. X        goto bad;
  1346. X    }
  1347. X    if (auid) { /* first time thru for this exec... set uid/gid stuff */
  1348. X        uid = ntohl(msg->m_args[ R_EXECUID ]);
  1349. X        if (uid < 0)
  1350. X            uid = u.u_uid;
  1351. X        gid = ntohl(msg->m_args[ R_EXECGID ]);
  1352. X        if (gid < 0)
  1353. X            gid = u.u_gid;
  1354. X        *auid = uid;
  1355. X        *agid = gid;
  1356. X    }
  1357. X    return(sysindex);
  1358. X
  1359. Xbad:
  1360. X    u.u_error = error;
  1361. X    return(-1);
  1362. X}
  1363. X
  1364. X/*
  1365. X * This is the simple routine that is called by remote_path1 as the
  1366. X * specific routine for handling RSYS_execinfo.  remote_execinfo() is
  1367. X * called from exec, and remote_execinfo() calls remote_path1() who in
  1368. X * turn calls rmt_execinfo().
  1369. X */
  1370. Xrmt_execinfo(sysindex, m)
  1371. X    long    sysindex;
  1372. X    struct mbuf    *m;
  1373. X{
  1374. X    struct message *msg = mtod(m, struct message *);
  1375. X#ifdef BSD4_3
  1376. X    msg->m_args[0] = htonl(sizeof (struct exec));
  1377. X#else BSD4_3
  1378. X    msg->m_args[0] = htonl(sizeof (u.u_exdata));
  1379. X#endif BSD4_3
  1380. X    return (rmt_msgfin(sysindex, m, 0));
  1381. X}
  1382. X
  1383. X/*
  1384. X * Read into memory an executable file from a remote system.
  1385. X */
  1386. X#ifdef BSD4_3
  1387. Xremote_execread(sysindex, oldtextsize, ep)
  1388. X    register struct exec *ep;
  1389. X    register int    sysindex, oldtextsize;
  1390. X#else BSD4_3
  1391. Xremote_execread(sysindex, oldtextsize)
  1392. X    register int    sysindex, oldtextsize;
  1393. X#endif BSD4_3
  1394. X{
  1395. X    struct remoteinfo    *rp = remote_info + sysindex;
  1396. X    struct uio auio;
  1397. X    struct iovec aiov[2];
  1398. X    struct mbuf    *m;
  1399. X    struct message    *msg;
  1400. X    register long    hdrsize, datasize, textsize, error, len, magic;
  1401. X    register struct proc    *p = u.u_procp;
  1402. X    long    iovlen;
  1403. X
  1404. X#ifdef BSD4_3
  1405. X    datasize = (int)ep->a_data;
  1406. X    magic = ep->a_magic;
  1407. X#define HEADERSIZE    sizeof(struct exec);
  1408. X#else BSD4_3
  1409. X    datasize = (int)u.u_exdata.ux_dsize;
  1410. X    magic = u.u_exdata.ux_mag;
  1411. X#define HEADERSIZE    sizeof(u.u_exdata.Ux_A);
  1412. X#endif BSD4_3
  1413. X    if (datasize <= 0) {
  1414. X        u.u_error = ENOEXEC;
  1415. X        return(-1);
  1416. X    }
  1417. X
  1418. X    /*
  1419. X     * We are guarenteed that at this point the text size is zero.
  1420. X     * But we know what the old text size was passed along for the sake of
  1421. X     * shared-text programs:  the binaries for these do not
  1422. X     * necessarily have the data page-aligned in the file (as we
  1423. X     * assume that demand-paged programs do), but instead,
  1424. X     * it is aligned when it is read in.  We must do the same here.
  1425. X     */
  1426. X    if (oldtextsize && magic == SHARED_TEXT) {
  1427. X        aiov[0].iov_len = oldtextsize;
  1428. X        aiov[1].iov_len = datasize - oldtextsize;
  1429. X        iovlen = 2;
  1430. X        aiov[0].iov_base = (char *)ctob(tptov(p, 0));
  1431. X        aiov[1].iov_base = (char *)ctob(btoc(oldtextsize));
  1432. X        debug0("execrd: %d @ %x, %d @ %x ",
  1433. X            aiov[0].iov_len, aiov[0].iov_base,
  1434. X            aiov[1].iov_len, aiov[1].iov_base);
  1435. X    }
  1436. X    else {
  1437. X        iovlen = 1;
  1438. X        aiov[0].iov_base = (char *)ctob(dptov(p, 0)),
  1439. X        aiov[0].iov_len = datasize;
  1440. X        debug0("execrd: %d @ %x ", aiov[0].iov_len, aiov[0].iov_base);
  1441. X    }
  1442. X    auio.uio_offset = 0;
  1443. X    auio.uio_segflg = 0;
  1444. X    if (magic == DEMAND_PAGED)
  1445. X        hdrsize = CLBYTES;
  1446. X    else
  1447. X        hdrsize = HEADERSIZE;
  1448. X
  1449. X    /*
  1450. X     * Now ask for it in remote_maxchunk size chunks.
  1451. X     */
  1452. X    debug0("hdsz=%d, datasz=%d, rd ", hdrsize, datasize);
  1453. X    error = 0;
  1454. X    while (datasize >= 0) {
  1455. X        auio.uio_resid = MIN(datasize, remote_maxchunk);
  1456. X        if (auio.uio_resid == 0)
  1457. X            datasize = -1;
  1458. X        else {
  1459. X            if (aiov[0].iov_len <= 0 && iovlen == 2) {
  1460. X                aiov[0] = aiov[1];
  1461. X                iovlen = 1;
  1462. X            }
  1463. X            auio.uio_iov = aiov;
  1464. X            auio.uio_iovcnt = iovlen;
  1465. X            datasize -= auio.uio_resid;
  1466. X        }
  1467. X        MGET(m, M_WAIT, MT_DATA);
  1468. X        if (m == NULL)
  1469. X            return(ENOBUFS);
  1470. X        msg = mtod(m, struct message *);
  1471. X        len = introduce_2extra(msg, RSYS_execread, hdrsize,
  1472. X            auio.uio_resid);
  1473. X        m->m_len = len;
  1474. X        msg->m_hdlen = htons(len);
  1475. X        msg->m_totlen = htonl(len);
  1476. X#ifdef RFSDEBUG
  1477. X        if (auio.uio_resid) {
  1478. X            debug0("\n %d: %d@%d", auio.uio_resid,
  1479. X                aiov[0].iov_len, aiov[0].iov_base);
  1480. X            if (iovlen == 2)
  1481. X                debug0(",%d@%d.",
  1482. X                    aiov[1].iov_len, aiov[1].iov_base);
  1483. X        }
  1484. X        rmt_showmsg(msg, FALSE);
  1485. X#endif RFSDEBUG
  1486. X        if (datasize >= 0)
  1487. X            error = remoteio(sysindex, &m, &auio, RFLG_RD);
  1488. X        else
  1489. X            remoteio(sysindex, &m, 0, RFLG_INFO);
  1490. X#ifdef RFSDEBUG
  1491. X        msg = &rp->r_msg;
  1492. X        rmt_showmsg(msg, TRUE);
  1493. X#endif RFSDEBUG
  1494. X        /*
  1495. X         * If there are any errors, simply send the last
  1496. X         * message: we're all done.
  1497. X         */
  1498. X        if (error && datasize >= 0)
  1499. X            datasize = 0;
  1500. X        else if (error)
  1501. X            return(error);
  1502. X    }
  1503. X
  1504. X    debug0("\n");
  1505. X    return ( error );
  1506. X}
  1507. SHAREOF
  1508. chmod 444 remote/usr.sys.remote/rmt_exec.c
  1509. #
  1510. # remote/usr.sys.remote/rmt_final.c
  1511. #
  1512. if [ -f remote/usr.sys.remote/rmt_final.c ]; then 
  1513.     echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_final.c or ^C to quit' 
  1514.     read ans 
  1515.     rm -f remote/usr.sys.remote/rmt_final.c 
  1516. fi 
  1517.  
  1518. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_final.c
  1519. X/*
  1520. X * Copyright 1985, Todd Brunhoff.
  1521. X *
  1522. X * This software was written at Tektronix Computer Research Laboratories
  1523. X * as partial fulfillment of a Master's degree at the University of Denver.
  1524. X * This is not Tektronix proprietary software and should not be
  1525. X * confused with any software product sold by Tektronix.  No warranty is
  1526. X * expressed or implied on the reliability of this software; the author,
  1527. X * the University of Denver, and Tektronix, inc. accept no liability for
  1528. X * any damage done directly or indirectly by this software.  This software
  1529. X * may be copied, modified or used in any way, without fee, provided this
  1530. X * notice remains an unaltered part of the software.
  1531. X *
  1532. X * $Header: rmt_final.c,v 2.1 85/12/30 16:51:01 toddb Exp $
  1533. X *
  1534. X * $Log:    rmt_final.c,v $
  1535. X * Revision 2.1  85/12/30  16:51:01  toddb
  1536. X * Made rmt_copypath() compatible between 4.2 and 4.3 by adding a c-version
  1537. X * of copystr() and copyinstr() for 4.2 versions (copystr() and copyinstr()
  1538. X * are assembler routines in 4.3).
  1539. X * 
  1540. X * Revision 2.0  85/12/07  18:20:12  toddb
  1541. X * First public release.
  1542. X * 
  1543. X */
  1544. X#include    "../h/param.h"
  1545. X#ifndef pyr /* Pyramid */
  1546. X#include    "../machine/pte.h"
  1547. X#endif
  1548. X#include    "../h/systm.h"
  1549. X#include    "../h/map.h"
  1550. X#include    "../h/dir.h"
  1551. X#include    "../h/user.h"
  1552. X#include    "../h/kernel.h"
  1553. X#include    "../h/proc.h"
  1554. X#include    "../h/mbuf.h"
  1555. X#include    "../h/socket.h"
  1556. X#include    "../h/file.h"
  1557. X#include    "../remote/remotefs.h"
  1558. X#include    "../h/errno.h"
  1559. X#include    "../netinet/in.h"
  1560. X#include    "../h/uio.h"
  1561. X
  1562. Xextern struct remoteinfo    remote_info[];
  1563. X
  1564. X/*
  1565. X * rmt_msgfin() finalizes the message by adding in the header and total
  1566. X * lengths and sending the message.  It returns the return value found in the
  1567. X * reply.
  1568. X */
  1569. Xrmt_msgfin(sysindex, m, flags)
  1570. X    long    sysindex, flags;
  1571. X    struct mbuf    *m;
  1572. X{
  1573. X    long    error, len;
  1574. X    struct message    *msg = mtod(m, struct message *);
  1575. X    struct remoteinfo    *rp = remote_info + sysindex;
  1576. X
  1577. X    /*
  1578. X     * If the length has been set (by remote_path[12]), then don't
  1579. X     * meddle, otherwise assign it.
  1580. X     */
  1581. X    if (msg->m_hdlen == 0)
  1582. X        len = m->m_len;
  1583. X    else
  1584. X        len = msg->m_hdlen;
  1585. X    msg->m_hdlen = htons(len);
  1586. X    msg->m_totlen = htonl(len);
  1587. X        
  1588. X    rmt_showmsg(msg, FALSE);
  1589. X    error = remoteio(sysindex, &m, 0, flags);
  1590. X
  1591. X    if (! error) {
  1592. X        if ((flags & RFLG_INFO) == 0) {
  1593. X            msg = &rp->r_msg;
  1594. X            rmt_showmsg(msg, TRUE);
  1595. X            if ((error = msg->m_errno) == 0)
  1596. X                u.u_r.r_val1 = msg->m_args[R_RETVAL];
  1597. X        }
  1598. X        else
  1599. X            u.u_r.r_val1 = 0;
  1600. X    }
  1601. X    return ( error );
  1602. X}
  1603. X
  1604. X/*
  1605. X * rmt_datafin() finalizes a message and fixes up the header and total
  1606. X * lengths (like rmt_msgfin()) and sends a message plus data.  It returns
  1607. X * the return value found in the reply.
  1608. X */
  1609. Xrmt_datafin(sysindex, m, flags)
  1610. X    long    sysindex, flags;
  1611. X    struct mbuf    *m;
  1612. X{
  1613. X    register long    i, error, len;
  1614. X    struct message    *msg = mtod(m, struct message *);
  1615. X    short    syscall = ntohs(msg->m_syscall);
  1616. X    struct remoteinfo    *rp = remote_info + sysindex;
  1617. X    struct uio auio, *uio;
  1618. X    struct iovec aiov[16], *iov = aiov;
  1619. X    struct a {
  1620. X        long    fd;
  1621. X        char    *databuf;
  1622. X        long    datalen;
  1623. X    } *uap = (struct a *)u.u_ap;
  1624. X
  1625. X    /*
  1626. X     * Package up the data.
  1627. X     * If the length has been set (by remote_path1 for readlink),
  1628. X     * then don't meddle, otherwise assign it the length of the first
  1629. X     * (and only) mbuf.
  1630. X     */
  1631. X    if (msg->m_hdlen == 0)
  1632. X        msg->m_hdlen = htons(len = m->m_len);
  1633. X    else
  1634. X        msg->m_hdlen = htons(len = msg->m_hdlen);
  1635. X    if (flags & (RFLG_RD | RFLG_WR)) {
  1636. X        uio = &auio;
  1637. X        uio->uio_iov = iov;
  1638. X        uio->uio_segflg = 0;
  1639. X        uio->uio_offset = 0;
  1640. X        if (flags & RFLG_DATAV) {
  1641. X            uio->uio_iovcnt = uap->datalen;
  1642. X            error = copyin((caddr_t)uap->databuf, (caddr_t)iov,
  1643. X                (unsigned)(uap->datalen * sizeof (struct iovec)));
  1644. X            if (error)
  1645. X                goto done;
  1646. X            uio->uio_resid = 0;
  1647. X            for (i = 0; i < uio->uio_iovcnt; i++) {
  1648. X                if (iov->iov_len < 0) {
  1649. X                    error = EINVAL;
  1650. X                    goto done;
  1651. X                }
  1652. X                uio->uio_resid += iov->iov_len;
  1653. X                iov++;
  1654. X            }
  1655. X        }
  1656. X        else {
  1657. X            iov->iov_base = uap->databuf;
  1658. X            iov->iov_len = uio->uio_resid = uap->datalen;
  1659. X            uio->uio_iovcnt = 1;
  1660. X        }
  1661. X        if (uio->uio_resid < 0) {
  1662. X            error = EINVAL;
  1663. X            goto done;
  1664. X        }
  1665. X        if (flags & RFLG_WR)
  1666. X            msg->m_totlen = htonl(len + uio->uio_resid);
  1667. X        else
  1668. X            msg->m_totlen = htonl(len);
  1669. X    }
  1670. X    else {
  1671. X        uio = NULL;
  1672. X        msg->m_totlen = htonl(len);
  1673. X    }
  1674. X    rmt_showmsg(msg, FALSE);
  1675. X    error = remoteio(sysindex, &m, uio, flags);
  1676. X    m = NULL;
  1677. X    if (error)
  1678. X        goto done;
  1679. X
  1680. X    msg = &rp->r_msg;
  1681. X    rmt_showmsg(msg, TRUE);
  1682. X    if ((error = msg->m_errno) == 0)
  1683. X        u.u_r.r_val1 = msg->m_args[R_RETVAL];
  1684. Xdone:
  1685. X    if (m)
  1686. X        m_free(m);
  1687. X    return ( error );
  1688. X}
  1689. X
  1690. X/*
  1691. X * Copy a path into a string of mbufs.  The source pointer may be in user
  1692. X * space, in which case we must use uchar() to copy.  Note that this routine
  1693. X * expects 'm' to point to the first mbuf in the current chain:  it will
  1694. X * append to the end of the chain, and update the length of the message
  1695. X * in msg->m_hdlen.
  1696. X */
  1697. Xrmt_copypath(psrc, m, copy_from_user)
  1698. X    register char    *psrc;
  1699. X    register struct mbuf    *m;
  1700. X{
  1701. X    register char    *pdest;
  1702. X    register int    error,
  1703. X            totlen,
  1704. X            room;
  1705. X    register struct mbuf    *m2;
  1706. X    struct message    *msg = mtod(m, struct message *);
  1707. X    int        copystr(),
  1708. X            copyinstr(),
  1709. X            got;
  1710. X    func        copier = copy_from_user ? copyinstr : copystr;
  1711. X
  1712. X    /*
  1713. X     * find the end of the mbuf chain.
  1714. X     */
  1715. X    while (m->m_next)
  1716. X        m = m->m_next;
  1717. X    m2 = m;
  1718. X    pdest = mtod(m, char *) + m->m_len;
  1719. X    totlen = msg->m_hdlen;
  1720. X
  1721. X    debug2("copy %s path @%x-->%x, len=%d\n",
  1722. X        copy_from_user ? "user" : "kernel", psrc, pdest, totlen);
  1723. X
  1724. X    room = MLEN - m->m_len;
  1725. X    for(;;) {
  1726. X        got = 0;    /* copy*str adds copied bytes to 'got' */
  1727. X        error = (*copier)(psrc, pdest, room, (u_int *)&got);
  1728. X        if (error && error != ENOENT)
  1729. X            return(error);
  1730. X        m2->m_len += got;
  1731. X        totlen += got;
  1732. X        if (got < room)
  1733. X            break;
  1734. X        MGET(m, M_WAIT, MT_DATA);
  1735. X        if (m == NULL)
  1736. X            return(ENOBUFS);
  1737. X        m2 = m2->m_next = m;
  1738. X        m2->m_len = 0;
  1739. X        room = MLEN;
  1740. X        pdest = mtod(m2, char *);
  1741. X        psrc += got;
  1742. X    }
  1743. X    msg->m_hdlen = totlen;
  1744. X    debug2("len now=%d\n", totlen);
  1745. X
  1746. X    return(0);
  1747. X}
  1748. X
  1749. X#ifdef BSD4_3
  1750. X#else BSD4_3
  1751. X/*
  1752. X * C version of copyinstr() from 4.3.
  1753. X */
  1754. Xcopyinstr(src, dest, maxlength, lencopied)
  1755. X    register char    *src, *dest;
  1756. X    register int    maxlength;
  1757. X    register int    *lencopied;
  1758. X{
  1759. X    register int    c;
  1760. X    int        dummy;
  1761. X
  1762. X    if (!maxlength)
  1763. X        return(EFAULT);
  1764. X    if (lencopied == NULL)
  1765. X        lencopied = &dummy;
  1766. X    for(;;) {
  1767. X        c = *dest++ = fubyte(src++);
  1768. X        if (c == -1) {
  1769. X            *(dest-1) = 0;
  1770. X            return(EFAULT);
  1771. X        }
  1772. X        if (--maxlength < 0)
  1773. X            return(ENOENT);
  1774. X        (*lencopied)++;
  1775. X        if (c == 0)
  1776. X            return(0);
  1777. X    }
  1778. X}
  1779. X
  1780. X/*
  1781. X * C version of copystr() from 4.3.
  1782. X */
  1783. Xcopystr(src, dest, maxlength, lencopied)
  1784. X    register char    *src, *dest;
  1785. X    register int    maxlength;
  1786. X    register int    *lencopied;
  1787. X{
  1788. X    int        dummy;
  1789. X
  1790. X    if (!maxlength)
  1791. X        return(EFAULT);
  1792. X    if (lencopied == NULL)
  1793. X        lencopied = &dummy;
  1794. X    for(;;) {
  1795. X        if (--maxlength < 0)
  1796. X            return(ENOENT);
  1797. X        (*lencopied)++;
  1798. X        if ((*dest++ = *src++) == 0)
  1799. X            return(0);
  1800. X    }
  1801. X}
  1802. X#endif BSD4_3
  1803. X
  1804. X#ifdef RFSDEBUG
  1805. X
  1806. Xrmt_debug(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  1807. X{
  1808. X    printf(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  1809. X}
  1810. X
  1811. Xrmt_showmsg(msg, fromserver)
  1812. X    struct message    *msg;
  1813. X    int    fromserver;
  1814. X{
  1815. X    long    end, len, pid, uid, totlen;
  1816. X
  1817. X    if ((remote_debug & 0x18000) == 0)
  1818. X        return;
  1819. X    if (fromserver)
  1820. X        len = msg->m_hdlen,
  1821. X        totlen = msg->m_totlen,
  1822. X        pid = msg->m_pid,
  1823. X        uid = msg->m_uid;
  1824. X    else
  1825. X        len = ntohs(msg->m_hdlen),
  1826. X        totlen = ntohl(msg->m_totlen),
  1827. X        pid = ntohs(msg->m_pid),
  1828. X        uid = ntohs(msg->m_uid);
  1829. X    debug15("%s srvr: len=%d,tot=%d,pid=%d,uid=%d",
  1830. X        fromserver ? "from" : "to", len, totlen, pid, uid);
  1831. X
  1832. X    /* round up into long words */
  1833. X    len = (len - R_MINRMSG + 3) >> 2;
  1834. X    if (fromserver)
  1835. X    {
  1836. X        debug15(",err=%d,ret=%d",
  1837. X            msg->m_errno,
  1838. X            msg->m_args[ R_RETVAL ]);
  1839. X        end = R_RETVAL+1;
  1840. X    }
  1841. X    else
  1842. X    {
  1843. X        debug15(",syscall=%d", htons(msg->m_syscall));
  1844. X        end = 0;
  1845. X    }
  1846. X    for (; end<len; end++)
  1847. X        debug16(",0x%x", ntohl(msg->m_args[ end ]));
  1848. X    rmt_debug("\n");
  1849. X}
  1850. X#endif RFSDEBUG
  1851. SHAREOF
  1852. chmod 444 remote/usr.sys.remote/rmt_final.c
  1853. #
  1854. # remote/usr.sys.remote/rmt_syscall3.c
  1855. #
  1856. if [ -f remote/usr.sys.remote/rmt_syscall3.c ]; then 
  1857.     echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_syscall3.c or ^C to quit' 
  1858.     read ans 
  1859.     rm -f remote/usr.sys.remote/rmt_syscall3.c 
  1860. fi 
  1861.  
  1862. sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_syscall3.c
  1863. X/*
  1864. X * Copyright 1985, Todd Brunhoff.
  1865. X *
  1866. X * This software was written at Tektronix Computer Research Laboratories
  1867. X * as partial fulfillment of a Master's degree at the University of Denver.
  1868. X * This is not Tektronix proprietary software and should not be
  1869. X * confused with any software product sold by Tektronix.  No warranty is
  1870. X * expressed or implied on the reliability of this software; the author,
  1871. X * the University of Denver, and Tektronix, inc. accept no liability for
  1872. X * any damage done directly or indirectly by this software.  This software
  1873. X * may be copied, modified or used in any way, without fee, provided this
  1874. X * notice remains an unaltered part of the software.
  1875. X *
  1876. X * $Header: rmt_syscall3.c,v 2.0 85/12/07 18:19:35 toddb Rel $
  1877. X *
  1878. X * $Log:    rmt_syscall3.c,v $
  1879. X * Revision 2.0  85/12/07  18:19:35  toddb
  1880. X * First public release.
  1881. X * 
  1882. X */
  1883. X#include    "../h/param.h"
  1884. X#ifndef pyr    /* Pyramid */
  1885. X#include    "../machine/pte.h"
  1886. X#endif
  1887. X#include    "../h/systm.h"
  1888. X#include    "../h/map.h"
  1889. X#include    "../h/dir.h"
  1890. X#include    "../h/user.h"
  1891. X#include    "../h/kernel.h"
  1892. X#include    "../h/proc.h"
  1893. X#include    "../h/inode.h"
  1894. X#include    "../h/mbuf.h"
  1895. X#include    "../h/socket.h"
  1896. X#include    "../remote/remotefs.h"
  1897. X#include    "../h/file.h"
  1898. X#include    "../h/stat.h"
  1899. X#include    "../h/errno.h"
  1900. X#include    "../netinet/in.h"
  1901. X
  1902. Xextern long    rmtrw(), rmtioctl(), rmtselect(), rmtclose();
  1903. Xstruct     fileops remoteops =
  1904. X    { rmtrw, rmtioctl, rmtselect, rmtclose };
  1905. Xrmtrw()    { return(0); }
  1906. Xrmtioctl()    { return(0); }
  1907. Xrmtselect()    { return(0); }
  1908. Xrmtclose()    { return(0); }
  1909. X
  1910. Xextern struct remoteinfo    remote_info[];
  1911. Xextern struct remoteinfo    *remote_generic;
  1912. X
  1913. X/*
  1914. X * Remote open()
  1915. X */
  1916. Xrmt_open (sysindex, m)
  1917. X    long    sysindex;
  1918. X    struct mbuf    *m;
  1919. X{
  1920. X    register long    fd, error;
  1921. X    register struct message *msg = mtod(m, struct message *);
  1922. X    register struct file    *fp;
  1923. X    struct file        *falloc();
  1924. X    register struct a {
  1925. X        char    *path;
  1926. X        long    flags,
  1927. X            mode;
  1928. X    } *uap = (struct a *)u.u_ap;
  1929. X
  1930. X    /*
  1931. X     * Initialize the file structure.
  1932. X     */
  1933. X    if ((fp = falloc()) == NULL)
  1934. X        return(-1);
  1935. X    fp->f_type = DTYPE_REMOTE;
  1936. X    fp->f_ops = &remoteops;
  1937. X    fd = u.u_r.r_val1;
  1938. X    fp->f_data = (caddr_t)sysindex;
  1939. X    fp->f_flag = (uap->mode&FMASK) | FREMOTE;
  1940. X    remote_info[ sysindex ].r_nfile++;
  1941. X
  1942. X    if (ntohs(msg->m_syscall) == RSYS_creat) {
  1943. X        uap->mode = uap->flags;
  1944. X        uap->flags = FWRITE|FCREAT|FTRUNC;
  1945. X        msg->m_syscall = htons(RSYS_open);
  1946. X    }
  1947. X    msg->m_args[ 0 ] = htonl(uap->flags);
  1948. X    msg->m_args[ 1 ] = htonl(uap->mode);
  1949. X    msg->m_args[ 2 ] = htonl(fd);
  1950. X    msg->m_args[ 3 ] = htonl(u.u_cmask);
  1951. X
  1952. X    /*
  1953. X     * Now send it.
  1954. X     */
  1955. X    error = rmt_msgfin(sysindex, m, 0);
  1956. X    if (error)
  1957. X        rmt_deallocfd(fd);
  1958. X    else {
  1959. X        msg = &remote_info[ sysindex ].r_msg;
  1960. X        fp->f_offset = msg->m_args[1];
  1961. X    }
  1962. X    return(error);
  1963. X}
  1964. X
  1965. X/*
  1966. X * Remote readlink()
  1967. X */
  1968. Xrmt_readlink (sysindex, m)
  1969. X    long    sysindex;
  1970. X    struct mbuf    *m;
  1971. X{
  1972. X    struct message    *msg = mtod(m, struct message *);
  1973. X    struct a {
  1974. X        char    *path;
  1975. X        char    *buf;
  1976. X        long    len;
  1977. X    } *uap = (struct a *)u.u_ap;
  1978. X
  1979. X
  1980. X    msg->m_args[ 0 ] = htonl(uap->len);
  1981. X    /*
  1982. X     * Now send it.
  1983. X     */
  1984. X    return( rmt_datafin(sysindex, m, RFLG_RD) );
  1985. X}
  1986. X
  1987. X/*
  1988. X * Remote stat() and lstat() and fstat()
  1989. X */
  1990. Xrmt_stat (sysindex, m)
  1991. X    long    sysindex;
  1992. X    struct mbuf    *m;
  1993. X{
  1994. X    long    error, i;
  1995. X    struct message *msg = mtod(m, struct message *);
  1996. X    struct remoteinfo *rp = remote_info + sysindex;
  1997. X    struct a {
  1998. X        long    fd_or_path;
  1999. X        struct stat    *statp;
  2000. X    } *uap = (struct a *)u.u_ap;
  2001. X    struct stat    st;
  2002. X
  2003. X    if (ntohl(msg->m_syscall) == RSYS_fstat)
  2004. X        m->m_len = R_MINRMSG + sizeof(long);
  2005. X    if (error = rmt_msgfin(sysindex, m, 0))
  2006. X        return( error );
  2007. X    msg = &rp->r_msg;
  2008. X    i = R_RETVAL + 1;
  2009. X    st.st_dev      = ntohl(msg->m_args[ i++ ]);
  2010. X    st.st_ino      = ntohl(msg->m_args[ i++ ]);
  2011. X    st.st_mode      = ntohl(msg->m_args[ i++ ]);
  2012. X    st.st_nlink      = ntohl(msg->m_args[ i++ ]);
  2013. X    st.st_uid      = ntohl(msg->m_args[ i++ ]);
  2014. X    st.st_gid      = ntohl(msg->m_args[ i++ ]);
  2015. X    st.st_rdev      = ntohl(msg->m_args[ i++ ]);
  2016. X    st.st_size      = ntohl(msg->m_args[ i++ ]);
  2017. X    st.st_atime      = ntohl(msg->m_args[ i++ ]);
  2018. X    st.st_mtime      = ntohl(msg->m_args[ i++ ]);
  2019. X    st.st_ctime      = ntohl(msg->m_args[ i++ ]);
  2020. X    st.st_blksize      = ntohl(msg->m_args[ i++ ]);
  2021. X    st.st_blocks       = ntohl(msg->m_args[ i++ ]);
  2022. X    st.st_spare1 = sysindex+1;
  2023. X    st.st_spare2 = 0;
  2024. X    st.st_spare3 = 0;
  2025. X    st.st_spare4[0] = st.st_spare4[1] = 0;
  2026. X    if (msg->m_args[ i ]) { /* this is the remote root */
  2027. X        if (rp->r_mntpt == NULL)
  2028. X            rp = remote_generic;
  2029. X        if (rp && rp->r_mntpt != NULL) {
  2030. X            st.st_dev = rp->r_mntpt->i_dev;
  2031. X            st.st_ino = rp->r_mntpt->i_number;
  2032. X        }
  2033. X    }
  2034. X    (void)copyout((caddr_t)&st, (caddr_t)uap->statp, sizeof(struct stat));
  2035. X    return(0);
  2036. X}
  2037. X
  2038. X/*
  2039. X * Remote truncate() and ftrucate()
  2040. X */
  2041. Xrmt_truncate (sysindex, m)
  2042. X    long    sysindex;
  2043. X    struct mbuf    *m;
  2044. X{
  2045. X    long    i = 0;
  2046. X    struct message *msg = mtod(m, struct message *);
  2047. X    struct a {
  2048. X        long    fd_or_path;
  2049. X        long    len;
  2050. X    } *uap = (struct a *)u.u_ap;
  2051. X
  2052. X    if (htons(msg->m_syscall) == RSYS_ftruncate)
  2053. X        i++;
  2054. X    msg->m_args[ i ] = htonl(uap->len);
  2055. X    /*
  2056. X     * Now send it.
  2057. X     */
  2058. X    return( rmt_msgfin(sysindex, m, 0) );
  2059. X}
  2060. X
  2061. X/*
  2062. X * Remote utimes()
  2063. X */
  2064. Xrmt_utimes (sysindex, m)
  2065. X    long    sysindex;
  2066. X    struct mbuf    *m;
  2067. X{
  2068. X    struct message    *msg = mtod(m, struct message *);
  2069. X    struct a {
  2070. X        char    *path;
  2071. X        struct timeval    *timevalp;
  2072. X    } *uap = (struct a *)u.u_ap;
  2073. X    struct timeval    *tv = uap->timevalp;
  2074. X
  2075. X    msg->m_args[ 0 ] = htonl(tv[0].tv_sec);
  2076. X    msg->m_args[ 1 ] = htonl(tv[0].tv_usec);
  2077. X    msg->m_args[ 2 ] = htonl(tv[1].tv_sec);
  2078. X    msg->m_args[ 3 ] = htonl(tv[1].tv_usec);
  2079. X
  2080. X    /*
  2081. X     * Now send it.
  2082. X     */
  2083. X    return( rmt_msgfin(sysindex, m, 0) );
  2084. X}
  2085. SHAREOF
  2086. chmod 444 remote/usr.sys.remote/rmt_syscall3.c
  2087.  
  2088.