home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / fsp / part03 < prev    next >
Encoding:
Text File  |  1992-12-17  |  58.4 KB  |  2,223 lines

  1. Newsgroups: comp.sources.misc
  2. From: wen-king@vlsi.cs.caltech.edu (Wen-King Su)
  3. Subject:  v34i077:  fsp - Internet archive server and client software, Part03/04
  4. Message-ID: <1992Dec18.164016.11453@sparky.imd.sterling.com>
  5. X-Md4-Signature: d75dc12edea050136785277b3585f4b5
  6. Date: Fri, 18 Dec 1992 16:40:16 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: wen-king@vlsi.cs.caltech.edu (Wen-King Su)
  10. Posting-number: Volume 34, Issue 77
  11. Archive-name: fsp/part03
  12. Environment: UNIX, Sockets
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  bsd_src/glob.c bsd_src/ls.h bsd_src/print.c client_lib.c
  19. #   common_def.h fcdcmd.1 fgrabcmd.1 fprocmd.c fspd.1 server_def.h
  20. #   server_host.c server_main.c udp_io.c
  21. # Wrapped by kent@sparky on Fri Dec 18 10:21:25 1992
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 3 (of 4)."'
  25. if test -f 'bsd_src/glob.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'bsd_src/glob.c'\"
  27. else
  28.   echo shar: Extracting \"'bsd_src/glob.c'\" \(10233 characters\)
  29.   sed "s/^X//" >'bsd_src/glob.c' <<'END_OF_FILE'
  30. X/*
  31. X * Copyright (c) 1980 Regents of the University of California.
  32. X * All rights reserved.
  33. X *
  34. X * Redistribution and use in source and binary forms are permitted
  35. X * provided that the above copyright notice and this paragraph are
  36. X * duplicated in all such forms and that any documentation,
  37. X * advertising materials, and other materials related to such
  38. X * distribution and use acknowledge that the software was developed
  39. X * by the University of California, Berkeley.  The name of the
  40. X * University may not be used to endorse or promote products derived
  41. X * from this software without specific prior written permission.
  42. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  43. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  44. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  45. X */
  46. X
  47. X#ifndef lint
  48. Xstatic char sccsid[] = "@(#)glob.c    5.4 (Berkeley) 6/29/88";
  49. X#endif /* not lint */
  50. X
  51. X/*
  52. X * C-shell glob for random programs.
  53. X */
  54. X
  55. X#include "../client_def.h"
  56. X#include "tweak.h"
  57. X
  58. X#define    QUOTE 0200
  59. X#define    TRIM 0177
  60. X#define    eq(a,b)        (strcmp(a, b)==0)
  61. X#define    GAVSIZ        (NCARGS/6)
  62. X#define    isdir(d)    ((d.st_mode & S_IFMT) == S_IFDIR)
  63. X
  64. Xstatic    char **gargv;        /* Pointer to the (stack) arglist */
  65. Xstatic    int gargc;        /* Number args in gargv */
  66. Xstatic    int gnleft;
  67. Xstatic    int gflag;
  68. Xstatic    int tglob();
  69. Xchar    **glob();
  70. Xchar    *globerr;
  71. Xchar    *home;
  72. Xstruct    passwd *getpwnam();
  73. Xextern    int errno;
  74. Xstatic    char *strspl(), *strend();
  75. Xchar    *malloc(), *strcpy(), *strcat();
  76. Xchar    **copyblk();
  77. X
  78. Xstatic    int globcnt;
  79. X
  80. Xchar    *globchars = "`{[*?";
  81. X
  82. Xstatic    char *gpath, *gpathp, *lastgpathp;
  83. Xstatic    int globbed;
  84. Xstatic    char *entp;
  85. Xstatic    char **sortbas;
  86. X
  87. Xstatic  rscan(), ginit(), collect(), Gcat(), sort(), acollect(), expand(),
  88. X    addpath(), execbrc(), matchdir(), match(), amatch();
  89. X
  90. Xchar **
  91. Xglob(v)
  92. X    register char *v;
  93. X{
  94. X    char agpath[BUFSIZ];
  95. X    char *agargv[GAVSIZ];
  96. X    char *vv[2];
  97. X    vv[0] = v;
  98. X    vv[1] = 0;
  99. X    gflag = 0;
  100. X    rscan(vv, tglob);
  101. X    if (gflag == 0)
  102. X        return (copyblk(vv));
  103. X
  104. X    globerr = 0;
  105. X    gpath = agpath; gpathp = gpath; *gpathp = 0;
  106. X    lastgpathp = &gpath[sizeof agpath - 2];
  107. X    ginit(agargv); globcnt = 0;
  108. X    collect(v);
  109. X    if (globcnt == 0 && (gflag&1)) {
  110. X        blkfree(gargv), gargv = 0;
  111. X        return (0);
  112. X    } else
  113. X        return (gargv = copyblk(gargv));
  114. X}
  115. X
  116. Xstatic
  117. Xginit(agargv)
  118. X    char **agargv;
  119. X{
  120. X
  121. X    agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
  122. X    gnleft = NCARGS - 4;
  123. X}
  124. X
  125. Xstatic
  126. Xcollect(as)
  127. X    register char *as;
  128. X{
  129. X    if (eq(as, "{") || eq(as, "{}")) {
  130. X        Gcat(as, "");
  131. X        sort();
  132. X    } else
  133. X        acollect(as);
  134. X}
  135. X
  136. Xstatic
  137. Xacollect(as)
  138. X    register char *as;
  139. X{
  140. X    register int ogargc = gargc;
  141. X
  142. X    gpathp = gpath; *gpathp = 0; globbed = 0;
  143. X    expand(as);
  144. X    if (gargc != ogargc)
  145. X        sort();
  146. X}
  147. X
  148. Xstatic
  149. Xsort()
  150. X{
  151. X    register char **p1, **p2, *c;
  152. X    char **Gvp = &gargv[gargc];
  153. X
  154. X    p1 = sortbas;
  155. X    while (p1 < Gvp-1) {
  156. X        p2 = p1;
  157. X        while (++p2 < Gvp)
  158. X            if (strcmp(*p1, *p2) > 0)
  159. X                c = *p1, *p1 = *p2, *p2 = c;
  160. X        p1++;
  161. X    }
  162. X    sortbas = Gvp;
  163. X}
  164. X
  165. Xstatic
  166. Xexpand(as)
  167. X    char *as;
  168. X{
  169. X    register char *cs;
  170. X    register char *sgpathp, *oldcs;
  171. X    struct stat stb;
  172. X
  173. X    sgpathp = gpathp;
  174. X    cs = as;
  175. X    if (*cs == '~' && gpathp == gpath) {
  176. X        addpath('~');
  177. X        for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
  178. X            addpath(*cs++);
  179. X        if (!*cs || *cs == '/') {
  180. X            if (gpathp != gpath + 1) {
  181. X                *gpathp = 0;
  182. X                if (gethdir(gpath + 1))
  183. X                    globerr = "Unknown user name after ~";
  184. X                (void) strcpy(gpath, gpath + 1);
  185. X            } else
  186. X                (void) strcpy(gpath, home);
  187. X            gpathp = strend(gpath);
  188. X        }
  189. X    }
  190. X    while (!any(*cs, globchars)) {
  191. X        if (*cs == 0) {
  192. X            if (!globbed)
  193. X                Gcat(gpath, "");
  194. X            else if (util_stat(gpath, &stb) >= 0) {
  195. X                Gcat(gpath, "");
  196. X                globcnt++;
  197. X            }
  198. X            goto endit;
  199. X        }
  200. X        addpath(*cs++);
  201. X    }
  202. X    oldcs = cs;
  203. X    while (cs > as && *cs != '/')
  204. X        cs--, gpathp--;
  205. X    if (*cs == '/')
  206. X        cs++, gpathp++;
  207. X    *gpathp = 0;
  208. X    if (*oldcs == '{') {
  209. X        (void) execbrc(cs, ((char *)0));
  210. X        return;
  211. X    }
  212. X    matchdir(cs);
  213. Xendit:
  214. X    gpathp = sgpathp;
  215. X    *gpathp = 0;
  216. X}
  217. X
  218. Xstatic
  219. Xmatchdir(pattern)
  220. X    char *pattern;
  221. X{
  222. X    struct stat stb;
  223. X    register struct rdirent *dp;
  224. X    RDIR *dirp;
  225. X
  226. X    dirp = util_opendir(gpath);
  227. X    if (dirp == NULL) {
  228. X        if (globbed)
  229. X            return;
  230. X        goto patherr2;
  231. X    }
  232. X    if (util_stat(gpath, &stb) < 0)
  233. X        goto patherr1;
  234. X    if (!isdir(stb)) {
  235. X        errno = ENOTDIR;
  236. X        goto patherr1;
  237. X    }
  238. X    while ((dp = util_readdir(dirp)) != NULL) {
  239. X        if (dp->d_ino == 0)
  240. X            continue;
  241. X        if (match(dp->d_name, pattern)) {
  242. X            Gcat(gpath, dp->d_name);
  243. X            globcnt++;
  244. X        }
  245. X    }
  246. X    util_closedir(dirp);
  247. X    return;
  248. X
  249. Xpatherr1:
  250. X    util_closedir(dirp);
  251. Xpatherr2:
  252. X    globerr = "Bad directory components";
  253. X}
  254. X
  255. Xstatic
  256. Xexecbrc(p, s)
  257. X    char *p, *s;
  258. X{
  259. X    char restbuf[BUFSIZ + 2];
  260. X    register char *pe, *pm, *pl;
  261. X    int brclev = 0;
  262. X    char *lm, savec, *sgpathp;
  263. X
  264. X    for (lm = restbuf; *p != '{'; *lm++ = *p++)
  265. X        continue;
  266. X    for (pe = ++p; *pe; pe++)
  267. X    switch (*pe) {
  268. X
  269. X    case '{':
  270. X        brclev++;
  271. X        continue;
  272. X
  273. X    case '}':
  274. X        if (brclev == 0)
  275. X            goto pend;
  276. X        brclev--;
  277. X        continue;
  278. X
  279. X    case '[':
  280. X        for (pe++; *pe && *pe != ']'; pe++)
  281. X            continue;
  282. X        continue;
  283. X    }
  284. Xpend:
  285. X    brclev = 0;
  286. X    for (pl = pm = p; pm <= pe; pm++)
  287. X    switch (*pm & (QUOTE|TRIM)) {
  288. X
  289. X    case '{':
  290. X        brclev++;
  291. X        continue;
  292. X
  293. X    case '}':
  294. X        if (brclev) {
  295. X            brclev--;
  296. X            continue;
  297. X        }
  298. X        goto doit;
  299. X
  300. X    case ','|QUOTE:
  301. X    case ',':
  302. X        if (brclev)
  303. X            continue;
  304. Xdoit:
  305. X        savec = *pm;
  306. X        *pm = 0;
  307. X        (void) strcpy(lm, pl);
  308. X        (void) strcat(restbuf, pe + 1);
  309. X        *pm = savec;
  310. X        if (s == 0) {
  311. X            sgpathp = gpathp;
  312. X            expand(restbuf);
  313. X            gpathp = sgpathp;
  314. X            *gpathp = 0;
  315. X        } else if (amatch(s, restbuf))
  316. X            return (1);
  317. X        sort();
  318. X        pl = pm + 1;
  319. X        if (brclev)
  320. X            return (0);
  321. X        continue;
  322. X
  323. X    case '[':
  324. X        for (pm++; *pm && *pm != ']'; pm++)
  325. X            continue;
  326. X        if (!*pm)
  327. X            pm--;
  328. X        continue;
  329. X    }
  330. X    if (brclev)
  331. X        goto doit;
  332. X    return (0);
  333. X}
  334. X
  335. Xstatic
  336. Xmatch(s, p)
  337. X    char *s, *p;
  338. X{
  339. X    register int c;
  340. X    register char *sentp;
  341. X    char sglobbed = globbed;
  342. X
  343. X    if (*s == '.' && *p != '.')
  344. X        return (0);
  345. X    sentp = entp;
  346. X    entp = s;
  347. X    c = amatch(s, p);
  348. X    entp = sentp;
  349. X    globbed = sglobbed;
  350. X    return (c);
  351. X}
  352. X
  353. Xstatic
  354. Xamatch(s, p)
  355. X    register char *s, *p;
  356. X{
  357. X    register int scc;
  358. X    int ok, lc;
  359. X    char *sgpathp;
  360. X    struct stat stb;
  361. X    int c, cc;
  362. X
  363. X    globbed = 1;
  364. X    for (;;) {
  365. X        scc = *s++ & TRIM;
  366. X        switch (c = *p++) {
  367. X
  368. X        case '{':
  369. X            return (execbrc(p - 1, s - 1));
  370. X
  371. X        case '[':
  372. X            ok = 0;
  373. X            lc = 077777;
  374. X            while (cc = *p++) {
  375. X                if (cc == ']') {
  376. X                    if (ok)
  377. X                        break;
  378. X                    return (0);
  379. X                }
  380. X                if (cc == '-') {
  381. X                    if (lc <= scc && scc <= *p++)
  382. X                        ok++;
  383. X                } else
  384. X                    if (scc == (lc = cc))
  385. X                        ok++;
  386. X            }
  387. X            if (cc == 0)
  388. X                if (ok)
  389. X                    p--;
  390. X                else
  391. X                    return 0;
  392. X            continue;
  393. X
  394. X        case '*':
  395. X            if (!*p)
  396. X                return (1);
  397. X            if (*p == '/') {
  398. X                p++;
  399. X                goto slash;
  400. X            }
  401. X            s--;
  402. X            do {
  403. X                if (amatch(s, p))
  404. X                    return (1);
  405. X            } while (*s++);
  406. X            return (0);
  407. X
  408. X        case 0:
  409. X            return (scc == 0);
  410. X
  411. X        default:
  412. X            if (c != scc)
  413. X                return (0);
  414. X            continue;
  415. X
  416. X        case '?':
  417. X            if (scc == 0)
  418. X                return (0);
  419. X            continue;
  420. X
  421. X        case '/':
  422. X            if (scc)
  423. X                return (0);
  424. Xslash:
  425. X            s = entp;
  426. X            sgpathp = gpathp;
  427. X            while (*s)
  428. X                addpath(*s++);
  429. X            addpath('/');
  430. X            if (util_stat(gpath, &stb) == 0 && isdir(stb))
  431. X                if (*p == 0) {
  432. X                    Gcat(gpath, "");
  433. X                    globcnt++;
  434. X                } else
  435. X                    expand(p);
  436. X            gpathp = sgpathp;
  437. X            *gpathp = 0;
  438. X            return (0);
  439. X        }
  440. X    }
  441. X}
  442. X
  443. Xstatic
  444. XGmatch(s, p)
  445. X    register char *s, *p;
  446. X{
  447. X    register int scc;
  448. X    int ok, lc;
  449. X    int c, cc;
  450. X
  451. X    for (;;) {
  452. X        scc = *s++ & TRIM;
  453. X        switch (c = *p++) {
  454. X
  455. X        case '[':
  456. X            ok = 0;
  457. X            lc = 077777;
  458. X            while (cc = *p++) {
  459. X                if (cc == ']') {
  460. X                    if (ok)
  461. X                        break;
  462. X                    return (0);
  463. X                }
  464. X                if (cc == '-') {
  465. X                    if (lc <= scc && scc <= *p++)
  466. X                        ok++;
  467. X                } else
  468. X                    if (scc == (lc = cc))
  469. X                        ok++;
  470. X            }
  471. X            if (cc == 0)
  472. X                if (ok)
  473. X                    p--;
  474. X                else
  475. X                    return 0;
  476. X            continue;
  477. X
  478. X        case '*':
  479. X            if (!*p)
  480. X                return (1);
  481. X            for (s--; *s; s++)
  482. X                if (Gmatch(s, p))
  483. X                    return (1);
  484. X            return (0);
  485. X
  486. X        case 0:
  487. X            return (scc == 0);
  488. X
  489. X        default:
  490. X            if ((c & TRIM) != scc)
  491. X                return (0);
  492. X            continue;
  493. X
  494. X        case '?':
  495. X            if (scc == 0)
  496. X                return (0);
  497. X            continue;
  498. X
  499. X        }
  500. X    }
  501. X}
  502. X
  503. Xstatic
  504. XGcat(s1, s2)
  505. X    register char *s1, *s2;
  506. X{
  507. X    register int len = strlen(s1) + strlen(s2) + 1;
  508. X
  509. X    if (len >= gnleft || gargc >= GAVSIZ - 1)
  510. X        globerr = "Arguments too long";
  511. X    else {
  512. X        gargc++;
  513. X        gnleft -= len;
  514. X        gargv[gargc] = 0;
  515. X        gargv[gargc - 1] = strspl(s1, s2);
  516. X    }
  517. X}
  518. X
  519. Xstatic
  520. Xaddpath(c)
  521. X    char c;
  522. X{
  523. X
  524. X    if (gpathp >= lastgpathp)
  525. X        globerr = "Pathname too long";
  526. X    else {
  527. X        *gpathp++ = c;
  528. X        *gpathp = 0;
  529. X    }
  530. X}
  531. X
  532. Xstatic
  533. Xrscan(t, f)
  534. X    register char **t;
  535. X    int (*f)();
  536. X{
  537. X    register char *p, c;
  538. X
  539. X    while (p = *t++) {
  540. X        if (f == tglob)
  541. X            if (*p == '~')
  542. X                gflag |= 2;
  543. X            else if (eq(p, "{") || eq(p, "{}"))
  544. X                continue;
  545. X        while (c = *p++)
  546. X            (*f)(c);
  547. X    }
  548. X}
  549. X/*
  550. Xstatic
  551. Xscan(t, f)
  552. X    register char **t;
  553. X    int (*f)();
  554. X{
  555. X    register char *p, c;
  556. X
  557. X    while (p = *t++)
  558. X        while (c = *p)
  559. X            *p++ = (*f)(c);
  560. X} */
  561. X
  562. Xstatic
  563. Xtglob(c)
  564. X    register char c;
  565. X{
  566. X
  567. X    if (any(c, globchars))
  568. X        gflag |= c == '{' ? 2 : 1;
  569. X    return (c);
  570. X}
  571. X/*
  572. Xstatic
  573. Xtrim(c)
  574. X    char c;
  575. X{
  576. X
  577. X    return (c & TRIM);
  578. X} */
  579. X
  580. X
  581. Xletter(c)
  582. X    register char c;
  583. X{
  584. X
  585. X    return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
  586. X}
  587. X
  588. Xdigit(c)
  589. X    register char c;
  590. X{
  591. X
  592. X    return (c >= '0' && c <= '9');
  593. X}
  594. X
  595. Xany(c, s)
  596. X    register int c;
  597. X    register char *s;
  598. X{
  599. X
  600. X    while (*s)
  601. X        if (*s++ == c)
  602. X            return(1);
  603. X    return(0);
  604. X}
  605. Xblklen(av)
  606. X    register char **av;
  607. X{
  608. X    register int i = 0;
  609. X
  610. X    while (*av++)
  611. X        i++;
  612. X    return (i);
  613. X}
  614. X
  615. Xchar **
  616. Xblkcpy(oav, bv)
  617. X    char **oav;
  618. X    register char **bv;
  619. X{
  620. X    register char **av = oav;
  621. X
  622. X    while (*av++ = *bv++)
  623. X        continue;
  624. X    return (oav);
  625. X}
  626. X
  627. Xblkfree(av0)
  628. X    char **av0;
  629. X{
  630. X    register char **av = av0;
  631. X
  632. X    while (*av)
  633. X        free(*av++);
  634. X/*    free((char *)av0);            BAD BAD BAD BAD */
  635. X}
  636. X
  637. Xstatic
  638. Xchar *
  639. Xstrspl(cp, dp)
  640. X    register char *cp, *dp;
  641. X{
  642. X    register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));
  643. X
  644. X    if (ep == (char *)0)
  645. X        { perror("Out of memory 1"); exit(1); }
  646. X    (void) strcpy(ep, cp);
  647. X    (void) strcat(ep, dp);
  648. X    return (ep);
  649. X}
  650. X
  651. Xchar **
  652. Xcopyblk(v)
  653. X    register char **v;
  654. X{
  655. X    register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
  656. X                        sizeof(char **)));
  657. X    if (nv == (char **)0)
  658. X        { perror("Out of memory 2"); exit(2); }
  659. X
  660. X    return (blkcpy(nv, v));
  661. X}
  662. X
  663. Xstatic
  664. Xchar *
  665. Xstrend(cp)
  666. X    register char *cp;
  667. X{
  668. X
  669. X    while (*cp)
  670. X        cp++;
  671. X    return (cp);
  672. X}
  673. X/*
  674. X * Extract a home directory from the password file
  675. X * The argument points to a buffer where the name of the
  676. X * user whose home directory is sought is currently.
  677. X * We write the home directory of the user back there.
  678. X */
  679. Xgethdir(home)
  680. X    char *home;
  681. X{
  682. X}
  683. END_OF_FILE
  684.   if test 10233 -ne `wc -c <'bsd_src/glob.c'`; then
  685.     echo shar: \"'bsd_src/glob.c'\" unpacked with wrong size!
  686.   fi
  687.   # end of 'bsd_src/glob.c'
  688. fi
  689. if test -f 'bsd_src/ls.h' -a "${1}" != "-c" ; then 
  690.   echo shar: Will not clobber existing file \"'bsd_src/ls.h'\"
  691. else
  692.   echo shar: Extracting \"'bsd_src/ls.h'\" \(2175 characters\)
  693.   sed "s/^X//" >'bsd_src/ls.h' <<'END_OF_FILE'
  694. X/*
  695. X * Copyright (c) 1989 The Regents of the University of California.
  696. X * All rights reserved.
  697. X *
  698. X * This code is derived from software contributed to Berkeley by
  699. X * Michael Fischbein.
  700. X *
  701. X * Redistribution and use in source and binary forms are permitted
  702. X * provided that: (1) source distributions retain this entire copyright
  703. X * notice and comment, and (2) distributions including binaries display
  704. X * the following acknowledgement:  ``This product includes software
  705. X * developed by the University of California, Berkeley and its contributors''
  706. X * in the documentation or other materials provided with the distribution
  707. X * and in all advertising materials mentioning features or use of this
  708. X * software. Neither the name of the University nor the names of its
  709. X * contributors may be used to endorse or promote products derived
  710. X * from this software without specific prior written permission.
  711. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  712. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  713. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  714. X *
  715. X *    @(#)ls.h    5.10 (Berkeley) 4/8/90
  716. X */
  717. X
  718. Xtypedef struct _lsstruct {
  719. X    char *name;            /* file name */
  720. X    int len;            /* file name length */
  721. X    struct stat lstat;        /* lstat(2) for file */
  722. X} LS;
  723. X
  724. X/*
  725. X * overload -- we probably have to save blocks and/or maxlen with the lstat
  726. X * array, so tabdir() stuffs it into unused fields in the first stat structure.
  727. X * If there's ever a type larger than u_long, fix this.  Any calls to qsort
  728. X * must save and restore the values.
  729. X */
  730. X#define    st_btotal    st_dev
  731. X#define    st_maxlen    st_rdev
  732. X
  733. Xextern int errno;
  734. X
  735. Xextern int f_accesstime;    /* use time of last access */
  736. Xextern int f_group;        /* show group ownership of a file */
  737. Xextern int f_inode;        /* print inode */
  738. Xextern int f_kblocks;        /* print size in kilobytes */
  739. Xextern int f_longform;        /* long listing format */
  740. Xextern int f_singlecol;        /* use single column output */
  741. Xextern int f_size;        /* list size in short listing */
  742. Xextern int f_statustime;    /* use time of last mode change */
  743. Xextern int f_total;        /* if precede with "total" line */
  744. Xextern int f_type;        /* add type character for non-regular files */
  745. END_OF_FILE
  746.   if test 2175 -ne `wc -c <'bsd_src/ls.h'`; then
  747.     echo shar: \"'bsd_src/ls.h'\" unpacked with wrong size!
  748.   fi
  749.   # end of 'bsd_src/ls.h'
  750. fi
  751. if test -f 'bsd_src/print.c' -a "${1}" != "-c" ; then 
  752.   echo shar: Will not clobber existing file \"'bsd_src/print.c'\"
  753. else
  754.   echo shar: Extracting \"'bsd_src/print.c'\" \(4381 characters\)
  755.   sed "s/^X//" >'bsd_src/print.c' <<'END_OF_FILE'
  756. X/*
  757. X * Copyright (c) 1989 The Regents of the University of California.
  758. X * All rights reserved.
  759. X *
  760. X * This code is derived from software contributed to Berkeley by
  761. X * Michael Fischbein.
  762. X *
  763. X * Redistribution and use in source and binary forms are permitted
  764. X * provided that: (1) source distributions retain this entire copyright
  765. X * notice and comment, and (2) distributions including binaries display
  766. X * the following acknowledgement:  ``This product includes software
  767. X * developed by the University of California, Berkeley and its contributors''
  768. X * in the documentation or other materials provided with the distribution
  769. X * and in all advertising materials mentioning features or use of this
  770. X * software. Neither the name of the University nor the names of its
  771. X * contributors may be used to endorse or promote products derived
  772. X * from this software without specific prior written permission.
  773. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  774. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  775. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  776. X */
  777. X
  778. X#ifndef lint
  779. Xstatic char sccsid[] = "@(#)print.c    5.22 (Berkeley) 5/10/90";
  780. X#endif /* not lint */
  781. X
  782. X#include <sys/types.h>
  783. X#include <sys/param.h>
  784. X#include <sys/stat.h>
  785. X#include <stdio.h>
  786. X#include <grp.h>
  787. X#include <pwd.h>
  788. X#include <utmp.h>
  789. X#include "ls.h"
  790. X#include "tweak.h"
  791. X
  792. X#define BLK(A) (((A)+1023)/1024)
  793. X
  794. Xprintscol(stats, num)
  795. X    register LS *stats;
  796. X    register int num;
  797. X{
  798. X    for (; num--; ++stats) {
  799. X        (void)printaname(stats);
  800. X        (void)putchar('\n');
  801. X    }
  802. X}
  803. X
  804. Xprintlong(stats, num)
  805. X    LS *stats;
  806. X    register int num;
  807. X{
  808. X    extern int errno;
  809. X    char *modep;
  810. X
  811. X    if (f_total)
  812. X        (void)printf("total %lu\n", stats[0].lstat.st_btotal);
  813. X    for (; num--; ++stats) {
  814. X        if (f_inode) (void)printf("%6lu ", stats->lstat.st_ino);
  815. X        if (f_size ) (void)printf("%4ld ", BLK(stats->lstat.st_size));
  816. X        modep = ((S_IFDIR & stats->lstat.st_mode)) ? "drwxrwxrwx"
  817. X                            : "-rw-rw-rw-" ;
  818. X
  819. X        (void)printf("%s %3u %-*s ",
  820. X            modep, stats->lstat.st_nlink, 8, "nobody");
  821. X        if (f_group)
  822. X            (void)printf("%-*s ", 8, "nobody");
  823. X        else
  824. X            (void)printf("%8ld ", stats->lstat.st_size);
  825. X        if (f_accesstime)
  826. X            printtime(stats->lstat.st_atime);
  827. X        else if (f_statustime)
  828. X            printtime(stats->lstat.st_ctime);
  829. X        else
  830. X            printtime(stats->lstat.st_mtime);
  831. X        (void)printf("%s", stats->name);
  832. X        if (f_type)
  833. X            (void)printtype(stats->lstat.st_mode);
  834. X        (void)putchar('\n');
  835. X    }
  836. X}
  837. X
  838. X#define    TAB    8
  839. X
  840. Xprintcol(stats, num)
  841. X    LS *stats;
  842. X    int num;
  843. X{
  844. X    extern int termwidth;
  845. X    register int base, chcnt, cnt, col, colwidth;
  846. X    int endcol, numcols, numrows, row;
  847. X
  848. X    colwidth = stats[0].lstat.st_maxlen;
  849. X    if (f_inode)
  850. X        colwidth += 6;
  851. X    if (f_size)
  852. X        colwidth += 5;
  853. X    if (f_type)
  854. X        colwidth += 1;
  855. X
  856. X    colwidth = (colwidth + TAB) & ~(TAB - 1);
  857. X    if (termwidth < 2 * colwidth) {
  858. X        printscol(stats, num);
  859. X        return;
  860. X    }
  861. X
  862. X    numcols = termwidth / colwidth;
  863. X    numrows = num / numcols;
  864. X    if (num % numcols)
  865. X        ++numrows;
  866. X
  867. X    if (f_size && f_total)
  868. X        (void)printf("total %lu\n", stats[0].lstat.st_btotal);
  869. X    for (row = 0; row < numrows; ++row) {
  870. X        endcol = colwidth;
  871. X        for (base = row, chcnt = col = 0; col < numcols; ++col) {
  872. X            chcnt += printaname(stats + base);
  873. X            if ((base += numrows) >= num)
  874. X                break;
  875. X            while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
  876. X                (void)putchar('\t');
  877. X                chcnt = cnt;
  878. X            }
  879. X            endcol += colwidth;
  880. X        }
  881. X        putchar('\n');
  882. X    }
  883. X}
  884. X
  885. X/*
  886. X * print [inode] [size] name
  887. X * return # of characters printed, no trailing characters
  888. X */
  889. Xprintaname(lp)
  890. X    LS *lp;
  891. X{
  892. X    int chcnt;
  893. X
  894. X    chcnt = 0;
  895. X
  896. X    if (f_inode)
  897. X    {
  898. X        printf("%5lu ", lp->lstat.st_ino);
  899. X        chcnt += 6;
  900. X    }
  901. X
  902. X    if (f_size)
  903. X    {
  904. X        printf("%4ld ", BLK(lp->lstat.st_size));
  905. X        chcnt += 5;
  906. X    }
  907. X
  908. X    printf("%s", lp->name); chcnt += strlen(lp->name);
  909. X
  910. X    if (f_type)
  911. X    {
  912. X        chcnt += printtype(lp->lstat.st_mode);
  913. X    }
  914. X
  915. X    return(chcnt);
  916. X}
  917. X
  918. Xprinttime(ftime)
  919. X    time_t ftime;
  920. X{
  921. X    int i;
  922. X    char *longstring, *ctime();
  923. X    time_t time();
  924. X
  925. X    longstring = ctime((long *)&ftime);
  926. X    for (i = 4; i < 11; ++i)
  927. X        (void)putchar(longstring[i]);
  928. X
  929. X#define    SIXMONTHS    ((365 / 2) * 24 * 60 * 60)
  930. X    if (ftime + SIXMONTHS > time((time_t *)NULL))
  931. X        for (i = 11; i < 16; ++i)
  932. X            (void)putchar(longstring[i]);
  933. X    else {
  934. X        (void)putchar(' ');
  935. X        for (i = 20; i < 24; ++i)
  936. X            (void)putchar(longstring[i]);
  937. X    }
  938. X    (void)putchar(' ');
  939. X}
  940. X
  941. Xprinttype(mode)
  942. X    mode_t mode;
  943. X{
  944. X    switch(mode & S_IFMT) {
  945. X    case S_IFDIR:
  946. X        (void)putchar('/');
  947. X        return(1);
  948. X    }
  949. X    return(0);
  950. X}
  951. END_OF_FILE
  952.   if test 4381 -ne `wc -c <'bsd_src/print.c'`; then
  953.     echo shar: \"'bsd_src/print.c'\" unpacked with wrong size!
  954.   fi
  955.   # end of 'bsd_src/print.c'
  956. fi
  957. if test -f 'client_lib.c' -a "${1}" != "-c" ; then 
  958.   echo shar: Will not clobber existing file \"'client_lib.c'\"
  959. else
  960.   echo shar: Extracting \"'client_lib.c'\" \(4057 characters\)
  961.   sed "s/^X//" >'client_lib.c' <<'END_OF_FILE'
  962. X    /*********************************************************************\
  963. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  964. X    *                                                                     *
  965. X    *  You may copy or modify this file in any manner you wish, provided  *
  966. X    *  that this notice is always included, and that you hold the author  *
  967. X    *  harmless for any loss or damage resulting from the installation or *
  968. X    *  use of this software.                                              *
  969. X    \*********************************************************************/
  970. X
  971. X#include "client_def.h"
  972. X
  973. Xextern int errno;
  974. X
  975. Xstatic int myfd;
  976. Xstatic struct sockaddr_in server_addr;
  977. Xstatic unsigned short myseq = 0;
  978. Xstatic unsigned short key;
  979. X
  980. Xint client_trace      = 0;
  981. Xint client_intr_state = 0;
  982. Xunsigned long target_delay    = 3000L;    /* expected max delay     */
  983. Xunsigned long busy_delay        = 3000L;    /* busy retransmit timer */
  984. Xunsigned long idle_delay    = 3000L;    /* idle retransmit timer */
  985. Xunsigned long udp_sent_time;
  986. X
  987. XUBUF *client_interact(cmd,pos,l1,p1,l2,p2)
  988. X    unsigned cmd, l1, l2;
  989. X    unsigned long pos;
  990. X    unsigned char *p1, *p2;
  991. X{
  992. X    struct sockaddr_in from;
  993. X    UBUF sbuf;
  994. X    static UBUF rbuf;
  995. X    unsigned char *s, *t, *d;
  996. X    unsigned u, n, sum, mask, mlen;
  997. X    int retval, bytes, retry_send, retry_recv;
  998. X    unsigned long w_delay;
  999. X
  1000. X    sbuf.cmd = cmd;
  1001. X    sbuf.len = htons(l1);
  1002. X    sbuf.pos = htonl(pos);
  1003. X
  1004. X    client_intr_state = 1;
  1005. X
  1006. X    for(u = l1, d = (unsigned char *) sbuf.buf; u--; *d++ = *p1++);
  1007. X    for(u = l2                      ; u--; *d++ = *p2++);
  1008. X    mlen = d - (unsigned char *) &sbuf;
  1009. X
  1010. X    key = client_get_key();
  1011. X
  1012. X    for(retry_send = 0; ; retry_send++)
  1013. X    {
  1014. X    sbuf.key = key;
  1015. X    sbuf.seq = (myseq & 0xfffc) | (retry_send & 0x0003);
  1016. X    sbuf.sum = 0;
  1017. X
  1018. X    for(t = (unsigned char *) &sbuf, sum = n = mlen; n--; sum += *t++);
  1019. X    sbuf.sum = sum + (sum >> 8);
  1020. X
  1021. X    switch(retry_send)    /* adaptive retry delay adjustments */
  1022. X    {
  1023. X        case  0: busy_delay = (target_delay+(busy_delay<<3)-busy_delay)>>3;
  1024. X             w_delay = busy_delay;
  1025. X             break;
  1026. X
  1027. X        case  1: busy_delay = busy_delay + (busy_delay >> 1);
  1028. X             w_delay = busy_delay;
  1029. X             if(client_trace) write(2,"R",1);
  1030. X             break;
  1031. X
  1032. X        default: if(idle_delay < 5*60*1000) idle_delay = idle_delay << 1;
  1033. X             w_delay = idle_delay;
  1034. X             if(client_trace) write(2,"I",1);
  1035. X             break;
  1036. X    }
  1037. X
  1038. X    if(sendto(myfd,&sbuf,mlen,0,&server_addr,sizeof(server_addr)) == -1)
  1039. X                        { perror("sendto"); exit(1); }
  1040. X    udp_sent_time = time((time_t *) 0);
  1041. X    mask = 1 << myfd;
  1042. X
  1043. X    for(retry_recv = 0; ; retry_recv++)
  1044. X    {
  1045. X        if(retry_recv) write(2,"E",1);
  1046. X
  1047. X        retval = _x_select(&mask, w_delay);
  1048. X
  1049. X        if((retval == -1) && (errno == EINTR)) continue;
  1050. X
  1051. X        if(retval == 1)    /* an incoming message is waiting */
  1052. X        {
  1053. X        bytes = sizeof(from);
  1054. X        if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
  1055. X                    &from,&bytes)) < UBUF_HSIZE) continue;
  1056. X
  1057. X        s = (unsigned char *) &rbuf;
  1058. X        d = s + bytes;
  1059. X        u = rbuf.sum; rbuf.sum = 0;
  1060. X        for(t = s, sum = 0; t < d; sum += *t++);
  1061. X        sum = (sum + (sum >> 8)) & 0xff;
  1062. X        if(sum != u) continue;  /* wrong check sum */
  1063. X
  1064. X        rbuf.len = htons(rbuf.len);
  1065. X        rbuf.pos = htonl(rbuf.pos);
  1066. X
  1067. X        if((rbuf.seq & 0xfffc) != myseq) continue;  /* wrong seq # */
  1068. X        if(rbuf.len+UBUF_HSIZE  > bytes) continue;  /* truncated.  */
  1069. X
  1070. X        myseq = (myseq + 0x0004) & 0xfffc;  /* seq for next request */
  1071. X        key   = rbuf.key;            /* key for next request */
  1072. X
  1073. X        client_put_key(key);
  1074. X
  1075. X        if(client_intr_state == 2)
  1076. X        {
  1077. X            if(!key_persists) client_done();
  1078. X            exit(1);
  1079. X        }
  1080. X
  1081. X        return(&rbuf);
  1082. X
  1083. X        } else break;   /* go back to re-transmit buffer again */
  1084. X    }
  1085. X    }
  1086. X}
  1087. X
  1088. Xinit_client(host,port,myport)
  1089. X    char *host;
  1090. X    int   port;
  1091. X    int myport;
  1092. X{
  1093. X    busy_delay = idle_delay = target_delay;
  1094. X
  1095. X    if((myfd = _x_udp(&myport)) == -1)
  1096. X        { perror("socket open"); exit(1); }
  1097. X
  1098. X    if(_x_adr(host,port,&server_addr) == -1)
  1099. X        { perror("server addr"); exit(1); } 
  1100. X
  1101. X    client_init_key(server_addr.sin_addr.s_addr,port,getpid());
  1102. X}
  1103. X
  1104. Xclient_done()
  1105. X{
  1106. X    (void) client_interact(CC_BYE,0L,0,NULLP,0,NULLP);
  1107. X}
  1108. END_OF_FILE
  1109.   if test 4057 -ne `wc -c <'client_lib.c'`; then
  1110.     echo shar: \"'client_lib.c'\" unpacked with wrong size!
  1111.   fi
  1112.   # end of 'client_lib.c'
  1113. fi
  1114. if test -f 'common_def.h' -a "${1}" != "-c" ; then 
  1115.   echo shar: Will not clobber existing file \"'common_def.h'\"
  1116. else
  1117.   echo shar: Extracting \"'common_def.h'\" \(5145 characters\)
  1118.   sed "s/^X//" >'common_def.h' <<'END_OF_FILE'
  1119. X    /*********************************************************************\
  1120. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1121. X    *                                                                     *
  1122. X    *  You may copy or modify this file in any manner you wish, provided  *
  1123. X    *  that this notice is always included, and that you hold the author  *
  1124. X    *  harmless for any loss or damage resulting from the installation or *
  1125. X    *  use of this software.                                              *
  1126. X    \*********************************************************************/
  1127. X
  1128. X#include <stdio.h>
  1129. X#include <sys/param.h>
  1130. X#include <sys/types.h>
  1131. X#include <errno.h>
  1132. X#include <sys/socket.h>
  1133. X#include <netinet/in.h>
  1134. X#include <sys/stat.h>
  1135. X#include <sys/time.h>
  1136. X#include <fcntl.h>
  1137. X#include <signal.h>
  1138. X
  1139. X#ifdef DIRENT
  1140. X#include <dirent.h>
  1141. X#else
  1142. X#include <sys/dir.h>
  1143. X#endif
  1144. X
  1145. X/****************************************************************************
  1146. X*  UBUF is the structure of message exchanged between server and clients. 
  1147. X*
  1148. X*    The 'buf' part of the buffer is variable lenght up to max of 1024.
  1149. X*    The 'key' field is used by the server for sequence identification.
  1150. X*    The 'seq' field is used by the client for sequence identification.
  1151. X*
  1152. X*  Client's message to server contain a key value that is the same as the
  1153. X*  key value of the previous message received from the server.  Similarly,
  1154. X*  the server's message to client contains a seq value that is the same
  1155. X*  as the seq value of the previous message from the client. 
  1156. X*
  1157. X*  The buf field is logically partitioned into two parts by the len field.
  1158. X*  The len field indicate the size of the first part of the buffer starting
  1159. X*  at buf[0].  The rest of the buffer is the second field.  In some cases
  1160. X*  both fields can contain information.
  1161. X*
  1162. X****************************************************************************/
  1163. X
  1164. X#define UBUF_HSIZE 12                           /* 12 bytes for the header */
  1165. X#define UBUF_SPACE 1024                    /* maximum payload.        */
  1166. X
  1167. Xtypedef struct UBUF {            char   cmd;  /* message code.             */
  1168. X                        unsigned char   sum;  /* message checksum.         */
  1169. X                        unsigned short  key;  /* message key.              */
  1170. X                        unsigned short  seq;  /* message sequence number.  */
  1171. X                        unsigned short  len;  /* number of bytes in buf 1. */
  1172. X                        unsigned long   pos;  /* location in the file.     */
  1173. X
  1174. X                        char   buf[UBUF_SPACE];
  1175. X                    } UBUF;
  1176. X
  1177. X/* definition of cmd */
  1178. X
  1179. X#define CC_VERSION    0x10    /* return server's version string.    */
  1180. X#define CC_ERR          0x40    /* error response from server.          */
  1181. X#define CC_GET_DIR      0x41    /* get a directory listing.             */
  1182. X#define CC_GET_FILE     0x42    /* get a file.                          */
  1183. X#define CC_UP_LOAD      0x43    /* open a file for writing.             */
  1184. X#define CC_INSTALL      0x44    /* close a file opened for writing.     */
  1185. X#define CC_DEL_FILE     0x45    /* delete a file.                       */
  1186. X#define CC_DEL_DIR      0x46    /* delete a directory.                  */
  1187. X#define CC_GET_PRO      0x47    /* get directory protection.            */
  1188. X#define CC_SET_PRO      0x48    /* set directory protection.            */
  1189. X#define CC_MAKE_DIR     0x49    /* create a directory.                  */
  1190. X#define CC_BYE          0x4A    /* finish a session.                    */
  1191. X#define CC_GRAB_FILE    0x4B    /* atomic get+delete a file.        */
  1192. X#define CC_GRAB_DONE    0x4C    /* atomic get+delete a file done.    */
  1193. X#define CC_LIMIT    0x80    /* # > 0x7f for future cntrl blk ext.   */
  1194. X
  1195. X/****************************************************************************
  1196. X*  RDIRENT is the structure of a directory entry contained in a .FSP_CONTENT
  1197. X*  file.  Each entry contains a 4 bytes quantity 'time', a 4 bytes quentity
  1198. X*  'size', and 1 byte of 'type'.  Then followed by x number of bytes of
  1199. X*  'name'.  'name' is null terminated.  Then followed by enough number of
  1200. X*  padding to fill to an 4-byte boundary.  At this point, if the next entry
  1201. X*  to follow will spread across 1k boundary, then two possible things will
  1202. X*  happen.  1) if the header fits between this entry and the 1k boundary,
  1203. X*  a complete header will be filled in with a 'type' set to RDTYPE_SKIP.
  1204. X*  And then enough bytes to padd to 1k boundary.  2) if the header does
  1205. X*  not fit, then simply pad to the 1k boundary.  This will make sure that
  1206. X*  messages carrying directory information carry only complete directory
  1207. X*  entries and no fragmented entries.  The last entry is type RDTYPE_END.
  1208. X****************************************************************************/
  1209. X
  1210. X#define RDHSIZE (2*sizeof(unsigned long)+sizeof(unsigned char))
  1211. X
  1212. Xtypedef struct RDIRENT { unsigned long  time;
  1213. X                         unsigned long  size;
  1214. X                         unsigned char  type;
  1215. X                         char        name[1]; } RDIRENT;
  1216. X
  1217. X#define RDTYPE_END      0x00
  1218. X#define RDTYPE_FILE     0x01
  1219. X#define RDTYPE_DIR      0x02
  1220. X#define RDTYPE_SKIP     0x2A
  1221. X
  1222. X#define NULLP ((char *) 0)
  1223. END_OF_FILE
  1224.   if test 5145 -ne `wc -c <'common_def.h'`; then
  1225.     echo shar: \"'common_def.h'\" unpacked with wrong size!
  1226.   fi
  1227.   # end of 'common_def.h'
  1228. fi
  1229. if test -f 'fcdcmd.1' -a "${1}" != "-c" ; then 
  1230.   echo shar: Will not clobber existing file \"'fcdcmd.1'\"
  1231. else
  1232.   echo shar: Extracting \"'fcdcmd.1'\" \(2145 characters\)
  1233.   sed "s/^X//" >'fcdcmd.1' <<'END_OF_FILE'
  1234. X.TH FCD 1 "8 December 1991"
  1235. X.SH NAME
  1236. Xfcdcmd, fcd \- change client's current working directory in the FSP database
  1237. X.SH SYNOPSIS
  1238. X.B fcdcmd
  1239. X.I path
  1240. X.LP
  1241. X.B fcd
  1242. X.I path
  1243. X.SH DESCRIPTION
  1244. X.LP
  1245. XIf no paths are given, / is used as the current working directory.  If
  1246. X.I path
  1247. Xbegins with a /,
  1248. X.B fcdcmd
  1249. Xuses it as the current working directory.  Otherwise,
  1250. X.B fcdcmd
  1251. Xappends
  1252. X.I path
  1253. Xto the end of the current working directory.  In both cases,
  1254. X.B fcdcmd
  1255. Xsimplifies the new path and writes it to the
  1256. X.I stdout.
  1257. XIn order for the effect of
  1258. X.B fcdcmd
  1259. Xto be felt in subsequent FSP transactions, user needs to save the
  1260. X.I stdout
  1261. Xoutput in the
  1262. X.I FSP_DIR
  1263. Xvariable.  If the change is successful,
  1264. X.B fcdcmd
  1265. Xwill display the protection setting of the new working directory.
  1266. X.LP
  1267. X.B fcdcmd
  1268. Xwill perform
  1269. X.B csh
  1270. Xfile name globbing based on file and directory information
  1271. Xobtained from the FSP database.
  1272. X.LP
  1273. XSince user's command shells generally cannot do the proper globbing for
  1274. Xthis program, it is recommended that user defines a shell alias or
  1275. Xfucntion to turns off command shell globbing before running this program.
  1276. X.B csh
  1277. Xexample:
  1278. X.LP
  1279. X.nf
  1280. Xalias fcd setenv FSP_DIR \e`\e(set noglob\e; exec fcdcmd \e!\e*\e)\e`
  1281. X.fi
  1282. X.SH ENVIRONMENT
  1283. X.LP
  1284. XThe following variables associate this program with a FSP database:
  1285. X.TP
  1286. X.B FSP_HOST
  1287. XThe name or internet number of the machine with the FSP server.
  1288. X.TP
  1289. X.B FSP_PORT
  1290. XThe port number of the UDP socket used by the FSP server.
  1291. X.TP
  1292. X.B FSP_LOCALPORT
  1293. XThe port number of the UDP socket used by FSP client utilities.
  1294. XThe only reason to define this varable is to ensure mutual
  1295. Xexclusion of client commands when none of the udp packet
  1296. Xmultiplexing mechanisms are enabled during compile time.
  1297. XYou may pick any number not currently used for other purposes.
  1298. X.TP
  1299. X.B FSP_DIR
  1300. XThe current working directory of the client in the FSP database.
  1301. XThe root of the database is /.
  1302. X.SH "SEE ALSO"
  1303. X.PD
  1304. Xfcatcmd(1), fcdcmd(1), fgetcmd(1), fgrabcmd(1), flscmd(1), fmkdir(1),
  1305. Xfprocmd(1), fput(1), frmcmd(1), frmdircmd(1), fver(1), fspd(1)
  1306. X.br
  1307. X.ne 5
  1308. X.SH BUGS
  1309. X.LP
  1310. XIf more than one
  1311. X.B paths
  1312. Xare given, only the first one will be used.
  1313. XThe rest will be silently ignored.
  1314. END_OF_FILE
  1315.   if test 2145 -ne `wc -c <'fcdcmd.1'`; then
  1316.     echo shar: \"'fcdcmd.1'\" unpacked with wrong size!
  1317.   fi
  1318.   # end of 'fcdcmd.1'
  1319. fi
  1320. if test -f 'fgrabcmd.1' -a "${1}" != "-c" ; then 
  1321.   echo shar: Will not clobber existing file \"'fgrabcmd.1'\"
  1322. else
  1323.   echo shar: Extracting \"'fgrabcmd.1'\" \(2112 characters\)
  1324.   sed "s/^X//" >'fgrabcmd.1' <<'END_OF_FILE'
  1325. X.TH FGET 1 "8 December 1991"
  1326. X.SH NAME
  1327. Xfgrabcmd, fgrab \- download files from the FSP database
  1328. X.SH SYNOPSIS
  1329. X.B fgrabcmd
  1330. X.br
  1331. X.B fgrabcmd
  1332. X.I filename
  1333. X\&.\|.\|.
  1334. X.LP
  1335. X.B fgrab
  1336. X.br
  1337. X.B fgrab
  1338. X.I filename
  1339. X\&.\|.\|.
  1340. X.SH DESCRIPTION
  1341. X.LP
  1342. XWhen used without arguments, a list of file names is read from the
  1343. Xstandard input.  When arguments are given, the arguments are taken
  1344. Xto be the list of file names.  For each file named in the list,
  1345. X.B fgrabcmd
  1346. Xcopies the file to the client's current working directory in the
  1347. Xclient machine, and deletes it from the FSP database.
  1348. XIt is guaranteed that multiple concurrent grab actions appear to be
  1349. Xmutually exclusive.
  1350. X.B fgrabcmd
  1351. Xwill perform
  1352. X.B csh
  1353. Xfile name globbing based on file and directory information
  1354. Xobtained from the FSP database.
  1355. X.LP
  1356. XSince user's command shells generally cannot do the proper globbing for
  1357. Xthis program, it is recommended that user defines a shell alias or
  1358. Xfucntion to turns off command shell globbing before running this program.
  1359. X.B csh
  1360. Xexample:
  1361. X.LP
  1362. X.nf
  1363. Xalias fgrab \e(set noglob\e; exec fgrabcmd \e!\e*\e)
  1364. X.fi
  1365. X.SH ENVIRONMENT
  1366. X.LP
  1367. XThe following variables associate this program with a FSP database:
  1368. X.TP
  1369. X.B FSP_HOST
  1370. XThe name or internet number of the machine with the FSP server.
  1371. X.TP
  1372. X.B FSP_PORT
  1373. XThe port number of the UDP socket used by the FSP server.
  1374. X.TP
  1375. X.B FSP_LOCALPORT
  1376. XThe port number of the UDP socket used by FSP client utilities.
  1377. XThe only reason to define this varable is to ensure mutual
  1378. Xexclusion of client commands when none of the udp packet
  1379. Xmultiplexing mechanisms are enabled during compile time.
  1380. XYou may pick any number not currently used for other purposes.
  1381. X.TP
  1382. X.B FSP_DIR
  1383. XThe current working directory of the client in the FSP database.
  1384. XThe root of the database is /.
  1385. X.TP
  1386. X.B FSP_TRACE
  1387. XIf this variable is set,   
  1388. X.B fgrabcmd
  1389. Xwill display the number of kilo-byte blocks transfered as transfer 
  1390. Xprogresses. 
  1391. X.SH "BUGS"
  1392. XIf
  1393. X.B fgrab
  1394. Xis interrupted, the file being copied is deleted nonetheless.
  1395. X.SH "SEE ALSO"
  1396. X.PD
  1397. Xfcatcmd(1), fcdcmd(1), fgetcmd(1), fgrabcmd(1), flscmd(1), fmkdir(1),
  1398. Xfprocmd(1), fput(1), frmcmd(1), frmdircmd(1), fver(1), fspd(1)
  1399. END_OF_FILE
  1400.   if test 2112 -ne `wc -c <'fgrabcmd.1'`; then
  1401.     echo shar: \"'fgrabcmd.1'\" unpacked with wrong size!
  1402.   fi
  1403.   # end of 'fgrabcmd.1'
  1404. fi
  1405. if test -f 'fprocmd.c' -a "${1}" != "-c" ; then 
  1406.   echo shar: Will not clobber existing file \"'fprocmd.c'\"
  1407. else
  1408.   echo shar: Extracting \"'fprocmd.c'\" \(1689 characters\)
  1409.   sed "s/^X//" >'fprocmd.c' <<'END_OF_FILE'
  1410. X    /*********************************************************************\
  1411. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1412. X    *                                                                     *
  1413. X    *  You may copy or modify this file in any manner you wish, provided  *
  1414. X    *  that this notice is always included, and that you hold the author  *
  1415. X    *  harmless for any loss or damage resulting from the installation or *
  1416. X    *  use of this software.                                              *
  1417. X    \*********************************************************************/
  1418. X
  1419. X#include "client_def.h"
  1420. X
  1421. Xextern char **glob(), *util_abs_path();
  1422. X
  1423. Xstatic print_pro(p)
  1424. X    char *p;
  1425. X{
  1426. X    char *op;
  1427. X    UBUF *ub;
  1428. X
  1429. X    op = util_abs_path(p);
  1430. X
  1431. X    ub = client_interact(CC_GET_PRO,0L, strlen(op),op+1, 0,NULLP);
  1432. X
  1433. X    printf("%s\t: %s\n",p,ub->buf);
  1434. X
  1435. X    return(0);
  1436. X}
  1437. X
  1438. Xstatic set_pro(p,key)
  1439. X    char *p, *key;
  1440. X{
  1441. X    char *op;
  1442. X    UBUF *ub;
  1443. X
  1444. X    op = util_abs_path(p);
  1445. X
  1446. X    ub = client_interact(CC_SET_PRO,0L, strlen(op),op+1, strlen(key)+1,key);
  1447. X
  1448. X    printf("%s\t: %s\n",p,ub->buf);
  1449. X
  1450. X    return(0);
  1451. X}
  1452. X
  1453. Xmain(argc,argv,envp)
  1454. X    int argc;
  1455. X    char **argv,**envp;
  1456. X{
  1457. X    char **av, *av2[2], *key;
  1458. X
  1459. X    env_client();
  1460. X
  1461. X    if(argv[1]    && (argv[1][0] == '+' || argv[1][0] == '-') && !argv[1][2])
  1462. X    {
  1463. X        key = *++argv;
  1464. X
  1465. X    while(*++argv)
  1466. X    {
  1467. X        if(!(av = glob(*argv))) { av = av2; av2[0] = *argv; av2[1] = 0; }
  1468. X        while(*av) set_pro(*av++,key);
  1469. X    }
  1470. X
  1471. X    } else
  1472. X    {
  1473. X    if(argv[1]) while(*++argv)
  1474. X    {
  1475. X        if(!(av = glob(*argv))) { av = av2; av2[0] = *argv; av2[1] = 0; }
  1476. X        while(*av) print_pro(*av++);
  1477. X
  1478. X    } else print_pro(".");
  1479. X    }
  1480. X
  1481. X    client_done();
  1482. X
  1483. X    exit(0);
  1484. X}
  1485. END_OF_FILE
  1486.   if test 1689 -ne `wc -c <'fprocmd.c'`; then
  1487.     echo shar: \"'fprocmd.c'\" unpacked with wrong size!
  1488.   fi
  1489.   # end of 'fprocmd.c'
  1490. fi
  1491. if test -f 'fspd.1' -a "${1}" != "-c" ; then 
  1492.   echo shar: Will not clobber existing file \"'fspd.1'\"
  1493. else
  1494.   echo shar: Extracting \"'fspd.1'\" \(2370 characters\)
  1495.   sed "s/^X//" >'fspd.1' <<'END_OF_FILE'
  1496. X.TH FSPD 1 "8 December 1991"
  1497. X.SH NAME
  1498. Xfspd, in.fspd \- server for the FSP database
  1499. X.SH SYNOPSIS
  1500. X.B fspd
  1501. X[
  1502. X.B -h path
  1503. X.B |
  1504. X.B -p port
  1505. X.B |
  1506. X.B -u uid
  1507. X]
  1508. X.LP
  1509. X.B in.fspd
  1510. X.SH DESCRIPTION
  1511. X.B fspd
  1512. Xis the server for an anonymous-ftp style archive called FSP. The main
  1513. Xfeatures of this service are: connection-less model, communication
  1514. Xrobustness, server resource protection, inter-client protection, and user
  1515. Xfriendly interface. Please read the INFO file bundled with the FSP source
  1516. Xfor more information. 
  1517. X.LP
  1518. X.SH FILES
  1519. X.PD 0
  1520. X.TP 20
  1521. X.B .OWN.XXXXXXXX
  1522. XUsed to indicate the ownership of a directory.  If this file is
  1523. Xpresent in a directory, the directory is owned by the machine whose
  1524. Xinet number is XXXXXXXX when printed as an 8-digit hex number.
  1525. X
  1526. X.TP
  1527. X.B .FSP_OK_DEL
  1528. XExistence of this file in a directory grants non-owner machines
  1529. Xthe permission to delete items from this directory.
  1530. X
  1531. X.TP
  1532. X.B .FSP_OK_ADD
  1533. XExistence of this file in a directory grants non-owner machines
  1534. Xthe permission to add items to this directory.
  1535. X
  1536. X.TP
  1537. X.B .TXXXXXXXXXXXX
  1538. XTransient temporary file in the FSP directory cache directory used for file
  1539. Xuploading.
  1540. X
  1541. X.TP
  1542. X.B .GXXXXXXXXXXXX
  1543. XTransient temporary file in the FSP directory used for file
  1544. Xdownloading through the
  1545. X.B fgrab
  1546. Xcommand.
  1547. X
  1548. X.TP
  1549. X.B .HTAB_DUMP
  1550. XA file created in the top directory when
  1551. X.B fspd
  1552. Xreceives an alarm signal.  It contains a listing of the active
  1553. Xclients in
  1554. X.B fspd's
  1555. Xclient table.
  1556. X
  1557. X.TP
  1558. X.B .ROGUE_HOSTS
  1559. XA file containing a list of inet numbers in the normal 4-part format.
  1560. X.B fspd
  1561. Xwill not respond to messages from machines named in this file.
  1562. X
  1563. X.TP
  1564. X.B .FSP_CONTENT
  1565. XFile used to cache directory listing.  Such files are normally created
  1566. Xon demand in each directory that
  1567. X.B fspd
  1568. Xexports.  If a
  1569. X.B .FSP_CONTENT
  1570. Xfile exists in a directory, but is not writable by the
  1571. X.B fspd
  1572. Xprocess, then the directory cannot be listed.  If it does not exist and
  1573. X.B fspd
  1574. Xfails in its attempt to create a
  1575. X.B .FSP_CONTENT
  1576. Xfile, then
  1577. X.B fspd
  1578. Xwill create one with a hashed name in a cache directory specified during
  1579. Xcompile time.  Options can be set at compile time such that 
  1580. X.B fspd
  1581. Xwill create a cache file in the cache directory even if a
  1582. X.B .FSP_CONTENT
  1583. Xfile could have been created in the directory to be listed.
  1584. X
  1585. X.SH "SEE ALSO"
  1586. X.PD
  1587. Xfcatcmd(1), fcdcmd(1), fgetcmd(1), fgrabcmd(1), flscmd(1), fmkdir(1),
  1588. Xfprocmd(1), fput(1), frmcmd(1), frmdircmd(1), fver(1), fspd(1)
  1589. END_OF_FILE
  1590.   if test 2370 -ne `wc -c <'fspd.1'`; then
  1591.     echo shar: \"'fspd.1'\" unpacked with wrong size!
  1592.   fi
  1593.   # end of 'fspd.1'
  1594. fi
  1595. if test -f 'server_def.h' -a "${1}" != "-c" ; then 
  1596.   echo shar: Will not clobber existing file \"'server_def.h'\"
  1597. else
  1598.   echo shar: Extracting \"'server_def.h'\" \(2399 characters\)
  1599.   sed "s/^X//" >'server_def.h' <<'END_OF_FILE'
  1600. X    /*********************************************************************\
  1601. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1602. X    *                                                                     *
  1603. X    *  You may copy or modify this file in any manner you wish, provided  *
  1604. X    *  that this notice is always included, and that you hold the author  *
  1605. X    *  harmless for any loss or damage resulting from the installation or *
  1606. X    *  use of this software.                                              *
  1607. X    \*********************************************************************/
  1608. X
  1609. X#include "common_def.h"
  1610. X
  1611. X/****************************************************************************
  1612. X*  HTAB is structure for storing client information for one client machine.
  1613. X*  They makes it easy to reuse regular unix tool's source for new purposes.
  1614. X****************************************************************************/
  1615. X
  1616. Xtypedef struct HTAB HTAB;
  1617. X
  1618. Xstruct HTAB {    unsigned long    inet_num;    /* inet number of client     */
  1619. X        unsigned long   last_acc;    /* last sucessful access time*/
  1620. X        unsigned short    next_key;    /* next key client should use*/
  1621. X        unsigned short    last_key;    /* previous key client used  */
  1622. X        unsigned short   acc_cnt;    /* number of successful acc  */
  1623. X        unsigned short  active:1;       /* session continuing.         */
  1624. X        unsigned short inhibit:1; };    /* deny access permission.   */
  1625. X
  1626. X/*****************************************************************************
  1627. X* The PPATH structure is filled in by the function check_path when given a
  1628. X* path string.  See server_file.c for more info.
  1629. X*****************************************************************************/
  1630. X
  1631. Xtypedef struct { char *fullp;
  1632. X         char *f_ptr;
  1633. X         int   f_len;
  1634. X         char *d_ptr;
  1635. X         int   d_len; } PPATH;
  1636. X
  1637. Xextern init_htab();
  1638. Xextern HTAB *find_host();
  1639. Xextern char *check_path();
  1640. X
  1641. Xextern char *server_make_dir();
  1642. Xextern char *server_del_dir();
  1643. Xextern char *server_del_file();
  1644. Xextern char *server_get_dir();
  1645. Xextern char *server_get_file();
  1646. Xextern char *server_get_pro();
  1647. Xextern char *server_set_pro();
  1648. Xextern char *server_up_load();
  1649. Xextern char *server_install();
  1650. Xextern char *server_secure_file();
  1651. Xextern char *server_grab_file();
  1652. Xextern char *server_grab_done();
  1653. X
  1654. Xextern int dbug;
  1655. Xextern char *home_dir;
  1656. Xextern int max_nlen;
  1657. Xextern int always_use_cache_dir;
  1658. Xextern int dir_cache_limit;
  1659. Xextern char *dir_cache_dir;
  1660. END_OF_FILE
  1661.   if test 2399 -ne `wc -c <'server_def.h'`; then
  1662.     echo shar: \"'server_def.h'\" unpacked with wrong size!
  1663.   fi
  1664.   # end of 'server_def.h'
  1665. fi
  1666. if test -f 'server_host.c' -a "${1}" != "-c" ; then 
  1667.   echo shar: Will not clobber existing file \"'server_host.c'\"
  1668. else
  1669.   echo shar: Extracting \"'server_host.c'\" \(4144 characters\)
  1670.   sed "s/^X//" >'server_host.c' <<'END_OF_FILE'
  1671. X    /*********************************************************************\
  1672. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1673. X    *                                                                     *
  1674. X    *  You may copy or modify this file in any manner you wish, provided  *
  1675. X    *  that this notice is always included, and that you hold the author  *
  1676. X    *  harmless for any loss or damage resulting from the installation or *
  1677. X    *  use of this software.                                              *
  1678. X    \*********************************************************************/
  1679. X
  1680. X#include "server_def.h"
  1681. X
  1682. X/****************************************************************************
  1683. X* This file contains routines to maintain client database.
  1684. X****************************************************************************/
  1685. X
  1686. Xextern char *realloc(), *malloc(), *ctime();
  1687. X
  1688. Xstatic HTAB     *htab;        /* client data base.            */
  1689. Xstatic unsigned  hcnt;        /* number of clients.            */
  1690. Xstatic unsigned  htot = 0;    /* available entries in the data base.    */
  1691. Xstatic HTAB     hzero;
  1692. X
  1693. X#define HALLOC_SIZE 30
  1694. X
  1695. X/****************************************************************************
  1696. X* Returns an entry from the database corresponding to to the inet number.
  1697. X* A new entry is created is it is not found.
  1698. X* The database is a linear array of sorted structures.
  1699. X* Entries are searched using binary search on the array.
  1700. X****************************************************************************/
  1701. X
  1702. XHTAB *find_host(inet_num)
  1703. X    unsigned long inet_num;
  1704. X{
  1705. X    unsigned      l, h, m, i;
  1706. X    unsigned long inum;
  1707. X    HTAB      *hs, *hd;
  1708. X
  1709. X    for(l = 0, h = hcnt-1; (m = (l + h) >> 1) != l; )    /* binary search */
  1710. X    {
  1711. X    inum = htab[m].inet_num;
  1712. X    if(inum > inet_num) h = m; else
  1713. X    if(inum < inet_num) l = m; else { htab[m].acc_cnt++; return(htab+m); }
  1714. X    }
  1715. X
  1716. X    if(htab[m].inet_num < inet_num) m++;  /* locate first entry that is > */
  1717. X
  1718. X    if((hcnt+1) > htot)            /* need more space */
  1719. X    {
  1720. X    htot += HALLOC_SIZE;        /* add HALLOC_SIZE entries at a time */
  1721. X
  1722. X    if(!(htab = (HTAB *) realloc(htab,sizeof(HTAB)*htot)))
  1723. X                    { perror("grow_htab realloc"); exit(1); }
  1724. X    }
  1725. X
  1726. X    for(i = hcnt-m, hs = htab+hcnt, hd=htab+hcnt+1; i--; *--hd = *--hs);
  1727. X
  1728. X    htab[m]=hzero;
  1729. X    htab[m].inet_num = inet_num;
  1730. X    htab[m].last_key = get_next_key()  ;
  1731. X    htab[m].next_key = get_next_key()+1;
  1732. X    hcnt++;
  1733. X    return(htab+m);
  1734. X}
  1735. X
  1736. X/****************************************************************************
  1737. X* Write out the client table in the .HTAB_DUMP file.
  1738. X****************************************************************************/
  1739. X
  1740. Xdump_htab()
  1741. X{
  1742. X    int i;
  1743. X    FILE *fp;
  1744. X    HTAB *hp;
  1745. X
  1746. X    if(!(fp = fopen(".HTAB_DUMP","w"))) return;
  1747. X
  1748. X    for(i = hcnt-2, hp = htab+1; i--; hp++)
  1749. X    {
  1750. X    fprintf(fp,"%d.%d.%d.%d\t%5d %c %s",
  1751. X                ((unsigned char *)(&hp->inet_num))[0],
  1752. X                ((unsigned char *)(&hp->inet_num))[1],
  1753. X                ((unsigned char *)(&hp->inet_num))[2],
  1754. X                ((unsigned char *)(&hp->inet_num))[3],
  1755. X                hp->acc_cnt,
  1756. X                (hp->inhibit) ? '*' : ((hp->active) ? '+' : ' '),
  1757. X                ctime((time_t *) &(hp->last_acc)));
  1758. X    }
  1759. X
  1760. X    fclose(fp);
  1761. X}
  1762. X
  1763. X/****************************************************************************
  1764. X* Client database initialization routine.  Reads in .ROGUE_HOSTS.
  1765. X****************************************************************************/
  1766. X
  1767. Xinit_htab()        /* always have 2 entries -- 0, MAXINT */
  1768. X{
  1769. X    FILE *fp;
  1770. X    HTAB    *hp;
  1771. X    char  buf[1024];
  1772. X    unsigned int i1,i2,i3,i4;
  1773. X    unsigned long hnum;
  1774. X
  1775. X    if(!(htab = (HTAB *) malloc(sizeof(HTAB)*HALLOC_SIZE)))
  1776. X                { perror("grow_htab malloc"); exit(1); }
  1777. X    htab[0] = hzero;
  1778. X    htab[1] = hzero;
  1779. X    htab[1].inet_num = ~0;
  1780. X    hcnt = 2;
  1781. X    htot = HALLOC_SIZE;
  1782. X
  1783. X    if(fp = fopen(".ROGUE_HOSTS","r"))
  1784. X    {
  1785. X    while(fgets(buf,sizeof(buf),fp))
  1786. X    {
  1787. X        if(*buf < '0' || *buf > '9') continue;
  1788. X
  1789. X        sscanf(buf,"%d.%d.%d.%d",&i1,&i2,&i3,&i4);
  1790. X        ((unsigned char *) (&hnum))[0] = i1;
  1791. X        ((unsigned char *) (&hnum))[1] = i2;
  1792. X        ((unsigned char *) (&hnum))[2] = i3;
  1793. X        ((unsigned char *) (&hnum))[3] = i4;
  1794. X        hp = find_host(hnum);
  1795. X        hp->inhibit = 1;
  1796. X    }
  1797. X    fclose(fp);
  1798. X    }
  1799. X}
  1800. END_OF_FILE
  1801.   if test 4144 -ne `wc -c <'server_host.c'`; then
  1802.     echo shar: \"'server_host.c'\" unpacked with wrong size!
  1803.   fi
  1804.   # end of 'server_host.c'
  1805. fi
  1806. if test -f 'server_main.c' -a "${1}" != "-c" ; then 
  1807.   echo shar: Will not clobber existing file \"'server_main.c'\"
  1808. else
  1809.   echo shar: Extracting \"'server_main.c'\" \(6467 characters\)
  1810.   sed "s/^X//" >'server_main.c' <<'END_OF_FILE'
  1811. X    /*********************************************************************\
  1812. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1813. X    *                                                                     *
  1814. X    *  You may copy or modify this file in any manner you wish, provided  *
  1815. X    *  that this notice is always included, and that you hold the author  *
  1816. X    *  harmless for any loss or damage resulting from the installation or *
  1817. X    *  use of this software.                                              *
  1818. X    \*********************************************************************/
  1819. X
  1820. X#include "server_def.h"
  1821. X
  1822. X#define ERR(S) { send_error(from,ub,S); return; }
  1823. X
  1824. Xint max_nlen   = FILE_NAME_LIMIT;
  1825. Xint inetd_mode =               0;
  1826. Xint dbug       =               0;
  1827. Xint   udp_port =    DEF_FSP_PORT;
  1828. Xchar *home_dir =    DEF_FSP_HOME;
  1829. Xchar *run_uid  =               0;
  1830. X
  1831. Xint always_use_cache_dir = ALWAYS_USE_CACHE_DIR;
  1832. Xint dir_cache_limit      = MAX_DIR_CACHE_COUNT;
  1833. Xchar *dir_cache_dir      = DEF_DIRECTORY_CACHE;
  1834. X
  1835. X/****************************************************************************
  1836. X*  This is the dispatch loop for message that has been accepted.
  1837. X*    bytes: size of the message received.
  1838. X*       ub: pointer to the message buffer.
  1839. X*      old: true if this message contains old sequence number (retransmit).
  1840. X*       hp: pointer to the entry for the client host who sent this message.
  1841. X*     from: pointer to the socket address structure of the client host.
  1842. X****************************************************************************/
  1843. X
  1844. Xserver_get_packet(bytes,ub,old,hp,from)
  1845. X    int   bytes,old;
  1846. X    UBUF *ub;
  1847. X    HTAB *hp;
  1848. X    struct sockaddr_in *from;
  1849. X{
  1850. X    unsigned long  inet_num;
  1851. X    unsigned short port_num;
  1852. X    unsigned l1, l2;
  1853. X    char *s1, *s2, *pe;
  1854. X    FILE *fp;
  1855. X    PPATH pp;
  1856. X
  1857. X    l1 = ub->len;
  1858. X    l2 = bytes - l1 - UBUF_HSIZE;
  1859. X    s1 = ub->buf;
  1860. X    s2 = ub->buf + l1;
  1861. X
  1862. X    if(dbug) fprintf(stderr,"rcv (%c,%d,%d,%lu) <--- %d.%d.%d.%d\n",
  1863. X        ub->cmd, l1, l2, ub->pos,
  1864. X        ((unsigned char *)(&hp->inet_num))[0],
  1865. X        ((unsigned char *)(&hp->inet_num))[1],
  1866. X        ((unsigned char *)(&hp->inet_num))[2],
  1867. X        ((unsigned char *)(&hp->inet_num))[3]);
  1868. X
  1869. X    if(!old) { hp->last_key = hp->next_key;
  1870. X           hp->next_key = get_next_key() + ((hp->last_key+1) & 0x00ff); }
  1871. X
  1872. X    ub->key  = hp->next_key;
  1873. X    inet_num = hp->inet_num;
  1874. X    port_num = from->sin_port;
  1875. X
  1876. X    switch(ub->cmd)
  1877. X    {
  1878. X      case CC_VERSION : { ERR(VERSION_STR); }
  1879. X
  1880. X      case CC_BYE     : { if(!old) hp->active = 0;
  1881. X              server_reply(from,ub,0,0);
  1882. X              return; }
  1883. X            
  1884. X      case CC_GET_DIR : { if((pe = check_path(s1,l1,&pp)) ||
  1885. X                 (pe = server_get_dir(&pp,&fp))) ERR(pe);
  1886. X              send_file(from,ub,fp,l2,s2);
  1887. X              fclose(fp);
  1888. X              return; }
  1889. X
  1890. X      case CC_GET_FILE: { if((pe = check_path(s1,l1,&pp)) ||
  1891. X                     (pe = server_get_file(&pp,&fp))) ERR(pe);
  1892. X              send_file(from,ub,fp,l2,s2);
  1893. X              fclose(fp);
  1894. X              return; }
  1895. X
  1896. X      case CC_DEL_FILE: { if(!old)
  1897. X                if((pe = check_path(s1,l1,&pp)) ||
  1898. X                   (pe = server_del_file(&pp,inet_num))) ERR(pe);
  1899. X              server_reply(from,ub,0,0);
  1900. X              return; }
  1901. X
  1902. X      case CC_DEL_DIR : { if(!old)
  1903. X                if((pe = check_path(s1,l1,&pp)) ||
  1904. X                   (pe = server_del_dir(&pp,inet_num))) ERR(pe);
  1905. X              server_reply(from,ub,0,0);
  1906. X              return; }
  1907. X
  1908. X      case CC_UP_LOAD : { if(!old)
  1909. X                if(pe = server_up_load(s1,l1,ub->pos,
  1910. X                           inet_num,port_num)) ERR(pe);
  1911. X              server_reply(from,ub,0,0);
  1912. X              return; }
  1913. X
  1914. X      case CC_INSTALL : { if(!old)
  1915. X                if((pe = check_path(s1,l1,&pp)) ||
  1916. X                   (pe = server_install(&pp,inet_num,port_num)))
  1917. X                                       ERR(pe);
  1918. X              server_reply(from,ub,0,0);
  1919. X              return; }
  1920. X
  1921. X      case CC_MAKE_DIR: { if(!old)
  1922. X                if((pe = check_path(s1,l1,&pp)) ||
  1923. X                   (pe = server_make_dir(&pp,inet_num))) ERR(pe);
  1924. X              if(pe = server_get_pro(&pp,s1,inet_num)) ERR(pe);
  1925. X              server_reply(from,ub,strlen(ub->buf)+1,0);
  1926. X              return; }
  1927. X
  1928. X      case CC_GET_PRO : { if((pe = check_path(s1,l1,&pp)) ||
  1929. X                 (pe = server_get_pro(&pp,s1,inet_num))) ERR(pe);
  1930. X              server_reply(from,ub,strlen(ub->buf)+1,0);
  1931. X              return; }
  1932. X
  1933. X      case CC_SET_PRO : { if(!old)
  1934. X                if((pe = check_path(s1,l1,&pp)) ||
  1935. X                   (pe = server_set_pro(&pp,s2,inet_num))) ERR(pe);
  1936. X              if(pe = server_get_pro(&pp,s1,inet_num)) ERR(pe);
  1937. X              server_reply(from,ub,strlen(ub->buf)+1,0);
  1938. X              return; }
  1939. X
  1940. X      case CC_GRAB_FILE: { if(pe = check_path(s1,l1,&pp)) ERR(pe);
  1941. X               if(!old && !ub->pos)
  1942. X                 if(pe = server_secure_file(&pp,inet_num,port_num))
  1943. X                                       ERR(pe);
  1944. X               if(pe = server_grab_file(&pp,&fp,inet_num,port_num))
  1945. X                                       ERR(pe);
  1946. X               send_file(from,ub,fp,l2,s2);
  1947. X               fclose(fp);
  1948. X               return; }
  1949. X
  1950. X      case CC_GRAB_DONE: { if(pe = check_path(s1,l1,&pp)) ERR(pe);
  1951. X               if(!old)
  1952. X                 if(pe = server_grab_done(&pp,inet_num,port_num))
  1953. X                                       ERR(pe);
  1954. X               server_reply(from,ub,0,0);
  1955. X               return; }
  1956. X
  1957. X    }
  1958. X}
  1959. X
  1960. Xarg_err()
  1961. X{
  1962. X    fputs("arg: -h absolute_path    set home directory.\n",stderr);
  1963. X    fputs("     -p udp_port_number  set port number.\n",stderr);
  1964. X    fputs("     -u uid_number       assume this uid after startup.\n",stderr);
  1965. X    fputs("     -d                  turn on debug mode.\n",stderr);
  1966. X    exit(1);
  1967. X}
  1968. X
  1969. Xmain(argc,argv)
  1970. X    int argc;
  1971. X    char **argv;
  1972. X{
  1973. X    int t;
  1974. X
  1975. X    inetd_mode = !strcmp(argv[0],"in.fspd");
  1976. X
  1977. X    if(inetd_mode)
  1978. X    {
  1979. X    init_inetd();
  1980. X    freopen("/dev/null","r",stdin);
  1981. X    freopen("/dev/null","w",stdout);
  1982. X    freopen("/dev/null","w",stderr);
  1983. X    }
  1984. X
  1985. X    for(t = 1; t < argc; t++)
  1986. X    {
  1987. X    if(argv[t][0] == '-') switch(argv[t][1])
  1988. X    {
  1989. X        case 'd':    dbug++; break;
  1990. X
  1991. X        case 'h':    if(argv[t][2]) home_dir = argv[t]+2; else
  1992. X            if(argv[t+1] ) home_dir = argv[++t]; else
  1993. X                                arg_err();
  1994. X            break;
  1995. X
  1996. X        case 'u':    if(argv[t][2]) run_uid = argv[t]+2; else
  1997. X            if(argv[t+1] ) run_uid = argv[++t]; else
  1998. X                                arg_err();
  1999. X            break;
  2000. X
  2001. X        case 'p':    if(argv[t][2]) udp_port = atoi(argv[t]+2); else
  2002. X            if(argv[t+1] ) udp_port = atoi(argv[++t]); else
  2003. X                                arg_err();
  2004. X            break;
  2005. X
  2006. X        default : arg_err();
  2007. X
  2008. X    } else arg_err();
  2009. X    }
  2010. X
  2011. X    if(!inetd_mode)
  2012. X    {
  2013. X    init_network(udp_port);
  2014. X    if(!dbug) { freopen("/dev/null","r",stdin);
  2015. X            freopen("/dev/null","w",stdout);
  2016. X            freopen("/dev/null","w",stderr); }
  2017. X    }
  2018. X
  2019. X    if(run_uid) if(setuid(atoi(run_uid)) != 0) exit(1);
  2020. X    init_home_dir();
  2021. X    init_htab();
  2022. X
  2023. X    srandom(getpid());
  2024. X
  2025. X    if(inetd_mode) {          server_loop(120*1000L); }  /* 2 minutes */
  2026. X          else { while(1) server_loop(      -1L); }
  2027. X
  2028. X    exit(0);
  2029. X}
  2030. END_OF_FILE
  2031.   if test 6467 -ne `wc -c <'server_main.c'`; then
  2032.     echo shar: \"'server_main.c'\" unpacked with wrong size!
  2033.   fi
  2034.   # end of 'server_main.c'
  2035. fi
  2036. if test -f 'udp_io.c' -a "${1}" != "-c" ; then 
  2037.   echo shar: Will not clobber existing file \"'udp_io.c'\"
  2038. else
  2039.   echo shar: Extracting \"'udp_io.c'\" \(4025 characters\)
  2040.   sed "s/^X//" >'udp_io.c' <<'END_OF_FILE'
  2041. X    /*********************************************************************\
  2042. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  2043. X    *                                                                     *
  2044. X    *  You may copy or modify this file in any manner you wish, provided  *
  2045. X    *  that this notice is always included, and that you hold the author  *
  2046. X    *  harmless for any loss or damage resulting from the installation or *
  2047. X    *  use of this software.                                              *
  2048. X    \*********************************************************************/
  2049. X
  2050. X#include "common_def.h"
  2051. X
  2052. Xstatic struct sockaddr_in INET_ZERO = { AF_INET };
  2053. X
  2054. Xextern int errno;
  2055. X#define DSIZE (sizeof(int)*8)
  2056. X#define SAVE(A) { int sav; sav = errno; A; errno = sav; }
  2057. X
  2058. X#ifndef EXOS_IPC
  2059. X
  2060. X#include <netdb.h>
  2061. X
  2062. Xextern unsigned long inet_addr();
  2063. X
  2064. X_x_udp(port)
  2065. X    int *port;
  2066. X{
  2067. X    int f, len, zz;
  2068. X    struct sockaddr_in me ;
  2069. X    struct sockaddr_in sin;
  2070. X
  2071. X    me = sin = INET_ZERO;
  2072. X
  2073. X    me.sin_port = htons((unsigned short) *port);
  2074. X    me.sin_family = AF_INET;
  2075. X    if((f=socket(AF_INET,SOCK_DGRAM,0)) == -1) return(-1);
  2076. X    if( setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz)) < 0 ||
  2077. X        bind(f,(struct sockaddr *) &me,(len = sizeof(me))) < 0 ||
  2078. X        getsockname(f,(char *)&sin,&len) < 0)
  2079. X                                { SAVE(((void) close(f))); return(-1); }
  2080. X    if(!*port) *port = ntohs((unsigned short) sin.sin_port); return(f);
  2081. X}      
  2082. X
  2083. X_x_adr(host,port,his)
  2084. X    struct sockaddr_in *his;
  2085. X    char *host;
  2086. X    int port;
  2087. X{
  2088. X    char myhost[128];
  2089. X    struct hostent *H;
  2090. X    int    i;
  2091. X    char *s, *d;
  2092. X    *his = INET_ZERO;
  2093. X    if(!host) (void) gethostname(host = myhost,sizeof(myhost));
  2094. X    if((his->sin_addr.s_addr = inet_addr(host)) != -1)
  2095. X    {   his->sin_family = AF_INET;
  2096. X    } else
  2097. X    if(H = gethostbyname(host))
  2098. X    {   for(s = (char *)H->h_addr, d = (char *)&his->sin_addr, i = H->h_length;
  2099. X                        i--; *d++ = *s++);
  2100. X        his->sin_family = H->h_addrtype;
  2101. X    } else return(-1);
  2102. X    his->sin_port = htons((unsigned short) port);
  2103. X    return(0);
  2104. X}
  2105. X
  2106. X_x_select(rf, tt)       /* tt is in unit of ms */
  2107. X    int *rf;
  2108. X    long tt;
  2109. X{
  2110. X    struct timeval timeout;
  2111. X    if(tt != -1)
  2112. X    {
  2113. X        timeout.tv_sec  =  tt / 1000;
  2114. X        timeout.tv_usec = (tt % 1000)*1000;
  2115. X        return(select(DSIZE, rf, (int *) 0, (int *) 0, &timeout));
  2116. X    }
  2117. X       
  2118. X    return(select(DSIZE, rf, (int *) 0, (int *) 0, (struct timeval *) 0));
  2119. X}
  2120. X#endif  /* not EXOS_IPC */
  2121. X
  2122. X#ifdef EXOS_IPC
  2123. X
  2124. Xextern long rhost();
  2125. X
  2126. X_x_udp(port)
  2127. X    int *port;
  2128. X{
  2129. X    struct sockaddr_in sin; int f;
  2130. X
  2131. X    sin = INET_ZERO;
  2132. X    sin.sin_family = AF_INET;
  2133. X    sin.sin_port   = htons((unsigned short) *port);
  2134. X    if((f = socket(SOCK_DGRAM, (struct sockproto *) 0, &sin, SO_REUSEADDR))
  2135. X                            == -1) return(-1);
  2136. X    sin = INET_ZERO;
  2137. X    if(socketaddr(f,&sin) == -1) { SAVE(((void) close(f))); return(-1); }
  2138. X    if(!*port) *port = ntohs((unsigned short) sin.sin_port); return(f);
  2139. X}
  2140. X
  2141. X_x_adr(host,port,his)
  2142. X    char *host;
  2143. X    int port;
  2144. X    struct sockaddr_in *his;
  2145. X{
  2146. X    char myhost[128];
  2147. X    int f;
  2148. X
  2149. X    *his = INET_ZERO;
  2150. X    if(!host) (void) gethostname(host = myhost,sizeof(myhost));
  2151. X
  2152. X    his->sin_family = AF_INET;
  2153. X    his->sin_port   = htons((unsigned short) port);
  2154. X
  2155. X    if((his->sin_addr.s_addr = rhost(&host)) == -1) return(-1);
  2156. X
  2157. X    return(0);
  2158. X}
  2159. X
  2160. X_x_select(readfds, tt)
  2161. X    int *readfds;
  2162. X    long tt;                /* Time to wait in miniseconds. */
  2163. X{
  2164. X    int  code;
  2165. X    long mask = *readfds;
  2166. X
  2167. X    if(tt & 0xc0000000) tt = 0x3fffffff;/* It does not like 0x7fffffff. */
  2168. X
  2169. X    code = select(DSIZE, &mask, (long *) 0, tt);
  2170. X
  2171. X    *readfds = mask;
  2172. X
  2173. X    return(code);
  2174. X}
  2175. X
  2176. Xrecvfrom(s, msg, len, flags, from, fromlen)
  2177. X    char *msg;
  2178. X    int s, len, flags, *fromlen;
  2179. X    struct sockaddr_in *from;
  2180. X{
  2181. X    return(receive(s,from,msg,len));
  2182. X}
  2183. X
  2184. Xsendto(s, msg, len, flags, to, tolen)
  2185. X    char *msg;
  2186. X    int s, len, flags, tolen;
  2187. X    struct sockaddr_in *to;
  2188. X{
  2189. X     to->sin_family = AF_INET;
  2190. X     return(send(s,to,msg,len));
  2191. X}
  2192. X
  2193. X#endif /* EXOS_IPC */
  2194. END_OF_FILE
  2195.   if test 4025 -ne `wc -c <'udp_io.c'`; then
  2196.     echo shar: \"'udp_io.c'\" unpacked with wrong size!
  2197.   fi
  2198.   # end of 'udp_io.c'
  2199. fi
  2200. echo shar: End of archive 3 \(of 4\).
  2201. cp /dev/null ark3isdone
  2202. MISSING=""
  2203. for I in 1 2 3 4 ; do
  2204.     if test ! -f ark${I}isdone ; then
  2205.     MISSING="${MISSING} ${I}"
  2206.     fi
  2207. done
  2208. if test "${MISSING}" = "" ; then
  2209.     echo You have unpacked all 4 archives.
  2210.     rm -f ark[1-9]isdone
  2211. else
  2212.     echo You still must unpack the following archives:
  2213.     echo "        " ${MISSING}
  2214. fi
  2215. exit 0
  2216. exit 0 # Just in case...
  2217.