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

  1. Subject: RFS: remote file system (part 3 of 7)
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 3, Issue 79
  6. Submitted by: tektronix!tekcrl!toddb
  7.  
  8. #!/bin/sh
  9. #
  10. # RFS, a kernel-resident remote file system.  Shar 3 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/list.c
  18. #    remote/make.base
  19. #    remote/make.base.M68
  20. #    remote/make.base.magnolia
  21. #    remote/make.base.pyramid
  22. #    remote/make.base.vax
  23. #    remote/make.base.vaxnorfs
  24. #    remote/new.c
  25. #    remote/newinit.c
  26. #    remote/rhost.c
  27. #    remote/rmtmnt.c
  28. #    remote/route.c
  29. #    remote/server.h
  30. #    remote/serverdata.c
  31. #    remote/serverdir.c
  32. #
  33. # remote/list.c
  34. #
  35. if [ -f remote/list.c ]; then 
  36.     echo -n 'Hit <return> to overwrite remote/list.c or ^C to quit' 
  37.     read ans 
  38.     rm -f remote/list.c 
  39. fi 
  40.  
  41. sed -e 's/^.//' << \SHAREOF > remote/list.c
  42. X/*
  43. X * Copyright 1985, Todd Brunhoff.
  44. X *
  45. X * This software was written at Tektronix Computer Research Laboratories
  46. X * as partial fulfillment of a Master's degree at the University of Denver.
  47. X * This is not Tektronix proprietary software and should not be
  48. X * confused with any software product sold by Tektronix.  No warranty is
  49. X * expressed or implied on the reliability of this software; the author,
  50. X * the University of Denver, and Tektronix, inc. accept no liability for
  51. X * any damage done directly or indirectly by this software.  This software
  52. X * may be copied, modified or used in any way, without fee, provided this
  53. X * notice remains an unaltered part of the software.
  54. X *
  55. X * $Log:    list.c,v $
  56. X * Revision 2.0  85/12/07  18:21:44  toddb
  57. X * First public release.
  58. X * 
  59. X */
  60. Xstatic char    *rcsid = "$Header: list.c,v 2.0 85/12/07 18:21:44 toddb Rel $";
  61. X#include    "server.h"
  62. X#include    <stdio.h>
  63. X
  64. X/*
  65. X * Stick a new item of any type on top of the list.
  66. X */
  67. Xl_list *addlist(list, item)
  68. X    register l_list    **list;
  69. X    register l_list    *item;
  70. X{
  71. X    item->l_next = *list;
  72. X    if (*list)
  73. X    {
  74. X        item->l_prev = (*list)->l_prev;
  75. X        (*list)->l_prev = item;
  76. X    }
  77. X    else
  78. X        item->l_prev = item;
  79. X    *list = item;
  80. X    return(item);
  81. X}
  82. X
  83. X/*
  84. X * delete an item from a list.  The item itself is left intact.  It is
  85. X * the responsibility of the caller to deal with the deleted item.
  86. X */
  87. Xl_list *deletelist(list, item)
  88. X    register l_list    **list;
  89. X    register l_list    *item;
  90. X{
  91. X    if (item == *list)
  92. X    {
  93. X        if (item->l_next == NULL)
  94. X            *list = NULL;
  95. X        else
  96. X        {
  97. X            *list = item->l_next;
  98. X            item->l_next->l_prev = item->l_next;
  99. X        }
  100. X    }
  101. X    else
  102. X    {
  103. X        item->l_prev->l_next = item->l_next;
  104. X        if (item->l_next != NULL)
  105. X            item->l_next->l_prev = item->l_prev;
  106. X    }
  107. X    return (*list);
  108. X}
  109. X
  110. X/*
  111. X * stick 'item' at the top of the 'list' ( if it isn't there
  112. X * already.
  113. X */
  114. Xl_list *toplist(list, item)
  115. X    register l_list    **list;
  116. X    register l_list    *item;
  117. X{
  118. X    if (item == *list)
  119. X        return;
  120. X    item->l_prev->l_next = item->l_next;
  121. X    if (item->l_next)
  122. X        item->l_next->l_prev = item->l_prev;
  123. X    item->l_next = (*list);
  124. X    /*
  125. X     * if our target is the last on the list, then
  126. X     * be careful that we don't make a cycle.  Since
  127. X     * we want the head of the list's l_prev pointer
  128. X     * to point to the last in the list, we don't
  129. X     * have to do anything.
  130. X     */
  131. X    if (item != (*list)->l_prev) /* NOT last on list */
  132. X        item->l_prev = (*list)->l_prev;
  133. X    (*list)->l_prev = item;
  134. X    *list = item;
  135. X}
  136. SHAREOF
  137. chmod 444 remote/list.c
  138. #
  139. # remote/make.base
  140. #
  141. if [ -f remote/make.base ]; then 
  142.     echo -n 'Hit <return> to overwrite remote/make.base or ^C to quit' 
  143.     read ans 
  144.     rm -f remote/make.base 
  145. fi 
  146.  
  147. sed -e 's/^.//' << \SHAREOF > remote/make.base
  148. XSOBJS      = change.$O file.$O fileserver.$O find.$O \
  149. X        info.$O init.$O list.$O new.$O \
  150. X        rhost.$O route.$O serverdata.$O serverdir.$O serverio.$O \
  151. X        serversyscall.$O
  152. XCFILES     = change.c file.c fileserver.c find.c \
  153. X        info.c init.c list.c new.c \
  154. X        rhost.c route.c serverdata.c serverdir.c serverio.c \
  155. X        serversyscall.c
  156. X
  157. Xall: $(ALL)
  158. X
  159. X$(RFS_SERVER): $(SOBJS)
  160. X    $(CC) -o $@ $(SOBJS) $(LDFLAGS)
  161. X    $(XINU) $(RFS_SERVER)
  162. X$(RMTMNT): rmtmnt.$O
  163. X    $(CC) -o $@ rmtmnt.$O $(LDFLAGS)
  164. X    $(XINU) $(RMTMNT)
  165. X$(DEBUG): debug.$O
  166. X    $(CC) -o $@ debug.$O $(LDFLAGS)
  167. X    $(XINU) $(DEBUG)
  168. Xtags: $(CFILES)
  169. X    ctags $(CFILES) $(INCLUDE)
  170. X$(SOBJS): $(INCLUDE)
  171. X
  172. Xinstall: all
  173. X    $(INSTALL) -c -m 755 $(RFS_SERVER) $(DEST)/etc/rfs_server
  174. X    $(INSTALL_RMTMNT) -c -m 0755 $(RMTMNT) $(DEST)/etc/rmtmnt
  175. SHAREOF
  176. chmod 664 remote/make.base
  177. #
  178. # remote/make.base.M68
  179. #
  180. if [ -f remote/make.base.M68 ]; then 
  181.     echo -n 'Hit <return> to overwrite remote/make.base.M68 or ^C to quit' 
  182.     read ans 
  183.     rm -f remote/make.base.M68 
  184. fi 
  185.  
  186. sed -e 's/^.//' << \SHAREOF > remote/make.base.M68
  187. XDEST           = /usr3/mag
  188. XHOST           =
  189. XINCLUDE        = $(DEST)/usr/include/remote/remotefs.h server.h
  190. XCFLAGS         = -G$(HOST) -O -DRFSDEBUG -DCANREMOTE -DBYTEORDER=3,2,1,0 -DREMOTEFS -DMACHTYPE=magnolia
  191. XLDFLAGS        = -z
  192. XCC             = cc68
  193. XO           = b
  194. XRFS_SERVER     = rfs_server.x
  195. XRMTMNT         = rmtmnt.x
  196. XDEBUG          = debug.x
  197. XINSTALL_RMTMNT = install68
  198. XINSTALL        = install68
  199. XALL           = $(RFS_SERVER) $(RMTMNT)
  200. XXINU           = xinu68
  201. X
  202. X.SUFFIXES:
  203. X.SUFFIXES: .b .c
  204. X
  205. X.c.b:
  206. X    $(CC) $(CFLAGS) $< -c
  207. SHAREOF
  208. chmod 664 remote/make.base.M68
  209. #
  210. # remote/make.base.magnolia
  211. #
  212. if [ -f remote/make.base.magnolia ]; then 
  213.     echo -n 'Hit <return> to overwrite remote/make.base.magnolia or ^C to quit' 
  214.     read ans 
  215.     rm -f remote/make.base.magnolia 
  216. fi 
  217.  
  218. sed -e 's/^.//' << \SHAREOF > remote/make.base.magnolia
  219. XHOST           = tekcrl
  220. XINCLUDE        = /usr/include/remote/remotefs.h server.h
  221. XO              = o
  222. XCFLAGS         = -G$(HOST) -O -DRFSDEBUG -DCANREMOTE -DBYTEORDER=3,2,1,0 -DREMOTEFS
  223. XLDFLAGS        = -z
  224. XRFS_SERVER     = rfs_server
  225. XRMTMNT         = rmtmnt
  226. XDEBUG          = debug
  227. XINSTALL        = install68
  228. XINSTALL_RMTMNT = install68
  229. XDEST           =
  230. XCC           = cc
  231. XALL           = $(RFS_SERVER) $(RMTMNT)
  232. XXINU           = :
  233. SHAREOF
  234. chmod 664 remote/make.base.magnolia
  235. #
  236. # remote/make.base.pyramid
  237. #
  238. if [ -f remote/make.base.pyramid ]; then 
  239.     echo -n 'Hit <return> to overwrite remote/make.base.pyramid or ^C to quit' 
  240.     read ans 
  241.     rm -f remote/make.base.pyramid 
  242. fi 
  243.  
  244. sed -e 's/^.//' << \SHAREOF > remote/make.base.pyramid
  245. XINCLUDE        = ../usr.include/remote/remotefs.h server.h
  246. XO              = o
  247. XLDFLAGS        = -z
  248. XRFS_SERVER     = rfs_server
  249. XINS_RFS_SERVER = rfs_server
  250. XRMTMNT         = rmtmnt
  251. XDEBUG          = debug
  252. XINSTALL_RMTMNT = install
  253. XINSTALL        = install
  254. XDEST           =
  255. XCC             = cc
  256. XALL           = $(RFS_SERVER) $(RMTMNT)
  257. XXINU           = :
  258. XDEFINES        = -DRFSDEBUG -DCANREMOTE -DBYTEORDER=3,2,1,0 -DREMOTEFS -I/usr/include/sys
  259. XCFLAGS         = -O ${DEFINES} -I../usr.include
  260. SHAREOF
  261. chmod 644 remote/make.base.pyramid
  262. #
  263. # remote/make.base.vax
  264. #
  265. if [ -f remote/make.base.vax ]; then 
  266.     echo -n 'Hit <return> to overwrite remote/make.base.vax or ^C to quit' 
  267.     read ans 
  268.     rm -f remote/make.base.vax 
  269. fi 
  270.  
  271. sed -e 's/^.//' << \SHAREOF > remote/make.base.vax
  272. XINCLUDE        = ../usr.include/remote/remotefs.h server.h
  273. XO              = o
  274. XLDFLAGS        = -z
  275. XRFS_SERVER     = rfs_server
  276. XINS_RFS_SERVER = rfs_server
  277. XRMTMNT         = rmtmnt
  278. XDEBUG          = debug
  279. XINSTALL_RMTMNT = install
  280. XINSTALL        = install
  281. XDEST           =
  282. XCC             = cc
  283. XALL           = $(RFS_SERVER) $(RMTMNT)
  284. XXINU           = :
  285. XDEFINES        = -DRFSDEBUG -DCANREMOTE -DBYTEORDER=0,1,2,3 -DREMOTEFS
  286. XCFLAGS         = -O ${DEFINES} -I../usr.include
  287. SHAREOF
  288. chmod 664 remote/make.base.vax
  289. #
  290. # remote/make.base.vaxnorfs
  291. #
  292. if [ -f remote/make.base.vaxnorfs ]; then 
  293.     echo -n 'Hit <return> to overwrite remote/make.base.vaxnorfs or ^C to quit' 
  294.     read ans 
  295.     rm -f remote/make.base.vaxnorfs 
  296. fi 
  297.  
  298. sed -e 's/^.//' << \SHAREOF > remote/make.base.vaxnorfs
  299. XINCLUDE        = ../usr.include/remote/remotefs.h server.h
  300. XO              = o
  301. XLDFLAGS        = -z
  302. XRFS_SERVER     = rfs_server
  303. XINS_RFS_SERVER = rfs_server
  304. XRMTMNT         = rmtmnt
  305. XDEBUG          = debug
  306. XINSTALL_RMTMNT = :
  307. XINSTALL        = install
  308. XDEST           =
  309. XCC             = cc
  310. XALL           = $(RFS_SERVER)
  311. XXINU           = :
  312. XCFLAGS         = -O -DRFSDEBUG -DBYTEORDER=0,1,2,3 -DNREMOTE=1 -I../usr.include
  313. SHAREOF
  314. chmod 664 remote/make.base.vaxnorfs
  315. #
  316. # remote/new.c
  317. #
  318. if [ -f remote/new.c ]; then 
  319.     echo -n 'Hit <return> to overwrite remote/new.c or ^C to quit' 
  320.     read ans 
  321.     rm -f remote/new.c 
  322. fi 
  323.  
  324. sed -e 's/^.//' << \SHAREOF > remote/new.c
  325. X/*
  326. X * Copyright 1985, Todd Brunhoff.
  327. X *
  328. X * This software was written at Tektronix Computer Research Laboratories
  329. X * as partial fulfillment of a Master's degree at the University of Denver.
  330. X * This is not Tektronix proprietary software and should not be
  331. X * confused with any software product sold by Tektronix.  No warranty is
  332. X * expressed or implied on the reliability of this software; the author,
  333. X * the University of Denver, and Tektronix, inc. accept no liability for
  334. X * any damage done directly or indirectly by this software.  This software
  335. X * may be copied, modified or used in any way, without fee, provided this
  336. X * notice remains an unaltered part of the software.
  337. X *
  338. X * $Log:    new.c,v $
  339. X * Revision 2.0  85/12/07  18:21:48  toddb
  340. X * First public release.
  341. X * 
  342. X */
  343. Xstatic char    *rcsid = "$Header: new.c,v 2.0 85/12/07 18:21:48 toddb Rel $";
  344. X#include    "server.h"
  345. X#include    <stdio.h>
  346. X
  347. Xextern short    current_pid;
  348. Xextern hosts    *host;
  349. X
  350. Xusers *newuser()
  351. X{
  352. X    register users    *user;
  353. X
  354. X    user = (users *)malloc(sizeof(users));
  355. X    if (user == NULL)
  356. X        log_fatal("cannot allocate space\n");
  357. X    bzero(user, sizeof(users));
  358. X    return(user);
  359. X}
  360. X
  361. Xhosts *newhost()
  362. X{
  363. X    register hosts    *h;
  364. X
  365. X    h = (hosts *)malloc(sizeof(hosts));
  366. X    if (h == NULL)
  367. X        log_fatal("cannot allocate space\n");
  368. X    bzero(h, sizeof(hosts));
  369. X    h->h_cmdfd = -1;
  370. X    return(h);
  371. X}
  372. X
  373. Xrusers *newruser()
  374. X{
  375. X    register rusers    *ruser;
  376. X
  377. X    ruser = (rusers *)malloc(sizeof(rusers));
  378. X    if (ruser == NULL)
  379. X        log_fatal("cannot allocate space\n");
  380. X    bzero(ruser, sizeof(rusers));
  381. X    return(ruser);
  382. X}
  383. X
  384. Xprocess *newprocess()
  385. X{
  386. X    register process    *p;
  387. X
  388. X    p = (process *)malloc(sizeof(process));
  389. X    if (p == NULL)
  390. X        log_fatal("cannot allocate space\n");
  391. X    bzero(p, sizeof(process));
  392. X    return(p);
  393. X}
  394. X
  395. Xfreeproc(p)
  396. X    register process *p;
  397. X{
  398. X    if (p->p_execfd >= 0)
  399. X        close(p->p_execfd);
  400. X    free(p);
  401. X}
  402. X
  403. Xchar    **newname(namelist, name)
  404. X    register char    **namelist;
  405. X    register char    *name;
  406. X{
  407. X    register long    i = 0;
  408. X
  409. X    if (namelist == NULL)
  410. X        namelist = (char **)malloc(sizeof(char *) * 2);
  411. X    else
  412. X    {
  413. X        /*
  414. X         * count the elements in the list now.
  415. X         */
  416. X        for (i=0; namelist && namelist[i]; i++) ;
  417. X
  418. X        namelist = (char **)realloc(namelist, sizeof(char *) * (i+2));
  419. X    }
  420. X    namelist[ i++ ] = copy(name);
  421. X    namelist[ i ] = NULL;
  422. X    return(namelist);
  423. X}
  424. X
  425. X/*
  426. X * Add a group to 'user' unless he has exceeded the limit or the group
  427. X * is already in his domain.
  428. X */
  429. Xaddgroup(user, gid)
  430. X    register users    *user;
  431. X    register short    gid;
  432. X{
  433. X    register long    i = 0,
  434. X            *gr = user->u_local_groups;
  435. X
  436. X    for (i=0; i < user->u_numgroups; i++)
  437. X        if (gr[ i ] == gid)
  438. X            return;
  439. X    if (i >= NGROUPS)
  440. X        return;
  441. X    gr[ user->u_numgroups++ ] = gid;
  442. X}
  443. X
  444. Xprocess *add_new_process(uid, pid)
  445. X    register short    uid, pid;
  446. X{
  447. X    register process    *p;
  448. X    register long    i;
  449. X
  450. X    debug0("allocate new proc: pid=%d uid=%d host=%s\n",
  451. X        pid, uid, host->h_names[0]);
  452. X    setup_proc(p = newprocess(), uid, pid);
  453. X    addlist(&host->h_proclist, p);
  454. X
  455. X    /*
  456. X     * Initialize the file descriptors for this process.
  457. X     */
  458. X    for(i=0; i<NOFILE; i++)
  459. X        p->p_fds[ i ] = 0x80;    /* -128 */
  460. X
  461. X    return(p);
  462. X}
  463. X
  464. Xsetup_proc(proc, uid, pid)
  465. X    register process    *proc;
  466. X    register short    uid, pid;
  467. X{
  468. X    register rusers    *ruser;
  469. X
  470. X    proc->p_pid = pid;
  471. X    proc->p_uid = uid;
  472. X    proc->p_handler = current_pid;
  473. X    proc->p_returnval = 0;
  474. X    proc->p_execfd = -1;
  475. X    if (ruser = findremuid(&host->h_rusers, uid))
  476. X        proc->p_ruser = ruser;
  477. X    else
  478. X        proc->p_ruser = host->h_default_ruser;
  479. X}
  480. SHAREOF
  481. chmod 444 remote/new.c
  482. #
  483. # remote/newinit.c
  484. #
  485. if [ -f remote/newinit.c ]; then 
  486.     echo -n 'Hit <return> to overwrite remote/newinit.c or ^C to quit' 
  487.     read ans 
  488.     rm -f remote/newinit.c 
  489. fi 
  490.  
  491. sed -e 's/^.//' << \SHAREOF > remote/newinit.c
  492. X/*
  493. X * Copyright 1985, Todd Brunhoff.
  494. X *
  495. X * This software was written at Tektronix Computer Research Laboratories
  496. X * as partial fulfillment of a Master's degree at the University of Denver.
  497. X * This is not Tektronix proprietary software and should not be
  498. X * confused with any software product sold by Tektronix.  No warranty is
  499. X * expressed or implied on the reliability of this software; the author,
  500. X * the University of Denver, and Tektronix, inc. accept no liability for
  501. X * any damage done directly or indirectly by this software.  This software
  502. X * may be copied, modified or used in any way, without fee, provided this
  503. X * notice remains an unaltered part of the software.
  504. X *
  505. X * $Log:    init.c,v $
  506. X * Revision 2.0  85/12/07  18:21:37  toddb
  507. X * First public release.
  508. X * 
  509. X */
  510. Xstatic char    *rcsid = "$Header: init.c,v 2.0 85/12/07 18:21:37 toddb Rel $";
  511. X#include    "server.h"
  512. X#include    <stdio.h>
  513. X#include    <pwd.h>
  514. X#include    <grp.h>
  515. X#include    <netdb.h>
  516. X#include    <fcntl.h>
  517. X#include    <sys/dir.h>
  518. X#include    <sys/user.h>
  519. X#include    <sys/signal.h>
  520. X#include    <sys/ioctl.h>
  521. X
  522. Xextern hosts    *hostlist;
  523. Xextern hosts    *thishost;
  524. Xextern users    *userlist;
  525. Xextern users    *default_user;
  526. Xextern char    hostname[];
  527. Xextern char    *service;
  528. Xextern short    current_uid;
  529. Xextern short    current_pid;
  530. Xextern process    *wildcard;
  531. Xextern struct sigvec    sig_vec;
  532. Xextern struct sigvec    sig_name;
  533. Xextern struct sigvec    sig_alarm;
  534. Xextern struct sigvec    sig_ignore;
  535. Xextern struct sigvec    sig_continue;
  536. X#ifdef RFSDEBUG
  537. Xextern struct sigvec    sig_debug;
  538. X#endif
  539. Xextern struct stat    root;
  540. X
  541. X/*
  542. X * Initialize the host tables and user tables.
  543. X */
  544. Xinit()
  545. X{
  546. X    long    tt;
  547. X    struct hostent    *gethostent();
  548. X    struct passwd    *getpwent();
  549. X    struct group    *getgrent();
  550. X
  551. X    /*
  552. X     * catch signals.
  553. X     */
  554. X    sigvec(SIGHUP, &sig_ignore, (struct sigvec *)0);
  555. X    sigvec(SIGINT, &sig_vec, (struct sigvec *)0);
  556. X    sigvec(SIGQUIT, &sig_vec, (struct sigvec *)0);
  557. X    sigvec(SIGILL, &sig_vec, (struct sigvec *)0);
  558. X#ifdef RFSDEBUG
  559. X    sigvec(SIGTRAP, &sig_debug, (struct sigvec *)0);
  560. X#endif RFSDEBUG
  561. X    /*    SIGIOT        */
  562. X    /*    SIGEMT        */
  563. X    /*    SIGFPE        */
  564. X    /*    SIGKILL        */
  565. X    sigvec(SIGBUS, &sig_vec, (struct sigvec *)0);
  566. X    sigvec(SIGSEGV, &sig_vec, (struct sigvec *)0);
  567. X    sigvec(SIGSYS, &sig_vec, (struct sigvec *)0);
  568. X    sigvec(SIGPIPE, &sig_vec, (struct sigvec *)0);
  569. X    sigvec(SIGALRM, &sig_alarm, (struct sigvec *)0);
  570. X    sigvec(SIGTERM, &sig_vec, (struct sigvec *)0);
  571. X    sigvec(SIGURG, &sig_name, (struct sigvec *)0);
  572. X    /*    SIGSTOP        */
  573. X    /*    SIGTSTP        */
  574. X    /*    SIGCONT        */
  575. X    /*    SIGCHLD        */
  576. X    sigvec(SIGTTIN, &sig_vec, (struct sigvec *)0);
  577. X    sigvec(SIGTTOU, &sig_vec, (struct sigvec *)0);
  578. X    sigvec(SIGIO, &sig_continue, (struct sigvec *)0);
  579. X    sigvec(SIGXCPU, &sig_vec, (struct sigvec *)0);
  580. X    sigvec(SIGXFSZ, &sig_vec, (struct sigvec *)0);
  581. X    sigvec(SIGVTALRM, &sig_vec, (struct sigvec *)0);
  582. X    /*    SIGPROF        */
  583. X
  584. X    /*
  585. X     * set up some important global values, including uid, pid,
  586. X     * the pipe file descriptors for messages to and from the gateway
  587. X     * server.  Register as the nameserver.  Get host name.  Get service.
  588. X     * Get root stat info.
  589. X     */
  590. X    if (chdir("/") == -1)
  591. X        log_fatal("cannot chdir(\"/\")\n");
  592. X    wildcard = newprocess();
  593. X    fcntl(2, F_SETFL, FAPPEND);
  594. X    close(0);
  595. X    close(1);
  596. X    change_to_uid(0);
  597. X    if (gethostname(hostname, HOSTNAMELEN) < 0 || *hostname == '\0')
  598. X        log_fatal("host name not set!\n");
  599. X    if (stat("/", &root) < 0)
  600. X        log_fatal("cannot stat /\n");
  601. X#ifdef CANREMOTE
  602. X    if (remotename(NM_SERVER, 0, 0, 0) < 0)
  603. X        log("cannot register as nameserver\n");
  604. X    /*
  605. X     * Turn off remote access, if we have any.
  606. X     */
  607. X    remoteoff(NULL);
  608. X#endif
  609. X    tt = open("/dev/tty", 2);
  610. X
  611. X    if (tt >= 0)
  612. X    {
  613. X        ioctl(tt, TIOCNOTTY, 0);
  614. X        close(tt);
  615. X    }
  616. X    setpgrp(0,0);
  617. X
  618. X    initusers();
  619. X    initgroups();
  620. X    inithosts();
  621. X    initrhosts();
  622. X}
  623. X
  624. X/*
  625. X * build the list of users on this host (where the server runs).
  626. X */
  627. Xinitusers()
  628. X{
  629. X    register struct passwd    *pw;
  630. X    register users    *user;
  631. X    char        buf[ BUFSIZ ];
  632. X    register char    *pbuf = buf;
  633. X
  634. X    while(pw = getpwent())
  635. X    {
  636. X        if (*pw->pw_dir == '\0' || *pw->pw_name == '\0')
  637. X        {
  638. X            log("login \"%s\" has problems, dir=\"%s\"\n",
  639. X                pw->pw_name, pw->pw_dir);
  640. X            continue;
  641. X        }
  642. X        user = newuser();
  643. X        user->u_local_uid = pw->pw_uid;
  644. X        user->u_name = copy( pw->pw_name );
  645. X        addgroup(user, pw->pw_gid);
  646. X        user->u_dir = copy( pw->pw_dir );
  647. X        sprintf(pbuf, "%s/.rhosts", pw->pw_dir);
  648. X        user->u_rhosts = copy( pbuf );
  649. X        addlist(&userlist, user);
  650. X    }
  651. X    endpwent();
  652. X    if (user = findusername(DEFAULTUSER))
  653. X        default_user = user;
  654. X    else
  655. X        log_fatal("The user \"%s\" must be in /etc/passwd (%s)\n",
  656. X            DEFAULTUSER, "for default permissions");
  657. X}
  658. X
  659. X/*
  660. X * Build the list of groups that each user belongs to.
  661. X */
  662. Xinitgroups()
  663. X{
  664. X    register struct group    *gr;
  665. X    register users    *user;
  666. X    register char    **p;
  667. X
  668. X
  669. X    while(gr = getgrent())
  670. X    {
  671. X        for (p = gr->gr_mem; *p; p++)
  672. X            if (user = findusername(*p))
  673. X                addgroup(user, gr->gr_gid);
  674. X            else
  675. X                log("group %s: bad user=%s\n",
  676. X                    gr->gr_name, *p);
  677. X    }
  678. X    endgrent();
  679. X}
  680. X
  681. X/*
  682. X * Then build the list of all hosts.
  683. X */
  684. Xinithosts()
  685. X{
  686. X    register struct hostent    *h;
  687. X    register rusers    *ruser;
  688. X    register hosts    *hst;
  689. X    register users    *user;
  690. X    register long    i;
  691. X    boolean        duplicate;
  692. X
  693. X    while (h = gethostent())
  694. X    {
  695. X        /*
  696. X         * One physical host may have more than one physical
  697. X         * address each having a unique host name associated
  698. X         * with it.  If we find any entry having one of its aliases
  699. X         * match a previous alias, then simply fold all aliases
  700. X         * into it, and continue.
  701. X         */
  702. X        duplicate = FALSE;
  703. X        for (i = -1; i < 0 || h->h_aliases[ i ]; i++)
  704. X        {
  705. X            if (i < 0)
  706. X                hst = findhost(h->h_name);
  707. X            else
  708. X                hst = findhost(h->h_aliases[i]);
  709. X            if (hst)
  710. X            {
  711. X                duplicate = TRUE;
  712. X                break;
  713. X            }
  714. X        }
  715. X
  716. X        /*
  717. X         * If we have a redundant host... add all the names
  718. X         * in; newname will remove redundant copies.
  719. X         */
  720. X        if (!duplicate)
  721. X            hst = newhost();
  722. X        hst->h_names = newname(hst->h_names, h->h_name);
  723. X        for (i=0; h->h_aliases[ i ]; i++)
  724. X            hst->h_names = newname(hst->h_names,
  725. X                    h->h_aliases[ i ]);
  726. X        if (duplicate)
  727. X
  728. X        hst->h_addr = *((struct in_addr *)(h->h_addr));
  729. X        addlist(&hostlist, hst);
  730. X
  731. X        /*
  732. X         * now if there exists a user on this machine having
  733. X         * the same name as the name of this host (NOT AN
  734. X         * ALIAS!), then that will be our defaut local user
  735. X         * to map to.  Be sure that we don't allow a machine
  736. X         * to be mapped onto a user if the uid is real small:
  737. X         * e.g. a machine named root, where all its user ids
  738. X         * become root using the remote fs!
  739. X         */
  740. X        user = findusername(hst->h_names[ 0 ]);
  741. X        if (user && user->u_local_uid <= UID_TOO_LOW)
  742. X        {
  743. X            log("host/user %s: uid %d too low for alias\n",
  744. X                hst->h_names[ 0 ], user->u_local_uid);
  745. X            user = NULL;
  746. X        }
  747. X        else if (user)
  748. X        {
  749. X            hst->h_default_user = user;
  750. X            debug2("default user for host %s (%s) is %s\n",
  751. X                hst->h_names[ 0 ],
  752. X                inet_ntoa(hst->h_addr), user->u_name);
  753. X        }
  754. X        ruser = hst->h_default_ruser = newruser();
  755. X        if (user)
  756. X            ruser->r_user = user;
  757. X        else
  758. X            ruser->r_user = default_user;
  759. X        ruser->r_uid = -1;
  760. X        ruser->r_name = copy(BOGUSUSER);
  761. X    }
  762. X    endhostent();
  763. X    if ((thishost = findhostname(hostname)) == NULL)
  764. X        log_fatal("this host (\"%s\") is not in host file\n",
  765. X            hostname);
  766. X}
  767. X
  768. X/*
  769. X * Now for each user that has a .rhosts file, assemble the
  770. X * references and attach them to the appropriate host.
  771. X */
  772. Xinitrhosts()
  773. X{
  774. X    register hosts    *hst;
  775. X    register rhost    *rh;
  776. X    register users    *user;
  777. X    char        buf[ BUFSIZ ];
  778. X    register char    *pbuf = buf;
  779. X
  780. X    for (user=userlist; user; user=user->u_next)
  781. X    {
  782. X        setrhost(user->u_rhosts);
  783. X        while (rh = getrhostent(pbuf))
  784. X            if (hst = findhostname(rh->rh_host))
  785. X                addremoteuser(hst, user, rh->rh_user);
  786. X        endrhost();
  787. X    }
  788. X}
  789. X
  790. Xchar    *copy(string)
  791. X    register char    *string;
  792. X{
  793. X    register char    *ret = malloc( strlen(string)+1 );
  794. X
  795. X    if (ret == NULL)
  796. X        log_fatal("cannot allocate space\n");
  797. X    strcpy(ret, string);
  798. X    return(ret);
  799. X}
  800. X
  801. X/*
  802. X * Add a remote user to those recognized on a certain host.
  803. X */
  804. Xaddremoteuser(h, user, remoteuser)
  805. X    register hosts    *h;
  806. X    register users    *user;
  807. X    register char    *remoteuser;
  808. X{
  809. X    register rusers    *ruser;
  810. X    register long    old = FALSE;
  811. X
  812. X    debug2("\t%s!%s --> %s ", *h->h_names, remoteuser, user->u_name);
  813. X    if ((ruser = findrusername(&h->h_rusers, remoteuser)) == NULL)
  814. X    {
  815. X        debug2("\n");
  816. X        ruser = newruser();
  817. X    }
  818. X    else
  819. X    {
  820. X        old = TRUE;
  821. X        if (strcmp(remoteuser, user->u_name) != 0)
  822. X        {
  823. X            debug2("(old, ignored)\n");
  824. X            return;
  825. X        }
  826. X        else
  827. X            debug2("(old)\n");
  828. X    }
  829. X    ruser->r_name = copy(remoteuser);
  830. X    ruser->r_uid = -1;
  831. X    ruser->r_user = user;
  832. X    if (! old)
  833. X        addlist(&h->h_rusers, ruser);
  834. X}
  835. SHAREOF
  836. chmod 664 remote/newinit.c
  837. #
  838. # remote/rhost.c
  839. #
  840. if [ -f remote/rhost.c ]; then 
  841.     echo -n 'Hit <return> to overwrite remote/rhost.c or ^C to quit' 
  842.     read ans 
  843.     rm -f remote/rhost.c 
  844. fi 
  845.  
  846. sed -e 's/^.//' << \SHAREOF > remote/rhost.c
  847. X/*
  848. X * Copyright 1985, Todd Brunhoff.
  849. X *
  850. X * This software was written at Tektronix Computer Research Laboratories
  851. X * as partial fulfillment of a Master's degree at the University of Denver.
  852. X * This is not Tektronix proprietary software and should not be
  853. X * confused with any software product sold by Tektronix.  No warranty is
  854. X * expressed or implied on the reliability of this software; the author,
  855. X * the University of Denver, and Tektronix, inc. accept no liability for
  856. X * any damage done directly or indirectly by this software.  This software
  857. X * may be copied, modified or used in any way, without fee, provided this
  858. X * notice remains an unaltered part of the software.
  859. X *
  860. X * $Log:    rhost.c,v $
  861. X * Revision 2.0  85/12/07  18:21:52  toddb
  862. X * First public release.
  863. X * 
  864. X */
  865. Xstatic char    *rcsid = "$Header: rhost.c,v 2.0 85/12/07 18:21:52 toddb Rel $";
  866. X#include    <stdio.h>
  867. X#include    "server.h"
  868. X
  869. Xstatic char    *rhostpath;
  870. Xstatic FILE    *fd;
  871. Xstatic rhost    rh;
  872. X
  873. Xsetrhost(path)
  874. X    register char    *path;
  875. X{
  876. X    extern int    errno;
  877. X
  878. X    if ((fd = fopen(path, "r")) != 0)
  879. X        debug2("rhost %s\n", path);
  880. X    errno = 0;
  881. X}
  882. X
  883. Xrhost *getrhostent(buf)
  884. X    register char    *buf;
  885. X{
  886. X    register char    *p;
  887. X
  888. X    while (1)
  889. X    {
  890. X        if (fd == NULL || fgets(buf, BUFSIZ, fd) == NULL)
  891. X            return(NULL);
  892. X
  893. X        /*
  894. X         * assign the first token to rh_host and then look for the
  895. X         * second token on the line.  If there is none, then
  896. X         * don't return this entry because we can never map
  897. X         * a remote user id name of "" to anything meaningful.
  898. X         */
  899. X        rh.rh_host = buf;
  900. X        for (p=buf; *p && *p != ' ' && *p != '\n'; p++) ;
  901. X        if (*p == '\n' || *p == '\0')
  902. X            continue;
  903. X
  904. X        /*
  905. X         * remove the newline on the end
  906. X         */
  907. X        rh.rh_user = p+1;
  908. X        *p = '\0';
  909. X        for (p++; *p && *p != ' ' && *p != '\n'; p++) ;
  910. X        *p = '\0';
  911. X        break;
  912. X    }
  913. X    return(&rh);
  914. X}
  915. X
  916. Xendrhost()
  917. X{
  918. X    if (fd)
  919. X    {
  920. X        fclose(fd);
  921. X        fd = NULL;
  922. X    }
  923. X}
  924. SHAREOF
  925. chmod 444 remote/rhost.c
  926. #
  927. # remote/rmtmnt.c
  928. #
  929. if [ -f remote/rmtmnt.c ]; then 
  930.     echo -n 'Hit <return> to overwrite remote/rmtmnt.c or ^C to quit' 
  931.     read ans 
  932.     rm -f remote/rmtmnt.c 
  933. fi 
  934.  
  935. sed -e 's/^.//' << \SHAREOF > remote/rmtmnt.c
  936. X/*
  937. X * Copyright 1985, Todd Brunhoff.
  938. X *
  939. X * This software was written at Tektronix Computer Research Laboratories
  940. X * as partial fulfillment of a Master's degree at the University of Denver.
  941. X * This is not Tektronix proprietary software and should not be
  942. X * confused with any software product sold by Tektronix.  No warranty is
  943. X * expressed or implied on the reliability of this software; the author,
  944. X * the University of Denver, and Tektronix, inc. accept no liability for
  945. X * any damage done directly or indirectly by this software.  This software
  946. X * may be copied, modified or used in any way, without fee, provided this
  947. X * notice remains an unaltered part of the software.
  948. X *
  949. X * $Log:    rmtmnt.c,v $
  950. X * Revision 2.0  85/12/07  18:21:56  toddb
  951. X * First public release.
  952. X * 
  953. X */
  954. Xstatic char    *rcsid = "$Header: rmtmnt.c,v 2.0 85/12/07 18:21:56 toddb Rel $";
  955. X#include    "server.h"
  956. X#include    <stdio.h>
  957. X#include    <sys/file.h>
  958. X#include    <netdb.h>
  959. X#include    <signal.h>
  960. X#include    <setjmp.h>
  961. X#include    <nlist.h>
  962. X
  963. Xextern int    errno;        /* for errors */
  964. Xchar        *service;    /* service name */
  965. Xchar        byteorder[4] = { BYTEORDER };
  966. X
  967. X/*
  968. X * for slow or dead remote hosts, we catch alarms.
  969. X */
  970. Xint        onalrm();
  971. Xstruct sigvec    vec = { onalrm, 0, 0 };
  972. X
  973. X/*
  974. X * Displaying current mount points requires that we read kernel space.
  975. X */
  976. Xstruct nlist    nl[] = {
  977. X#ifdef magnolia
  978. X    { "remote_info" },
  979. X#else
  980. X    { "_remote_info" },
  981. X#endif
  982. X    { "" },
  983. X};
  984. X#ifdef magnolia
  985. Xchar        *kernel = "/magix";
  986. X#else
  987. Xchar        *kernel = "/vmunix";
  988. X#endif
  989. X
  990. Xmain(argc, argv)
  991. X    int    argc;
  992. X    char    **argv;
  993. X{
  994. X    long    generic = FALSE,
  995. X        unmount = FALSE;
  996. X    char    *mntpt = NULL,
  997. X        *host = NULL;
  998. X
  999. X    /*
  1000. X     * Parse the args.
  1001. X     */
  1002. X    for (argv++, argc--; argc; argv++, argc--)
  1003. X    {
  1004. X        if (**argv != '-')
  1005. X            break;
  1006. X        switch(argv[0][1]) {
  1007. X        case 's':    /* service name */
  1008. X            if (argv[0][2])
  1009. X                service = argv[0]+2;
  1010. X            else
  1011. X                argv++, argc--, service = argv[0];
  1012. X            break;
  1013. X        case 'g':    /* Make this a generic mount point */
  1014. X            generic = TRUE;
  1015. X            break;
  1016. X        case 'u':    /* unmount this mount point */
  1017. X            unmount = TRUE;
  1018. X            break;
  1019. X        default:
  1020. X            fprintf(stderr, "unknown option = %s\n", *argv);
  1021. X            usage();
  1022. X            exit(1);
  1023. X        }
  1024. X    }
  1025. X
  1026. X    if (! generic && ! unmount && argc-- > 0)
  1027. X        host = *argv++;
  1028. X    if (argc-- > 0)
  1029. X    {
  1030. X        mntpt = *argv++;
  1031. X        if (*mntpt != '/')
  1032. X        {
  1033. X            fprintf(stderr, "mount point must begin with '/'\n");
  1034. X            mntpt = NULL;
  1035. X        }
  1036. X    }
  1037. X    else
  1038. X    {
  1039. X        show();
  1040. X        exit(0);
  1041. X    }
  1042. X
  1043. X    if (argc > 0
  1044. X    || (generic && unmount)
  1045. X    || (mntpt == NULL))
  1046. X        usage();
  1047. X
  1048. X    if (unmount)
  1049. X        turnoff(mntpt);
  1050. X    else
  1051. X        turnon(mntpt, host);
  1052. X}
  1053. X
  1054. X/*
  1055. X * Display the current mount points in the kernal.
  1056. X */
  1057. Xshow()
  1058. X{
  1059. X    long        index = 0,
  1060. X            diff,
  1061. X            now,
  1062. X            kfd;
  1063. X    char        buf[BUFSIZ],
  1064. X            *p;
  1065. X    struct sockaddr_in hostaddr;
  1066. X    struct sockaddr_in    *sys;
  1067. X    struct servent *servp;
  1068. X    struct hostent    *hostent;
  1069. X    struct remoteinfo rinfo[ R_MAXSYS ],
  1070. X            *rp;
  1071. X    struct mbuf    bufs[ R_MAXSYS ],
  1072. X            *m;
  1073. X
  1074. X    servp = getservbyname(REMOTE_FS_SERVER, "tcp");
  1075. X    /*
  1076. X     * Get the address of the remote mount point information
  1077. X     * and read kernel memory.
  1078. X     */
  1079. X    nlist(kernel, nl);
  1080. X    if(nl[0].n_type == 0)
  1081. X        log_fatal("no %s for namelist\n", kernel);
  1082. X    kfd = open("/dev/kmem", 0);
  1083. X    if(kfd < 0)
  1084. X        log_fatal("cannot open /dev/kmem\n");
  1085. X    lseek(kfd, (long)nl[0].n_value, 0);
  1086. X    read(kfd, rinfo, sizeof(struct remoteinfo) * R_MAXSYS);
  1087. X
  1088. X    /*
  1089. X     * Now get the mbufs on each mount point.
  1090. X     */
  1091. X    m = bufs;
  1092. X    time(&now);
  1093. X    for (index=0, rp = rinfo; rp < rinfo+R_MAXSYS; rp++, index++)
  1094. X    {
  1095. X        buf[0] = '\0';
  1096. X        if (rp->r_name || rp->r_mntpt)
  1097. X            printf("%d: ", index);
  1098. X        else
  1099. X            continue;
  1100. X        if (rp->r_name)
  1101. X        {
  1102. X            lseek(kfd, (long)rp->r_name, 0);
  1103. X            read(kfd, m, sizeof(struct mbuf));
  1104. X            rp->r_name = m++;
  1105. X            sys = mtod(rp->r_name, struct sockaddr_in *);
  1106. X            hostent = gethostbyaddr(&sys->sin_addr,
  1107. X                sizeof (struct in_addr), sys->sin_family);
  1108. X            if (hostent == NULL)
  1109. X            {
  1110. X                log("no host entry for %s\n",
  1111. X                    inet_ntoa(sys->sin_addr));
  1112. X                continue;
  1113. X            }
  1114. X            bprintf(buf, "%s(%s) on ",
  1115. X                hostent->h_name, inet_ntoa(sys->sin_addr));
  1116. X        }
  1117. X        else
  1118. X            bprintf(buf, "generic mount point ");
  1119. X        bprintf(buf, "%s", rp->r_mntpath);
  1120. X        if (rp->r_mntpt == NULL)
  1121. X            bprintf(buf, ", implied");
  1122. X        if (rp->r_name && sys->sin_port != servp->s_port)
  1123. X            bprintf(buf, ", port %d", sys->sin_port);
  1124. X        if (rp->r_sock)
  1125. X            bprintf(buf, ", connected");
  1126. X        if (rp->r_close)
  1127. X            bprintf(buf, ", closing");
  1128. X        if (rp->r_users)
  1129. X            bprintf(buf, ", %d process%s",
  1130. X                rp->r_users, rp->r_users > 1 ? "es" : "");
  1131. X        if (rp->r_nfile)
  1132. X            bprintf(buf, ", %d open file%s",
  1133. X                rp->r_nfile, rp->r_nfile > 1 ? "s" : "");
  1134. X        if (rp->r_nchdir)
  1135. X            bprintf(buf, ", %d chdir%s",
  1136. X                rp->r_nchdir, rp->r_nchdir > 1 ? "'s" : "");
  1137. X        if (rp->r_opening)
  1138. X            bprintf(buf, ", opening");
  1139. X        if (rp->r_failed)
  1140. X        {
  1141. X            bprintf(buf, ", connect failed, retry ");
  1142. X            diff = rp->r_age - now;
  1143. X            if (diff <= 0)
  1144. X                bprintf(buf, "time reached");
  1145. X            else
  1146. X            {
  1147. X                bprintf(buf, "in ");
  1148. X                if (diff / 60)
  1149. X                    bprintf(buf, "%d minute%s", diff/60,
  1150. X                        (diff/60) > 1 ? "s" : "");
  1151. X                if (diff / 60 && diff % 60)
  1152. X                    bprintf(buf, " and ");
  1153. X                if (diff % 60)
  1154. X                    bprintf(buf, "%d second%s", diff%60,
  1155. X                        (diff%60) > 1 ? "s" : "");
  1156. X            }
  1157. X        }
  1158. X        else if(rp->r_sock == NULL && rp->r_age)
  1159. X        {
  1160. X            bprintf(buf, ", last closed %s",
  1161. X                ctime(&rp->r_age));
  1162. X            buf[ strlen(buf)-1 ] = '\0'; /* remove newline */
  1163. X        }
  1164. X        printf("%s\n", buf);
  1165. X    }
  1166. X}
  1167. X
  1168. X/*
  1169. X * buffer printf.  i.e. do a printf into a buffer, appending to whatever
  1170. X * is there.  Split long lines.
  1171. X */
  1172. Xbprintf(buf, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  1173. X    char    *buf;
  1174. X{
  1175. X    char    xbuf[ BUFSIZ ],
  1176. X        *pfrom, *pto, c;
  1177. X    long    col;
  1178. X
  1179. X    sprintf(xbuf, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  1180. X    for (pto = buf; *pto; pto++) ;
  1181. X    for (pfrom = xbuf, col=0; *pfrom; pfrom++, col++)
  1182. X    {
  1183. X        c = *pfrom;
  1184. X        *pto++ = c;
  1185. X        if (c == '\n')
  1186. X            col = -1;
  1187. X        else if (c == ' ' && col > 50)
  1188. X        {
  1189. X            *pto++ = '\n';
  1190. X            *pto++ = '\t';
  1191. X            col = 7;
  1192. X        }
  1193. X    }
  1194. X    *pto = '\0';
  1195. X}
  1196. X
  1197. X/*
  1198. X * Do a mount.
  1199. X */
  1200. Xturnon(mntpt, host)
  1201. X    char    *mntpt, *host;
  1202. X{
  1203. X    int    index, ret, fdout, fdin;
  1204. X    struct message msgbuf, *msg = &msgbuf;
  1205. X    struct sockaddr_in    sys;
  1206. X    char    buf[ BUFSIZ ];
  1207. X
  1208. X    if (strlen(mntpt) >= R_MNTPATHLEN)
  1209. X        log_fatal("mount point must be < %d chars\n", R_MNTPATHLEN);
  1210. X
  1211. X    /*
  1212. X     * Connect to the machine and send it our byte order and
  1213. X     * password file.
  1214. X     */
  1215. X    if (host)
  1216. X    {
  1217. X        if ((fdout = tcpname(&sys, host)) < 0)
  1218. X            log("system unreachable now...");
  1219. X        index = remoteon(mntpt, strlen(mntpt)+1,
  1220. X            &sys, sizeof(struct sockaddr_in));
  1221. X    }
  1222. X    else
  1223. X        index = remoteon(mntpt, strlen(mntpt), 0, 0);
  1224. X    if (index == -1)
  1225. X        log_fatal("cant mount remote fs\n");
  1226. X    else if (host && fdout < 0)
  1227. X        log(" system mounted anyway\n");
  1228. X    if (host == NULL)
  1229. X        return;
  1230. X    if ((fdin = open("/etc/passwd", O_RDONLY)) == -1)
  1231. X        log_fatal("can't open /etc/passwd\n");
  1232. X    msg->m_syscall = htons(RSYS_nosys);
  1233. X    msg->m_hdlen = htons(R_MINRMSG + sizeof(long));
  1234. X    msg->m_totlen = htonl(R_MINRMSG + sizeof(long));
  1235. X    msg->m_args[0] = htonl(CMD_MOUNT);
  1236. X    write(fdout, msg, R_MINRMSG + sizeof(long));
  1237. X    write(fdout, byteorder, 4);
  1238. X    while ((ret = read(fdin, buf, BUFSIZ)) > 0)
  1239. X        write(fdout, buf, ret);
  1240. X    close(fdout);
  1241. X    close(fdin);
  1242. X    return;
  1243. X}
  1244. X
  1245. Xturnoff(mntpt)
  1246. X    char    *mntpt;
  1247. X{
  1248. X    int    index, fd;
  1249. X
  1250. X    index = remoteoff(mntpt);
  1251. X    if (index == -1)
  1252. X        log_fatal("can't unmount remote fs\n");
  1253. X    close(fd);
  1254. X}
  1255. X
  1256. Xusage()
  1257. X{
  1258. X    fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n",
  1259. X        "rmtmnt [-sservicename] -g path",
  1260. X        "rmtmnt [-sservicename] host path",
  1261. X        "rmtmnt");
  1262. X    exit(1);
  1263. X}
  1264. X
  1265. Xtcpname(sin, host)
  1266. X    struct sockaddr_in *sin;
  1267. X    char    *host;
  1268. X{
  1269. X    struct servent *servp;
  1270. X    struct hostent *hostp;
  1271. X    int s;
  1272. X
  1273. X    servp = getservbyname(service ? service : REMOTE_FS_SERVER, "tcp");
  1274. X
  1275. X    if (servp == NULL) {
  1276. X        fprintf(stderr, "%s: unknown service\n", REMOTE_FS_SERVER);
  1277. X        exit(1);
  1278. X    }
  1279. X
  1280. X    hostp = gethostbyname(host);
  1281. X    if (hostp == NULL) {
  1282. X        fprintf(stderr, "%s: unknown host\en", host);
  1283. X        exit(1);
  1284. X    }
  1285. X    bzero((char *)sin, sizeof (struct sockaddr_in));
  1286. X    bcopy(hostp->h_addr, (char *)&sin->sin_addr, hostp->h_length);
  1287. X    sin->sin_family = hostp->h_addrtype;
  1288. X    sin->sin_port = servp->s_port;
  1289. X
  1290. X    /*
  1291. X     * Ok, now make sure that the connection will work
  1292. X     */
  1293. X    if (sigvec(SIGALRM, &vec, (struct sigvec *)0) == -1) {
  1294. X        perror("signals");
  1295. X        return(-1);
  1296. X    }
  1297. X    s = socket(AF_INET, SOCK_STREAM, 0);
  1298. X    if (s < 0)
  1299. X        return(-1);
  1300. X    alarm(5);
  1301. X    if(connect(s, sin, sizeof(struct sockaddr_in)) < 0) {
  1302. X        alarm(0);
  1303. X        return(-1);
  1304. X    }
  1305. X    alarm(0);
  1306. X    return(s);
  1307. X}
  1308. X
  1309. Xonalrm(sig)
  1310. X{
  1311. X    fprintf(stderr, "timeout: ");
  1312. X}
  1313. X
  1314. Xlog_fatal(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  1315. X{
  1316. X    log(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  1317. X    exit(1);
  1318. X}
  1319. X
  1320. Xlog(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  1321. X{
  1322. X    if (errno)
  1323. X        perror("rmtmnt");
  1324. X    errno = 0;
  1325. X    fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  1326. X}
  1327. SHAREOF
  1328. chmod 444 remote/rmtmnt.c
  1329. #
  1330. # remote/route.c
  1331. #
  1332. if [ -f remote/route.c ]; then 
  1333.     echo -n 'Hit <return> to overwrite remote/route.c or ^C to quit' 
  1334.     read ans 
  1335.     rm -f remote/route.c 
  1336. fi 
  1337.  
  1338. sed -e 's/^.//' << \SHAREOF > remote/route.c
  1339. X/*
  1340. X * Copyright 1985, Todd Brunhoff.
  1341. X *
  1342. X * This software was written at Tektronix Computer Research Laboratories
  1343. X * as partial fulfillment of a Master's degree at the University of Denver.
  1344. X * This is not Tektronix proprietary software and should not be
  1345. X * confused with any software product sold by Tektronix.  No warranty is
  1346. X * expressed or implied on the reliability of this software; the author,
  1347. X * the University of Denver, and Tektronix, inc. accept no liability for
  1348. X * any damage done directly or indirectly by this software.  This software
  1349. X * may be copied, modified or used in any way, without fee, provided this
  1350. X * notice remains an unaltered part of the software.
  1351. X *
  1352. X * $Log:    route.c,v $
  1353. X * Revision 2.2  86/01/05  18:14:47  toddb
  1354. X * Added a forgotten case to gateway_listen(): S_CORRUPTED.
  1355. X * 
  1356. X * Revision 2.1  85/12/19  15:53:23  toddb
  1357. X * Changed declaration of a local variable (sigmask) because it conflicts
  1358. X * with a 4.3 define.
  1359. X * 
  1360. X * Revision 2.0  85/12/07  18:22:04  toddb
  1361. X * First public release.
  1362. X * 
  1363. X */
  1364. Xstatic char    *rcsid = "$Header: route.c,v 2.2 86/01/05 18:14:47 toddb Exp $";
  1365. X#include    "server.h"
  1366. X#include    <sys/file.h>
  1367. X#include    <sys/time.h>
  1368. X#include    <setjmp.h>
  1369. X#include    <errno.h>
  1370. X
  1371. Xextern short    current_pid;
  1372. Xextern short    current_ppid;
  1373. Xextern short    gateway_server;
  1374. Xextern short    current_server;
  1375. Xextern long    blocking_servers;
  1376. Xextern long    to_gateway;
  1377. Xextern long    from_servers;
  1378. Xextern long    errno;
  1379. Xextern boolean    i_am_gateway;
  1380. Xextern boolean    i_have_control;
  1381. Xextern boolean    gateway_needs_control;
  1382. Xextern boolean    route_to_gateway;
  1383. Xextern boolean    watch_for_lock;
  1384. Xextern boolean    i_am_asleep;
  1385. Xextern hosts    *host;
  1386. X
  1387. X/*
  1388. X * Reroute to the server whose pid is 'pid'.
  1389. X */
  1390. Xreroute(pid, msg)
  1391. X    register short    pid;
  1392. X    register struct message    *msg;
  1393. X{
  1394. X    if (route_to_gateway)
  1395. X    {
  1396. X        debug5("routing changed from server %d to gateway\n", pid);
  1397. X        route_to_gateway = FALSE;
  1398. X        pid = gateway_server;
  1399. X    }
  1400. X    watch_for_lock = gateway_needs_control = FALSE;
  1401. X    dont_gobble_msg(msg);
  1402. X
  1403. X    if (pid == current_pid)
  1404. X        log_fatal("reroute myself???\n");
  1405. X    debug5("%d waking up %d\n", current_pid, pid);
  1406. X
  1407. X    /*
  1408. X     * If we are the gateway, there may be some servers that are blocking
  1409. X     * on a request.  If so, then we lock file descriptor 2 with an
  1410. X     * shared lock.  This tells the server to always check to see if
  1411. X     * the lock goes up to an exclusive lock.  If so, then the server
  1412. X     * must then return control to the gateway.
  1413. X     */
  1414. X    if (i_am_gateway)
  1415. X    {
  1416. X        set_label("reading messages");
  1417. X        i_have_control = FALSE;
  1418. X        if (blocking_servers)
  1419. X            if (flock(2, LOCK_NB | LOCK_SH) < 0)
  1420. X                log_fatal("cannot lock fd 2\n");
  1421. X    }
  1422. X
  1423. X    i_am_asleep = TRUE;
  1424. X    if (pid == gateway_server)
  1425. X        say_something(S_THIS_IS_YOURS, gateway_server);
  1426. X    else
  1427. X        wake_up(pid);
  1428. X    slumber(FALSE);
  1429. X    if (! i_am_gateway)
  1430. X    {
  1431. X        /*
  1432. X         * Check for the lock on fd 2.  But even if the gateway wants
  1433. X         * control, go ahead an serve this request.
  1434. X         */
  1435. X        if (flock(2, LOCK_NB | LOCK_EX) < 0)
  1436. X            if (flock(2, LOCK_NB | LOCK_SH) >= 0)
  1437. X            {
  1438. X                debug5("watch for lock on each request\n");
  1439. X                watch_for_lock = TRUE;
  1440. X                flock(2, LOCK_UN);
  1441. X            }
  1442. X            else
  1443. X            {
  1444. X                debug5("Gateway wants control\n");
  1445. X                gateway_needs_control = TRUE;
  1446. X            }
  1447. X        else
  1448. X            flock(2, LOCK_UN);
  1449. X    }
  1450. X}
  1451. X
  1452. X
  1453. X/*
  1454. X * Tell the gateway something.
  1455. X */
  1456. Xsay_something(cmd, arg)
  1457. X    register long    cmd, arg;
  1458. X{
  1459. X    gtmsgs        gmsg[2];
  1460. X    register gtmsgs    *g = gmsg;
  1461. X    register long    len = sizeof(gtmsgs);
  1462. X
  1463. X
  1464. X    if (cmd == S_NEWSERVER)    /* actually 2 messages */
  1465. X    {
  1466. X        g->g_server = current_ppid;
  1467. X        g->g_cmd = cmd;
  1468. X        g->g_pid = current_pid;
  1469. X        cmd = S_NEWPROCESS;
  1470. X        g++;
  1471. X        len += sizeof(gtmsgs);
  1472. X    }
  1473. X    g->g_server = current_pid;
  1474. X    g->g_cmd = cmd;
  1475. X    g->g_pid = arg;
  1476. X
  1477. X    debug5("say: cmd=%d, arg=%d\n", cmd, arg);
  1478. X    if (write(to_gateway, gmsg, len) != len)
  1479. X        log_fatal("pid %d: can't write to gateway!!\n",
  1480. X            current_pid);
  1481. X}
  1482. X
  1483. X/*
  1484. X * Read message from servers.  We do the allocation of space and maintain it.
  1485. X */
  1486. Xgtmsgs *read_gtmsgs()
  1487. X{
  1488. X    static gtmsgs    *msgs;
  1489. X    static long    current_len,
  1490. X            len_needed = 10;
  1491. X    register long    red;
  1492. X    register gtmsgs    *g;
  1493. X
  1494. X    /*
  1495. X     * Allocate space for the current read.
  1496. X     */
  1497. X    if (current_len < len_needed)
  1498. X    {
  1499. X        if (msgs)
  1500. X            msgs = (gtmsgs *)realloc(msgs,
  1501. X                len_needed * sizeof(gtmsgs));
  1502. X        else
  1503. X            msgs = (gtmsgs *)malloc(len_needed * sizeof(gtmsgs));
  1504. X        current_len = len_needed;
  1505. X    }
  1506. X
  1507. X    /*
  1508. X     * Now read the messages.
  1509. X     */
  1510. X    red = read(from_servers, msgs, (current_len-1) * sizeof(gtmsgs));
  1511. X    if (red % sizeof(gtmsgs) != 0)
  1512. X        log_fatal("partial message on read = %d\n", red);
  1513. X    red /= sizeof(gtmsgs);
  1514. X    if (red == current_len-1)
  1515. X        len_needed++;
  1516. X    msgs[ red ].g_server = 0;
  1517. X#ifdef RFSDEBUG
  1518. X    for (g=msgs; g->g_server; g++)
  1519. X        debug14("red: server %d, cmd %d, pid=%d\n",
  1520. X            g->g_server, g->g_cmd, g->g_pid);
  1521. X#endif RFSDEBUG
  1522. X    return(msgs);
  1523. X}
  1524. X    
  1525. X/*
  1526. X * This process is called to gather incomming messages from servers out
  1527. X * there with something interesting to say.  We return TRUE if we have
  1528. X * read a message from a process that is relinquishing control, FALSE
  1529. X * otherwise.
  1530. X */
  1531. Xgateway_listen()
  1532. X{
  1533. X    register process    *proc;
  1534. X    register gtmsgs        *msgs, *g;
  1535. X    short            dequeue();
  1536. X    register short        cmd, i, pid, server;
  1537. X
  1538. X    msgs = read_gtmsgs();
  1539. X
  1540. X    errno = 0;
  1541. X    for (g=msgs; g->g_server; g++)
  1542. X    {
  1543. X        pid    = g->g_pid;
  1544. X        server = g->g_server;
  1545. X        cmd    = g->g_cmd;
  1546. X
  1547. X        switch(cmd) {
  1548. X        case S_NEWSERVER: /* a new server forked by another server */
  1549. X            debug5("hear: %d forks new server %d\n", server, pid);
  1550. X            break;
  1551. X        case S_NEWPROCESS: /* a new process is being served */
  1552. X            proc = add_new_process(0, pid);
  1553. X            proc->p_handler = server;
  1554. X            debug5("hear: pid %d serving pid %d\n", server, pid);
  1555. X            break;
  1556. X        case S_PROCEXIT: /* some server's client did an exit() call */
  1557. X            debug5("hear: proc exit from server %d: pid=%d\n",
  1558. X                server, pid);
  1559. X            if ((proc = findprocess(pid, -1)) == NULL)
  1560. X                log("can't find pid %d!\n", pid);
  1561. X            else
  1562. X            {
  1563. X                deletelist(&host->h_proclist, proc);
  1564. X                freeproc(proc);
  1565. X            }
  1566. X            break;
  1567. X        case S_I_WOULD_BLOCK: /* server will block on I/O */
  1568. X            debug5("hear: server %d blocks\n", server);
  1569. X            blocking_servers++;
  1570. X            goto gateway_control;
  1571. X        case S_ALLDONE:    /* an existing server is ready to die */
  1572. X        case S_EOF:    /* a server got eof on command socket */
  1573. X            mourne();
  1574. X            debug5("hear: server %d %s... ", server,
  1575. X                cmd == S_ALLDONE ? "dead" : "got eof");
  1576. X            for (proc=host->h_proclist; proc; proc=proc->p_next)
  1577. X                if (proc->p_handler == server)
  1578. X                {
  1579. X                    debug5("free proc %d...", proc->p_pid);
  1580. X                    deletelist(&host->h_proclist, proc);
  1581. X                    freeproc(proc);
  1582. X                }
  1583. X            debug5("\n");
  1584. X            /* fall through */
  1585. X        case S_THIS_IS_YOURS: /* just relinquish control */
  1586. X    gateway_control:
  1587. X            /*
  1588. X             * Always unlock when we have control.
  1589. X             */
  1590. X            flock(2, LOCK_UN);
  1591. X            if (cmd == S_THIS_IS_YOURS)
  1592. X                debug5("hear: server %d gives us control\n",
  1593. X                    server);
  1594. X            /*
  1595. X             * Now that we have control, see about dequeing
  1596. X             * a server that is ready to go.  If there is one,
  1597. X             * Then change this message so that it looks like
  1598. X             * a message from ourself saying to reroute to
  1599. X             * 'server'.
  1600. X             */
  1601. X            server = dequeue();
  1602. X            if (server > 0)
  1603. X            {
  1604. X                debug5("server %d ready to go\n", server);
  1605. X                wake_up(server);
  1606. X            }
  1607. X            else
  1608. X            {
  1609. X                debug5("gateway pid %d continuing\n",
  1610. X                    current_pid);
  1611. X                set_label("active");
  1612. X                i_have_control = TRUE;
  1613. X            }
  1614. X            break;
  1615. X        case S_I_AM_READY:
  1616. X            debug5("hear: server %d ready\n", server);
  1617. X            blocking_servers--;
  1618. X            if (flock(2, LOCK_EX) < 0)
  1619. X                log_fatal("cannot lock fd 2\n");
  1620. X            queue(server);
  1621. X            break;
  1622. X        case S_CORRUPTED:
  1623. X            log_fatal("corrupted input stream\n");
  1624. X            break;
  1625. X        default:
  1626. X            log("unknown message from %d = %d\n", server, cmd);
  1627. X            break;
  1628. X        }
  1629. X    }
  1630. X
  1631. X    return(FALSE);
  1632. X}
  1633. X
  1634. Xwake_up(pid)
  1635. X    long    pid;
  1636. X{
  1637. X    sendsig(pid, SIGIO);
  1638. X}
  1639. X
  1640. Xsendsig(pid, sig)
  1641. X    long    pid,
  1642. X        sig;
  1643. X{
  1644. X    register func    logger;
  1645. X    extern long    log(), log_fatal();
  1646. X
  1647. X    change_to_uid(0);
  1648. X    if (kill(pid, sig) < 0)
  1649. X    {
  1650. X        if (errno == ESRCH)
  1651. X            logger = log;
  1652. X        else
  1653. X            logger = log_fatal;
  1654. X        logger("couldn't signal %d w/ sig=%d\n", pid, sig);
  1655. X        return(FALSE);
  1656. X    }
  1657. X    return(TRUE);
  1658. X}
  1659. X
  1660. Xstatic short    *server_queue;
  1661. Xstatic short    server_len;
  1662. Xstatic short    last_server;
  1663. X/*
  1664. X * Put a server on a queue to be run again.  Fifo queue.
  1665. X */
  1666. Xqueue(pid)
  1667. X    register short    pid;
  1668. X{
  1669. X    if (++last_server > server_len)
  1670. X    {
  1671. X        server_len++;
  1672. X        if (server_queue == NULL)
  1673. X            server_queue = (short *)malloc(sizeof(short));
  1674. X        else
  1675. X            server_queue = (short *)realloc(server_queue,
  1676. X                server_len*sizeof(short));
  1677. X    }
  1678. X    server_queue[ last_server - 1 ] = pid;
  1679. X}
  1680. X
  1681. X/*
  1682. X * Get the first server off the queue.  Blech!  We have to copy all the
  1683. X * queue back one.
  1684. X */
  1685. Xshort dequeue()
  1686. X{
  1687. X    register short    retval, i;
  1688. X
  1689. X    if (last_server == 0)
  1690. X        return(0);
  1691. X    retval = server_queue[ 0 ];
  1692. X    for (i=1; i<last_server; i++)
  1693. X        server_queue[ i-1 ] = server_queue[ i ];
  1694. X    last_server--;
  1695. X    return( retval );
  1696. X}
  1697. X
  1698. X/*
  1699. X * Go to sleep awaiting a wakup call.  Do not return until we receive it.
  1700. X * However, if we are the gateway, we, of course MUST return and go
  1701. X * on reading messages.
  1702. X *
  1703. X * Since there is a window between testing the i_am_asleep flag and doing
  1704. X * the pause, in which we could be awakened, we must always jump around
  1705. X * this loop using longjmp() from the interrupt routine.
  1706. X */
  1707. Xslumber(forked)
  1708. X    boolean    forked;
  1709. X{
  1710. X    register long    signalmask;
  1711. X
  1712. X    if (i_am_gateway)
  1713. X    {
  1714. X        set_label("reading messages");
  1715. X        i_have_control = FALSE;
  1716. X        return;
  1717. X    }
  1718. X    set_label("asleep");
  1719. X    signalmask = sigblock(1<<(SIGIO-1));
  1720. X    while (i_am_asleep)
  1721. X        sigpause(signalmask);
  1722. X    sigsetmask(signalmask);
  1723. X
  1724. X    debug5("pid %d continuing%s\n",
  1725. X        current_pid, forked ? "after fork" : "");
  1726. X    set_label("active");
  1727. X    mourne();
  1728. X}
  1729. SHAREOF
  1730. chmod 444 remote/route.c
  1731. #
  1732. # remote/server.h
  1733. #
  1734. if [ -f remote/server.h ]; then 
  1735.     echo -n 'Hit <return> to overwrite remote/server.h or ^C to quit' 
  1736.     read ans 
  1737.     rm -f remote/server.h 
  1738. fi 
  1739.  
  1740. sed -e 's/^.//' << \SHAREOF > remote/server.h
  1741. X/*
  1742. X * Copyright 1985, Todd Brunhoff.
  1743. X *
  1744. X * This software was written at Tektronix Computer Research Laboratories
  1745. X * as partial fulfillment of a Master's degree at the University of Denver.
  1746. X * This is not Tektronix proprietary software and should not be
  1747. X * confused with any software product sold by Tektronix.  No warranty is
  1748. X * expressed or implied on the reliability of this software; the author,
  1749. X * the University of Denver, and Tektronix, inc. accept no liability for
  1750. X * any damage done directly or indirectly by this software.  This software
  1751. X * may be copied, modified or used in any way, without fee, provided this
  1752. X * notice remains an unaltered part of the software.
  1753. X *
  1754. X * $Header: server.h,v 2.0 85/12/07 18:22:12 toddb Rel $
  1755. X *
  1756. X * $Log:    server.h,v $
  1757. X * Revision 2.0  85/12/07  18:22:12  toddb
  1758. X * First public release.
  1759. X * 
  1760. X */
  1761. X#include    <sys/param.h>
  1762. X#include    <sys/mbuf.h>
  1763. X#include    <sys/socket.h>
  1764. X#include    <netinet/in.h>
  1765. X#include    <remote/remotefs.h>
  1766. X
  1767. Xtypedef    unsigned char    boolean;
  1768. X
  1769. X/*
  1770. X * The maximum number of longs in a message that we accept
  1771. X */
  1772. X#define    MAXMSGS        ((R_MAXMBUFS*MLEN)/sizeof(long))
  1773. X/*
  1774. X * The name of a host for which we have no record.  And the name of the user
  1775. X * to use if we don't recognize the user on the remote host.
  1776. X */
  1777. X#define    BOGUSHOST    "unknown host"
  1778. X#define    BOGUSUSER    "unknown user"
  1779. X#define DEFAULTUSER    "guest"
  1780. X
  1781. X/*
  1782. X * The uid number below which we reserve for privilaged users.
  1783. X */
  1784. X#define    UID_TOO_LOW    20
  1785. X
  1786. X/*
  1787. X * This is to make the debug? macro work for the server.
  1788. X *
  1789. X * The bits and what they turn on are as follows
  1790. X *    0x00000001    process switching
  1791. X *    0x00000002    system calls
  1792. X *    0x00000004    setuid/setgid, umask
  1793. X *    0x00000008    file descriptor allocation
  1794. X *    0x00000010    connections
  1795. X *    0x00000020    server switching
  1796. X *    0x00000040    nameserver
  1797. X *    0x00000080    directory nuxi
  1798. X *    0x00000100    message in and out
  1799. X *    0x00000200    don't fork child for gateway (good for adb)
  1800. X *    0x00000400    local/remote file decisions
  1801. X *    0x00000800    don't remove log file on exit (except exit on error)
  1802. X *    0x00001000    exec information
  1803. X *    0x00002000    auto debug for 0x20 (server switching)
  1804. X *    0x00004000    parsing messages to gateway
  1805. X */
  1806. X#define    rmt_debug    log
  1807. X#ifndef RFSDEBUG
  1808. X#define dumphost()
  1809. X#endif RFSDEBUG
  1810. X
  1811. X/*
  1812. X * The size of the initial allocation for internal io buffers.
  1813. X */
  1814. X#define    BIGBUF        (8*1024)
  1815. X
  1816. X/*
  1817. X * other Manifest constants...
  1818. X */
  1819. X#define    HOSTNAMELEN    255
  1820. X
  1821. X/*
  1822. X * Map a file descriptor from the user's fd to our own internal fd.
  1823. X */
  1824. X#define    MAPFD(fd, proc)            \
  1825. X    (((unsigned)fd > NOFILE) ? -1 : (proc)->p_fds[ fd ] )
  1826. X/*
  1827. X * requirements for different system calls.
  1828. X */
  1829. X#define    NEED_ZIP    0x000    /* don't need anything special */
  1830. X#define    NEED_CWD    0x001    /* need the current working directory set */
  1831. X#define    NEED_PERM    0x002    /* need the user and group ids set */
  1832. X#define    NEED_FD        0x004    /* need a file descriptor allocated */
  1833. X#define    NEED_2PATH    0x010    /* uses two paths */
  1834. X#define    NEED_MYSERVER    0x020    /* must be run by the assigned server */
  1835. X#define    NEED_2REMOTE    0x040    /* both paths must be remote */
  1836. X
  1837. X/*
  1838. X * Commands to the server sent by external programs (like rmtmnt, to mount
  1839. X * a remote system.
  1840. X */
  1841. X#define    CMD_SERVICE    1
  1842. X#define    CMD_MOUNT    2    /* here is mount information */
  1843. X#define    CMD_NEEDMOUNT    3    /* give me mount information */
  1844. X#define    CMD_WHOAMI    4    /* what uid am I on your host */
  1845. X
  1846. X/*
  1847. X * Finally, some commands that are sent to the gateway server by other
  1848. X * servers.
  1849. X */
  1850. X#define    S_NEWSERVER    0
  1851. X#define    S_NEWPROCESS    1
  1852. X#define    S_ALLDONE    2
  1853. X#define    S_THIS_IS_YOURS    3
  1854. X#define    S_PROCEXIT    4
  1855. X#define    S_EOF        5
  1856. X#define    S_I_WOULD_BLOCK    6
  1857. X#define    S_I_AM_READY    7
  1858. X#define    S_CORRUPTED    8
  1859. X
  1860. X/*
  1861. X * Macros for getting the address of the paths out of the incomming message.
  1862. X * Note that path1addr is for system calls that deal with only one path,
  1863. X * and twopath1addr() and twopath2addr() are for system calls that have
  1864. X * two paths (in the latter cases, path2 appears in the same position
  1865. X * as path1 does for single path system calls).
  1866. X */
  1867. X#define    path1addr(msg)        ((char *)&(msg)->m_args[R_PATHSTART])
  1868. X#define    twopath1addr(msg)    ((char *)(msg) + (msg)->m_args[R_PATHOFF])
  1869. X#define    twopath2addr(msg)    ((char *)&(msg)->m_args[R_PATHSTART])
  1870. X
  1871. X/*
  1872. X * Macro for preventing getmsg(), and thereby gobble_last_msg() from
  1873. X * reading the last message.  This is used when control is being passed
  1874. X * from one server to another.
  1875. X */
  1876. X#define    dont_gobble_msg(msg)    (msg)->m_totlen = 0
  1877. X
  1878. X/*
  1879. X * Macro for determining whether a stat structure reflects the root inode
  1880. X * of our machine or not.
  1881. X */
  1882. X#define    isroot(p)    (p->st_ino == root.st_ino && p->st_dev == root.st_dev)
  1883. X
  1884. X/*
  1885. X * This structure is one-to-one with each local user where the server runs.
  1886. X * Note that the u_next and u_prev pointers must be located
  1887. X * in the first and second spots of the structure, respectively so that
  1888. X * they can be modified by the linked-list routines.
  1889. X */
  1890. Xtypedef struct users_type    users;
  1891. Xstruct users_type {
  1892. X    users    *u_next;    /* pointers for linked list, both forward... */
  1893. X    users    *u_prev;    /* ... and back. */
  1894. X    char    *u_name;    /* The ascii name of same. */
  1895. X    char    *u_dir;        /* login directory for same */
  1896. X    char    *u_rhosts;    /* path of the user's rhost file */
  1897. X    short    u_local_uid;    /* A user id number on the local host */
  1898. X    long    u_local_groups[NGROUPS];/* The groups this user belongs to */
  1899. X    char    u_numgroups;    /* The number of groups in u_local_groups */
  1900. X};
  1901. X
  1902. X/*
  1903. X * Remote user specification.
  1904. X */
  1905. Xtypedef struct ruser_type    rusers;
  1906. Xstruct ruser_type {
  1907. X    rusers    *r_next;
  1908. X    rusers    *r_prev;
  1909. X    short     r_uid;    /* Uid number on remote host ... */
  1910. X    char    *r_name;    /* Uid name on remote host ... */
  1911. X    users    *r_user;    /* corresponding local user */
  1912. X};
  1913. X
  1914. X/*
  1915. X * This is the important stuff.  There is one of these structures for
  1916. X * each pid that we are providing service to.
  1917. X */
  1918. Xtypedef struct process_type    process;
  1919. Xstruct process_type {
  1920. X    process        *p_next;
  1921. X    process        *p_prev;
  1922. X    long        p_returnval;    /* return value from last syscall */
  1923. X    rusers        *p_ruser;    /* info about the owner of this pid */
  1924. X    short        p_pid;        /* process id number on remote host */
  1925. X    short        p_uid;        /* remote uid that was last known */
  1926. X    short        p_handler;    /* the handler for this process */
  1927. X    short        p_errno;    /* errno for the system call */
  1928. X    char        p_execfd;    /* file descriptor of exec file */
  1929. X    boolean        p_execstarted;    /* whether we have done first read */
  1930. X    char        p_fds[ NOFILE ];/* fd's assoc. with this pid */
  1931. X};
  1932. X
  1933. X/*
  1934. X * This structure keeps track of the possible hosts that may make a connection
  1935. X * the the remote fs server.  Note that the h_next and hprev pointers must be
  1936. X * located in the first and second spots of the structure, respectively,
  1937. X * so that they can be modified by the linked-list routines.
  1938. X */
  1939. Xtypedef struct hosts_type    hosts;
  1940. Xstruct hosts_type {
  1941. X    hosts    *h_next;
  1942. X    hosts    *h_prev;
  1943. X    char    **h_names;    /* name (and aliases) of a host */
  1944. X    rusers    *h_rusers;    /* the user list for this host */
  1945. X    users    *h_default_user;/* default local user (if defined */
  1946. X    rusers    *h_default_ruser;/* default when the remote user is unknown */
  1947. X    long    h_portnum;    /* port number that we connected on */
  1948. X    char    *h_mntpt;    /* mount point for this machine */
  1949. X    process    *h_proclist;    /* processes we know about on this host */
  1950. X    struct in_addr    h_addr;    /* network address */
  1951. X    union h_bytes {
  1952. X        long    hu_mounted; /* non-zero if host has been mounted */
  1953. X        u_char    hu_byteorder[4]; /* byte order for this host */
  1954. X    } h_bytes;
  1955. X#define        h_mounted    h_bytes.hu_mounted
  1956. X#define        h_byteorder    h_bytes.hu_byteorder
  1957. X    char    h_cmdfd;    /* file descriptor for commands */
  1958. X    boolean    h_byteorderok;    /* true if byte order same as ours */
  1959. X    short    h_serverpid;    /* gateway server for this host */
  1960. X};
  1961. X
  1962. X/*
  1963. X * This structure is the mask structure that the linked list routines use
  1964. X * to modify any linked-list type of structure.  Note that l_next and l_prev
  1965. X * must be in the first and second spots.
  1966. X */
  1967. Xtypedef struct l_list_type    l_list;
  1968. Xstruct l_list_type {
  1969. X    l_list    *l_next;
  1970. X    l_list    *l_prev;
  1971. X    long    l_data;        /* never used */
  1972. X};
  1973. X
  1974. X/*
  1975. X * This structure is for convenience: it simply defines an easy way of
  1976. X * storing the host/user line found in a .rhost file.
  1977. X */
  1978. Xtypedef struct rhost_type    rhost;
  1979. Xstruct rhost_type {
  1980. X    char    *rh_host;
  1981. X    char    *rh_user;
  1982. X};
  1983. X
  1984. X/*
  1985. X * Each message from the servers to the gateway, is placed into this
  1986. X * structure, the "gateway message".
  1987. X */
  1988. Xtypedef struct gtmsg_type    gtmsgs;
  1989. Xstruct gtmsg_type {
  1990. X    short    g_server;    /* server that sent the message. */
  1991. X    short    g_pid;        /* pid of whom this message is about */
  1992. X    short    g_cmd;        /* what this message is about */
  1993. X};
  1994. X
  1995. X/*
  1996. X * Finally, this is the way we keep database info on the system calls
  1997. X * themselves.
  1998. X */
  1999. Xtypedef struct syscallmap    syscallmap;
  2000. Xstruct syscallmap {
  2001. X    func    s_server;
  2002. X    func    s_syscall;
  2003. X    char    s_type;
  2004. X};
  2005. X
  2006. Xrhost    *getrhostent();
  2007. Xhosts    *tcpaccept();
  2008. Xhosts    *findhostaddr();
  2009. Xhosts    *findhostname();
  2010. Xhosts    *newhost();
  2011. Xl_list    *toplist();
  2012. Xl_list    *bottomlist();
  2013. Xl_list    *addlist();
  2014. Xl_list    *deletelist();
  2015. Xprocess *newprocess();
  2016. Xprocess    *findprocess();
  2017. Xprocess    *change_to_proc();
  2018. Xprocess    *add_new_process();
  2019. Xusers    *finduid();
  2020. Xusers    *findusername();
  2021. Xusers    *newuser();
  2022. Xrusers    *findremuid();
  2023. Xrusers    *findrusername();
  2024. Xrusers    *newruser();
  2025. Xchar    **newname();
  2026. Xchar    *copy();
  2027. Xchar    *malloc();
  2028. Xchar    *realloc();
  2029. Xchar    *get_data_buf();
  2030. Xshort    *newshortlist();
  2031. SHAREOF
  2032. chmod 444 remote/server.h
  2033. #
  2034. # remote/serverdata.c
  2035. #
  2036. if [ -f remote/serverdata.c ]; then 
  2037.     echo -n 'Hit <return> to overwrite remote/serverdata.c or ^C to quit' 
  2038.     read ans 
  2039.     rm -f remote/serverdata.c 
  2040. fi 
  2041.  
  2042. sed -e 's/^.//' << \SHAREOF > remote/serverdata.c
  2043. X/*
  2044. X * Copyright 1985, Todd Brunhoff.
  2045. X *
  2046. X * This software was written at Tektronix Computer Research Laboratories
  2047. X * as partial fulfillment of a Master's degree at the University of Denver.
  2048. X * This is not Tektronix proprietary software and should not be
  2049. X * confused with any software product sold by Tektronix.  No warranty is
  2050. X * expressed or implied on the reliability of this software; the author,
  2051. X * the University of Denver, and Tektronix, inc. accept no liability for
  2052. X * any damage done directly or indirectly by this software.  This software
  2053. X * may be copied, modified or used in any way, without fee, provided this
  2054. X * notice remains an unaltered part of the software.
  2055. X *
  2056. X * $Log:    serverdata.c,v $
  2057. X * Revision 2.0  85/12/07  18:22:20  toddb
  2058. X * First public release.
  2059. X * 
  2060. X */
  2061. Xstatic char    *rcsid = "$Header: serverdata.c,v 2.0 85/12/07 18:22:20 toddb Rel $";
  2062. X#include    "server.h"
  2063. X#include    <nlist.h>
  2064. X#include    <signal.h>
  2065. X#include    <netdb.h>
  2066. X#include    <sys/stat.h>
  2067. X
  2068. X/*
  2069. X * system calls.
  2070. X */
  2071. Xlong    access(), chdir(), chmod(), chown(), close(), dup(), execve(),
  2072. X    fchmod(), fchown(), fcntl(), flock(), fork(), fstat(), fsync(),
  2073. X    ftruncate(), ioctl(), link(), lseek(), lstat(), mkdir(),
  2074. X    mknod(), open(), read(), readlink(), rename(), rmdir(),
  2075. X    stat(), symlink(), truncate(), unlink(), utimes(),
  2076. X    write(),
  2077. X/*
  2078. X * ...and our own routines to set up for the system calls.
  2079. X */
  2080. X    noop(), s_access(), s_dup(), s_execinfo(), s_execread(), s_exit(),
  2081. X    s_fcntl(), s_fd1(), s_fd1_plus(), s_fork(), s_ioctl(), s_lseek(),
  2082. X    s_open(), s_path1(), s_path1_plus(), s_path2(), s_read(),
  2083. X    s_readlink(), s_stat(), s_utimes(), s_write();
  2084. X
  2085. Xsyscallmap smap[] = {
  2086. X    s_fork,        noop,     NEED_ZIP,        /* RSYS_fork */
  2087. X    s_read,        read,     NEED_ZIP,        /* RSYS_read */
  2088. X    s_write,    write,    NEED_ZIP,        /* RSYS_write */
  2089. X    s_open,        open,      NEED_CWD
  2090. X                 |NEED_MYSERVER
  2091. X                 |NEED_PERM
  2092. X                 |NEED_FD,        /* RSYS_open */
  2093. X    s_fd1,        close,    NEED_ZIP,        /* RSYS_close */
  2094. X    noop,        noop,      NEED_CWD
  2095. X                 |NEED_PERM
  2096. X                 |NEED_FD,        /* RSYS_creat */
  2097. X    s_path2,    link,      NEED_CWD
  2098. X                 |NEED_MYSERVER
  2099. X                 |NEED_2PATH
  2100. X                 |NEED_2REMOTE
  2101. X                 |NEED_PERM,        /* RSYS_link */
  2102. X    s_path1,    unlink,   NEED_CWD|NEED_PERM,    /* RSYS_unlink */
  2103. X    s_path1,    chdir,    NEED_MYSERVER
  2104. X                 |NEED_CWD
  2105. X                 |NEED_PERM
  2106. X                 |NEED_MYSERVER,    /* RSYS_chdir */
  2107. X    s_path1_plus,    mknod,    NEED_CWD|NEED_PERM,    /* RSYS_mknod */
  2108. X    s_path1_plus,    chmod,    NEED_CWD|NEED_PERM,    /* RSYS_chmod */
  2109. X    s_path1_plus,    chown,    NEED_CWD|NEED_PERM,    /* RSYS_chown */
  2110. X    s_stat,        stat,     NEED_CWD|NEED_PERM,    /* RSYS_stat */
  2111. X    s_lseek,    lseek,    NEED_ZIP,        /* RSYS_lseek */
  2112. X    s_access,    access,   NEED_CWD|NEED_PERM,    /* RSYS_access */
  2113. X    s_stat,        lstat,    NEED_CWD|NEED_PERM,    /* RSYS_lstat */
  2114. X    s_dup,        dup,      NEED_FD,        /* RSYS_dup */
  2115. X    s_ioctl,    ioctl,    NEED_ZIP,        /* RSYS_ioctl */
  2116. X    s_path2,    symlink,  NEED_CWD
  2117. X                 |NEED_2PATH
  2118. X                 |NEED_PERM,        /* RSYS_symlink */
  2119. X    s_readlink,    readlink, NEED_CWD|NEED_PERM,    /* RSYS_readlink */
  2120. X    s_stat,        fstat,    NEED_ZIP,        /* RSYS_fstat */
  2121. X    s_dup,        dup,      NEED_FD,        /* RSYS_dup2 */
  2122. X    s_fd1_plus,    fcntl,    NEED_ZIP,        /* RSYS_fcntl */
  2123. X    s_fd1,        fsync,    NEED_ZIP,        /* RSYS_fsync */
  2124. X    noop,        noop,     NEED_ZIP,        /* RSYS_readv */
  2125. X    noop,        noop,     NEED_ZIP,        /* RSYS_writev */
  2126. X    s_fd1_plus,    fchown,   NEED_PERM,        /* RSYS_fchown */
  2127. X    s_fd1_plus,    fchmod,   NEED_PERM,        /* RSYS_fchmod */
  2128. X    s_path2,    rename,   NEED_MYSERVER
  2129. X                 |NEED_2REMOTE
  2130. X                 |NEED_CWD
  2131. X                 |NEED_2PATH
  2132. X                 |NEED_PERM,        /* RSYS_rename */
  2133. X    s_path1_plus,    truncate, NEED_CWD|NEED_PERM,    /* RSYS_truncate */
  2134. X    s_fd1_plus,    ftruncate,NEED_ZIP,        /* RSYS_ftruncate */
  2135. X    s_fd1_plus,    flock,    NEED_ZIP,        /* RSYS_flock */
  2136. X    s_path1_plus,    mkdir,    NEED_CWD|NEED_PERM,    /* RSYS_mkdir */
  2137. X    s_path1,    rmdir,    NEED_CWD|NEED_PERM,    /* RSYS_rmdir */
  2138. X    s_utimes,    utimes,   NEED_CWD|NEED_PERM,    /* RSYS_utimes */
  2139. X    s_exit,        noop,      NEED_ZIP,        /* RSYS_exit */
  2140. X    s_fork,        noop,     NEED_ZIP,        /* RSYS_Vfork */
  2141. X    s_execinfo,    noop,      NEED_MYSERVER
  2142. X                 |NEED_CWD
  2143. X                 |NEED_PERM,        /* RSYS_execinfo */
  2144. X    s_execread,    noop,      NEED_PERM,        /* RSYS_execread */
  2145. X    noop,        noop,      NEED_ZIP,        /* RSYS_execve */
  2146. X    noop,        noop,      NEED_ZIP,        /* RSYS_nosys */
  2147. X    s_lseek,    lseek,    NEED_ZIP,        /* RSYS_qlseek */
  2148. X};
  2149. X
  2150. Xchar    *syscallnames[] = {
  2151. X    "fork",
  2152. X    "read",
  2153. X    "write",
  2154. X    "open",
  2155. X    "close",
  2156. X    "creat",
  2157. X    "link",
  2158. X    "unlink",
  2159. X    "chdir",
  2160. X    "mknod",
  2161. X    "chmod",
  2162. X    "chown",
  2163. X    "stat",
  2164. X    "lseek",
  2165. X    "access",
  2166. X    "lstat",
  2167. X    "dup",
  2168. X    "ioctl",
  2169. X    "symlink",
  2170. X    "readlink",
  2171. X    "fstat",
  2172. X    "dup2",
  2173. X    "fcntl",
  2174. X    "fsync",
  2175. X    "readv",
  2176. X    "writev",
  2177. X    "fchown",
  2178. X    "fchmod",
  2179. X    "rename",
  2180. X    "truncate",
  2181. X    "ftruncate",
  2182. X    "flock",
  2183. X    "mkdir",
  2184. X    "rmdir",
  2185. X    "utimes",
  2186. X    "exit",
  2187. X    "vfork",
  2188. X    "execinfo",
  2189. X    "execread",
  2190. X    "execve",
  2191. X    "nosys",
  2192. X    "quick lseek"
  2193. X};
  2194. X
  2195. Xchar    hostname[ HOSTNAMELEN ];/* our host name */
  2196. Xchar    mntpt[ MAXPATHLEN ];    /* mount point for client */
  2197. Xchar    *program;        /* name of this program */
  2198. Xchar    *last_argaddr;        /* last address that we can scribble on */
  2199. Xchar    *service = REMOTE_FS_SERVER; /* name of alternate internet service */
  2200. Xchar    *stdlogfile = "/usr/tmp/rfs_log"; /* log file  for server */
  2201. Xchar    *logfile;
  2202. Xlong    serviceport;        /* port number for service */
  2203. Xlong    remote_debug;        /* level of debug output */
  2204. Xshort    current_uid;        /* whatever uid we are, right now */
  2205. Xshort    current_pid;        /* whatever pid we are, right now */
  2206. Xshort    current_ppid;        /* our parent server */
  2207. Xshort    current_umask;        /* whatever umask we have, right now */
  2208. Xshort    current_server;        /* server that has control right now */
  2209. Xshort    gateway_server;        /* pid of our gateway */
  2210. Xshort    last_sentry;        /* previous sentry server (if non-zero) */
  2211. Xlong    fds_in_use;        /* number of total file descriptors open */
  2212. Xlong    to_gateway;        /* file descriptor for messages to gateway */
  2213. Xlong    so_listen;        /* socket for listening for connections */
  2214. Xlong    from_servers;        /* file descriptor for messages from servers */
  2215. Xlong    blocking_servers;    /* number of servers waiting for I/O */
  2216. Xhosts    *hostlist;        /* all the hosts we know of */
  2217. Xhosts    *host;            /* the current host that we talk to */
  2218. Xhosts    *thishost;        /* host pointer for this machine */
  2219. Xusers    *userlist;        /* all the users on this host we know of */
  2220. Xusers    *default_user;        /* default user to map unknown clients to */
  2221. Xprocess *wildcard;        /* wildcard process for easy requests */
  2222. Xboolean    i_am_gateway = TRUE;    /* whether we are the gateway server */
  2223. Xboolean    i_have_control = TRUE;    /* whether the gateway server has control of */
  2224. X                /* the command socket */
  2225. Xboolean    i_am_asleep;        /* whether we are sleeping or not */
  2226. Xboolean    gateway_needs_control;    /* True if gateway wants control back */
  2227. Xboolean    watch_for_lock;        /* True if we need to watch for lock on fd 2 */
  2228. Xboolean    route_to_gateway;    /* True if we should route to gateway */
  2229. Xboolean    in_root_directory = TRUE;/* whether we are at root directory or not */
  2230. Xstruct stat    filetypes[ NOFILE ];    /* file types for open files */
  2231. X
  2232. Xchar    byteorder[4] = { BYTEORDER };
  2233. Xlong    catch(),
  2234. X    nameserver(),
  2235. X    wakeup_call(),
  2236. X    alarmsig();
  2237. X
  2238. Xstruct sigvec sig_continue = {
  2239. X    wakeup_call,
  2240. X    1<<(SIGIO -1),
  2241. X    0
  2242. X};
  2243. X
  2244. Xstruct sigvec sig_ignore = {
  2245. X    (int (*)())SIG_IGN,
  2246. X    1<<(SIGHUP -1),
  2247. X    0
  2248. X};
  2249. X
  2250. Xstruct sigvec sig_alarm = {
  2251. X    alarmsig,
  2252. X    1<<(SIGALRM -1),
  2253. X    0
  2254. X};
  2255. X
  2256. Xstruct sigvec sig_name = {
  2257. X    nameserver,
  2258. X    1<<(SIGURG -1),
  2259. X    0
  2260. X};
  2261. X
  2262. Xstruct sigvec sig_vec = {
  2263. X    catch,
  2264. X     (1<<(SIGINT -1))
  2265. X    |(1<<(SIGQUIT-1))
  2266. X    |(1<<(SIGBUS-1))
  2267. X    |(1<<(SIGILL-1))
  2268. X    |(1<<(SIGSEGV-1))
  2269. X    |(1<<(SIGPIPE-1))
  2270. X    |(1<<(SIGSYS-1))
  2271. X    |(1<<(SIGTERM-1))
  2272. X    |(1<<(SIGTTIN-1))
  2273. X    |(1<<(SIGTTOU-1))
  2274. X    |(1<<(SIGXCPU-1))
  2275. X    |(1<<(SIGXFSZ-1))
  2276. X    |(1<<(SIGVTALRM-1)),
  2277. X    0
  2278. X};
  2279. X
  2280. X#ifdef RFSDEBUG
  2281. X
  2282. Xlong    newdebug();
  2283. X
  2284. Xstruct sigvec sig_debug = {
  2285. X    newdebug,
  2286. X    (1<<(SIGTRAP -1)),
  2287. X    0
  2288. X};
  2289. X#endif RFSDEBUG
  2290. X
  2291. Xstruct stat    root;            /* stat info for root directory */
  2292. SHAREOF
  2293. chmod 444 remote/serverdata.c
  2294. #
  2295. # remote/serverdir.c
  2296. #
  2297. if [ -f remote/serverdir.c ]; then 
  2298.     echo -n 'Hit <return> to overwrite remote/serverdir.c or ^C to quit' 
  2299.     read ans 
  2300.     rm -f remote/serverdir.c 
  2301. fi 
  2302.  
  2303. sed -e 's/^.//' << \SHAREOF > remote/serverdir.c
  2304. X/*
  2305. X * Copyright 1985, Todd Brunhoff.
  2306. X *
  2307. X * This software was written at Tektronix Computer Research Laboratories
  2308. X * as partial fulfillment of a Master's degree at the University of Denver.
  2309. X * This is not Tektronix proprietary software and should not be
  2310. X * confused with any software product sold by Tektronix.  No warranty is
  2311. X * expressed or implied on the reliability of this software; the author,
  2312. X * the University of Denver, and Tektronix, inc. accept no liability for
  2313. X * any damage done directly or indirectly by this software.  This software
  2314. X * may be copied, modified or used in any way, without fee, provided this
  2315. X * notice remains an unaltered part of the software.
  2316. X *
  2317. X * $Log:    serverdir.c,v $
  2318. X * Revision 2.0  85/12/07  18:22:28  toddb
  2319. X * First public release.
  2320. X * 
  2321. X */
  2322. Xstatic char    *rcsid = "$Header: serverdir.c,v 2.0 85/12/07 18:22:28 toddb Rel $";
  2323. X#include    "server.h"
  2324. X#include    <sys/dir.h>
  2325. X#include    <sys/stat.h>
  2326. X#include    <errno.h>
  2327. X
  2328. Xextern hosts    *host;
  2329. Xextern long    errno;
  2330. Xextern char    byteorder[];
  2331. Xextern struct stat    filetypes[];
  2332. X
  2333. X/*
  2334. X * Check to see type open file type... we may have to massage input
  2335. X * it if the user wants to read this file descriptor and it is a directory.
  2336. X */
  2337. Xcheckfiletype(fd)
  2338. X    register int    fd;
  2339. X{
  2340. X    struct stat    statb, *statp = &statb;
  2341. X
  2342. X    if (fd < 0)
  2343. X        return;
  2344. X    fstat(fd, statp);
  2345. X    filetypes[ fd ] = statb;
  2346. X}
  2347. X
  2348. X/*
  2349. X * If byte-ordering is different between this machine and our client,
  2350. X * the directories must be massaged into the right byte order.
  2351. X */
  2352. Xfixdir(fd, buf, size)
  2353. X    register long    size,
  2354. X            fd;
  2355. X    register char    *buf;
  2356. X{
  2357. X    register struct direct *dirp;
  2358. X    register char    *next, *last;
  2359. X    register u_char    *clientorder = host->h_byteorder;
  2360. X    short        fixshort();
  2361. X
  2362. X    if (size < 0)
  2363. X        return(errno);
  2364. X    if (fd >= NOFILE || (filetypes[fd].st_mode & S_IFDIR) == 0)
  2365. X        return(0);
  2366. X
  2367. X    /*
  2368. X     * we don't know this client's byteorder...  can't do it right
  2369. X     */
  2370. X    if (!host->h_mounted)
  2371. X        return(EIO);
  2372. X    dirp = (struct direct *)buf;
  2373. X    last = buf;
  2374. X    debug7("nuxi directory entry buf=0%x, size=%d, end @%x\n",
  2375. X        buf, size, buf+size);
  2376. X    while(last < buf + size && dirp->d_reclen)
  2377. X    {
  2378. X        dirp = (struct direct *)last;
  2379. X        next = last + dirp->d_reclen;
  2380. X
  2381. X        debug7("dir @0x%x (next+%d @0x%x): %x %x %x %s -->",
  2382. X            last, dirp->d_reclen, next,
  2383. X            dirp->d_ino,
  2384. X            (unsigned)dirp->d_reclen,
  2385. X            (unsigned)dirp->d_namlen,
  2386. X            dirp->d_name);
  2387. X        dirp->d_ino = fixlong(clientorder, &dirp->d_ino);
  2388. X        dirp->d_reclen = fixshort(clientorder, &dirp->d_reclen);
  2389. X        dirp->d_namlen = fixshort(clientorder, &dirp->d_namlen);
  2390. X        debug7(" %x %x %x %s\n",
  2391. X            dirp->d_ino,
  2392. X            (unsigned)dirp->d_reclen,
  2393. X            (unsigned)dirp->d_namlen,
  2394. X            dirp->d_name);
  2395. X        last = next;
  2396. X    }
  2397. X    return(0);
  2398. X}
  2399. X
  2400. Xfixlong(clto, from)
  2401. X    register char    *clto,    /* clients byte order */
  2402. X            *from;    /* data to be fixed */
  2403. X{
  2404. X    register char    *srvo,    /* server's byte order */
  2405. X            *to;
  2406. X    long        result;
  2407. X
  2408. X    to = (char *)&result;
  2409. X    srvo = byteorder;
  2410. X    to[ clto[0] ] = from[ srvo[0] ];
  2411. X    to[ clto[1] ] = from[ srvo[1] ];
  2412. X    to[ clto[2] ] = from[ srvo[2] ];
  2413. X    to[ clto[3] ] = from[ srvo[3] ];
  2414. X    return(result);
  2415. X}
  2416. X
  2417. Xshort fixshort(clto, from)
  2418. X    register char    *clto,    /* clients byte order */
  2419. X            *from;    /* data to be fixed */
  2420. X{
  2421. X    register char    *srvo,    /* server's byte order */
  2422. X            *to;
  2423. X    short        result;
  2424. X
  2425. X    to = (char *)&result;
  2426. X    srvo = byteorder;
  2427. X    to[ clto[0]&0x1 ] = from[ srvo[0]&0x1 ];
  2428. X    to[ clto[1]&0x1 ] = from[ srvo[1]&0x1 ];
  2429. X    return(result);
  2430. X}
  2431. SHAREOF
  2432. chmod 444 remote/serverdir.c
  2433.  
  2434.