home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-17 | 58.1 KB | 1,949 lines |
- Newsgroups: comp.sources.misc
- From: wen-king@vlsi.cs.caltech.edu (Wen-King Su)
- Subject: v34i076: fsp - Internet archive server and client software, Part02/04
- Message-ID: <1992Dec18.163934.11378@sparky.imd.sterling.com>
- X-Md4-Signature: 09ef8c343e26b31f2b4c05525e5007be
- Date: Fri, 18 Dec 1992 16:39:34 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: wen-king@vlsi.cs.caltech.edu (Wen-King Su)
- Posting-number: Volume 34, Issue 76
- Archive-name: fsp/part02
- Environment: UNIX, Sockets
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: ChangeLog bsd_src/ls.c bsd_src/random.c client_lock.c
- # client_util.c
- # Wrapped by kent@sparky on Fri Dec 18 10:21:24 1992
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 4)."'
- if test -f 'ChangeLog' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ChangeLog'\"
- else
- echo shar: Extracting \"'ChangeLog'\" \(12910 characters\)
- sed "s/^X//" >'ChangeLog' <<'END_OF_FILE'
- XVersion 1.0 -- Dec 91. Original source created.
- X
- XVersion 2.0 -- Dec 91. Added man pages. Server bug fix. In 1.0, files
- X in a directory that is protected from deletion can still
- X be written over. In 2.0, it is prohibited as well.
- X
- XVersion 2.1 -- Jan 1, 92.
- X
- X 1) The maximum length of a name in pre-2.1 server is
- X both limited by the 1k-byte udp packet size and, in
- X some cases more severely, by the OS it is running in.
- X On some systems, the OS imposes a limite of 14 chars.
- X For those systems, the server can now be made to hash
- X long names into short ones. The effect is transparent
- X to the clients except when two long names gets hashed
- X into the same value. In that case, they will refer
- X to the same file during downloading, and they will
- X displace each others during uploading.
- X
- X 2) Since directories, unlike files, have undisputable
- X ownership, removal of a directory owned by a client
- X should depends only on the ownership of the directory
- X itself, and not on that of its parent directory. In
- X pre-2.1 server, the client must have delete permission
- X to the parent directory before it is allowed to delete
- X the subdirectory. In 2.1, the permission is not needed.
- X
- XVersion 2.2 -- Feb 15, 92.
- X
- X 1) The fput and fgetcmd utilities will now accept a list of
- X files from its standward input. See their man pages for
- X this expanded usage. This is useful if you don't want
- X file names to show on 'ps' output.
- X
- X 2) The retransmit timer for client code has been changed
- X to use an adaptive algorithm. In pre-2.2 versions of
- X FSP, clients will retransmit if it has not received a
- X response from the server after a delay of 3 seconds.
- X In version-2.2, two separate delays are used. The
- X "busy" delay is used when waiting for a reply for the
- X first try and the second try. Any time a second try
- X is necessary, the delay is increased by 50%. Every
- X first try brings the delay 12.5% closer to the initial
- X delay setting (3 seconds by default, settable by the
- X FSP_DELAY variable). For the third try and beyond,
- X the "idle" delay is used. For each try, the delay is
- X doubled.
- X
- X 3) Makes available FSP request code space 0x80 - 0xff for
- X future user extensions. Each such extension will begin
- X with a code byte in that range, and followed by a control
- X block, which is likely to be different from the existing
- X one. The basic operations of FSP will not require the
- X use of such extensions.
- X
- X Note: 2.2 does not involve changes to the server itself.
- X The server is been checked out and added to by a
- X few people on the net. I will wait until the
- X modifications stabilize before I consolidate them.
- X
- XVersion 2.3 -- Mar 9, 92
- X
- X 1) The bsd_src/glob.c file has a bug in blkfree function
- X in that it tries to free something that is actually
- X on the stack of the glob function. The last call to
- X free has been commented out to fix the bug.
- X
- X 2) The fspd has a bug whoes only visible manifestation
- X is the that protection can't be changed. The fix has
- X required a moderate amount of code change in fspd.
- X
- X 3) .FSP_NO_DEL and .FSP_NO_ADD mechanism has been replaced
- X by .FSP_OK_DEL and .FSP_OK_ADD mechanism. Thus by
- X default, a directory is no delete and no add.
- X
- X 4) fprocmd is modified to relax option checking, allowing
- X arbitrary option characters be passed to the fsp server.
- X
- X 5) A fls bug is fixed so that a "fls /" in a directory other
- X than the root directory will not cause an error.
- X
- X 6) A -DDIRENT switch is added in Makefile to help support
- X those machines that does not have /usr/include/dirent.h.
- X
- XVersion 2.3a -- March 20, 1992
- X
- X 1) In a few places, non-critical errors of the form:
- X if(errno = EINTR) ....
- X was made. It obviously should have been == instead.
- X The problem is fixed.
- X
- X 2) In the previous versions there is a potential problem
- X such that if the first reply packet is dropped or is
- X messed up, making a retransmit necessary, fspd will
- X make the client utility wait for a 1 minute timeout.
- X A potential loop hole for this happening has been
- X closed by modifying server_lib.c where the packet key
- X is checked.
- X
- XVersion 2.4 -- March 27, 1992
- X
- X 1) fgrab/fgrabcmd client utility is added. It is like
- X fget except it also deletes the named files in such a
- X way that if there are multiple fgrabs for the same
- X file, only one will succeed. One bug/mis-feature of
- X fgrab is that when fgrab is terminated abnormally, the
- X file is not restored. This command is useful for things
- X like sharing bone files for modified versions of nethack.
- X
- X 2) FSP now allows multiple client programs to run at the
- X same time if one of the three multiplexing mechanisms
- X are chosen during compile time. It is likely that at
- X least one of them will work for your system. The
- X multiplexing is done at the client side, and does not
- X allow the client machine to issue request messages at
- X a higher rate compared to the previous versions. The
- X FSP_LOCALPORT variable is no longer needed. However,
- X if used, it will force serialization of client programs,
- X which might be desireable if none of the multiplexing
- X mechanisms are suitable for your machine. In order to
- X accommodate this change, the server code has been
- X changed to store temporary upload files with a different
- X name from the previous version. The names now have to
- X identify sender's port as well as sender's internet id.
- X Change is necessary to keep it under 14-character limit
- X of some OS.
- X
- X 3) Progress report mechanism enabled by FSP_TRACE variable
- X now try to update the kbyte display more promptly.
- X
- X 4) fcat/fcatcmd will now turn off FSP_TRACE during its
- X file transfer if its stdout is a tty.
- X
- XVersion 2.5 -- April 8, 1992
- X
- X 1) A bug introduced during the last release --- fspd will
- X not timeout and exit when running under inetd mode.
- X This bug is now fixed. It was introduced because it
- X is more convienent at one time for it not to exit when
- X it is still being debugged. The patch to stop it from
- X exiting was not removed before release time.
- X
- X 2) A very rarely seen bug in some OS is circumvented. UDP
- X packet's headers contain a checksum field. If the
- X checksum option is disabled, the OS will set the
- X checksum field to 0 before sending, and will not check
- X the checksum field when message is received. If the
- X option is enabled, the OS will stuff the checksum into
- X the checksum field. When a packet is received, the
- X checksum field is checked. If the checksum field is 0,
- X then the OS assume that the sender does not have option
- X enabled, and therefore the checking is skipped.
- X
- X Problem arises when a packet's computed checksum is
- X zero. Some OS will stuff 0xffff into the checksum
- X field before sending such a message to distinguish it
- X from the case for which checksum is disabled. Other
- X OS couldn't recognize 0xffff as an indication that the
- X actual checksum could be either 0 or 0xffff, and
- X subsequently reject the message. The client can thus
- X get stuck forever in retransmitting a request that
- X happens to have 0 for the computed checksum, but
- X 0xffff for the checksum field.
- X
- X To get around the problem, the sequence number field
- X of the request message (which has meaning only to the
- X client software), is partitioned such that 2 of the
- X bits reflect the retry sequence, and the remaining 14
- X bits reflect the request sequence. This will ensure
- X that if one request got ignored because it happens to
- X have a checksum of 0, the next retry will result in
- X a packet that does not have a checksum of 0. The only
- X file affected here is client_lib.c.
- X
- X 3) In response to those who have severely limited UDP
- X packet sizes, the environment variable FSP_BUF_SIZE
- X is supplied to set the data size of file and directory
- X information transfers. The default is 1024. You cannot
- X set it to be bigger than 1024, but you can set it to
- X be smaller if you find that your system cannot pass
- X UDP packets that includes 1024 bytes of data. This
- X requires changes both in the server and the client
- X code. The first parameter field of get-file and
- X get-directory requests contains the path of the file
- X or directory. The second parameter field was unused,
- X but it is now used to hold the number of bytes to read.
- X This change is backward compatible in the sense that
- X if the second field is empty (old client code), the
- X new server code will default to 1024. Changes to the
- X client code is confined to client_util.c.
- X
- XVersion 2.6 -- July 6, 1992
- X
- X 1) client_lock.c is fixed so that perror is always
- X followed by exit. Previously, if System-V shared
- X memory mechanism is chosen for locking control in
- X the Makefile, but the mechansim has not in fact
- X been configured into the UNIX kernel, the client
- X utilities would die of a segmentation fault error.
- X The error message will now be more reasonable.
- X
- X 2) mechanism is added so FSP server can put directory
- X cache files in a special directory other than the one
- X for which the files are intended. Previously a
- X .FSP_CONTENT file is created in each directory the
- X fspd process controls. Through variables in the
- X Makefile, provider of fsp service can now elect to put
- X cache files together in one single directory, and put
- X a cap on the total number of such files that can exist
- X simultaneously. The fsp server will create a cache
- X file in the cache directory when it couldn't find one
- X already exist in the directory being listed by the
- X client. Changed are minor and invovles the routines
- X server_get_dir, server_get_dir_2 [new] in "server_file.c";
- X the variable declaration section of "server_main.c", and
- X Makefile.
- X
- X 3) a line in util_cd is changed, and a line in get_dir_blk
- X is added in the file "client_util.c" to prevent fls from
- X sending some spurious requests to the fsp server.
- X
- X 4) Makefile is changed to allow the option of combining all
- X client utilities into one actual binary files. This is
- X necessary for space saving reasons on some versions of
- X UNIX. The various small main C files for the utilities
- X had to be changed as well to accomodate this change.
- X
- X 5) fver now will take an optional argument. If none is
- X supplied, it prints the version string of the server.
- X If one is supplied, it prints the versioin string of
- X the client FSP software.
- X
- XVersion 2.6.1 -- Aug 31, 1992
- X
- X 1) Small changes to Makefile. In 2.6, "make" will fail if
- X you needed to define LIB, or if your command shell is not
- X /bin/sh, and you want to merge client utilities. Version
- X 2.6.1 fixed them. Only Makefile is changed, everything
- X else is identical to 2.6.
- X
- XVersion 2.6.2 -- Sep 2, 1992
- X
- X 1) bsd_src/cmp.c was changed so that flscmd can sort its
- X output by date correctly on all systems. This particular
- X version of the BSD source made assumptions about what
- X the comparison functions should return for the qsort
- X routine, but those assumptions were not true for all
- X systems.
- X
- XVersion 2.6.3 -- Sep 19, 1992
- X
- X 1) client_lock.c is modified to fix a compilation phase
- X bug that occur when NOLOCKING option is used in the
- X Makefile. This affects only the client code.
- X
- X 2) server_file.c is modified so that upload uses the
- X directory cache directory instead of the top directory.
- X This is needed for those sites that want the top
- X directory be write protected. (good for ftp sites).
- X
- XVersion 2.6.4 -- Dec 12, 1992.
- X
- X 1) Make main makefile pass CC and CFLAGS definitions to
- X bsd_src's Makefile
- X
- X 2) Add util_cd2 to client_util and make bsd_src/ls.c use
- X it. This remove some of the spurious GET_DIR requests.
- X Also, there is a bug in client_util's util_cd routine
- X in that it always requests 1K worth of directory info
- X no matter what FSP_BUF_SIZE setting is used. Causeing
- X fsp clients to hang under situations where FSP_BUF_SIZE
- X is limited by the network (slip, usually).
- X
- X 3) function server_interrupt in server_lib.c was defined
- X to be of type void to avoid complaint from some compilers.
- X There are several other minor fixes in functin variable
- X declarations in several files for the same reason.
- X
- XWhat needs to be done EVENTUALLY
- X
- X Somebody should make a tar equivalent that read and write remote fsp
- X archives. This will allow transfer of whole directory in one command.
- X
- X Sources should be make to pass lint with as little problem as possible.
- END_OF_FILE
- if test 12910 -ne `wc -c <'ChangeLog'`; then
- echo shar: \"'ChangeLog'\" unpacked with wrong size!
- fi
- # end of 'ChangeLog'
- fi
- if test -f 'bsd_src/ls.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bsd_src/ls.c'\"
- else
- echo shar: Extracting \"'bsd_src/ls.c'\" \(10953 characters\)
- sed "s/^X//" >'bsd_src/ls.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1989 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Michael Fischbein.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that: (1) source distributions retain this entire copyright
- X * notice and comment, and (2) distributions including binaries display
- X * the following acknowledgement: ``This product includes software
- X * developed by the University of California, Berkeley and its contributors''
- X * in the documentation or other materials provided with the distribution
- X * and in all advertising materials mentioning features or use of this
- X * software. Neither the name of the University nor the names of its
- X * contributors may be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xchar copyright[] =
- X"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif /* not lint */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)ls.c 5.42 (Berkeley) 5/17/90";
- X#endif /* not lint */
- X
- X#include "../client_def.h"
- X#include <sys/ioctl.h>
- X#include <string.h>
- X#include "ls.h"
- X#include "tweak.h"
- X
- Xint (*sortfcn)(), (*printfcn)();
- Xchar *emalloc();
- X
- Xint termwidth = 80; /* default terminal width */
- X
- X/* flags */
- Xint f_accesstime; /* use time of last access */
- Xint f_column; /* columnated format */
- Xint f_group; /* show group ownership of a file */
- Xint f_ignorelink; /* indirect through symbolic link operands */
- Xint f_inode; /* print inode */
- Xint f_kblocks; /* print size in kilobytes */
- Xint f_listalldot; /* list . and .. as well */
- Xint f_listdir; /* list actual directory, not contents */
- Xint f_listdot; /* list files beginning with . */
- Xint f_longform; /* long listing format */
- Xint f_needstat; /* if need to stat files */
- Xint f_newline; /* if precede with newline */
- Xint f_nonprint; /* show unprintables as ? */
- Xint f_nosort; /* don't sort output */
- Xint f_recursive; /* ls subdirectories also */
- Xint f_reversesort; /* reverse whatever sort is used */
- Xint f_singlecol; /* use single column output */
- Xint f_size; /* list size in short listing */
- Xint f_statustime; /* use time of last mode change */
- Xint f_dirname; /* if precede with directory name */
- Xint f_timesort; /* sort by time vice name */
- Xint f_total; /* if precede with "total" line */
- Xint f_type; /* add type character for non-regular files */
- X
- Xfls_main(argc, argv)
- X int argc;
- X char **argv;
- X{
- X extern int optind;
- X int ch;
- X char *p, *getenv();
- X int acccmp(), modcmp(), namecmp(), prcopy(), printcol();
- X int printlong(), printscol(), revacccmp(), revmodcmp(), revnamecmp();
- X int revstatcmp(), statcmp();
- X
- X /* terminal defaults to -Cq, non-terminal defaults to -1 */
- X if (isatty(1)) {
- X f_nonprint = 1;
- X termwidth = 80;
- X#ifdef TIOCGWINSZ
- X { struct winsize win;
- X if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) {
- X if (p = getenv("COLUMNS"))
- X termwidth = atoi(p);
- X }
- X else
- X termwidth = win.ws_col;
- X }
- X#endif
- X f_column = 1;
- X } else
- X f_singlecol = 1;
- X
- X /* root is -A automatically */
- X if (!getuid())
- X f_listdot = 1;
- X
- X while ((ch = getopt(argc, argv, "1ACFLRacdfgiklqrstu")) != EOF) {
- X switch (ch) {
- X /*
- X * -1, -C and -l all override each other
- X * so shell aliasing works right
- X */
- X case '1':
- X f_singlecol = 1;
- X f_column = f_longform = 0;
- X break;
- X case 'C':
- X f_column = 1;
- X f_longform = f_singlecol = 0;
- X break;
- X case 'l':
- X f_longform = 1;
- X f_column = f_singlecol = 0;
- X break;
- X /* -c and -u override each other */
- X case 'c':
- X f_statustime = 1;
- X f_accesstime = 0;
- X break;
- X case 'u':
- X f_accesstime = 1;
- X f_statustime = 0;
- X break;
- X case 'F':
- X f_type = 1;
- X break;
- X case 'L':
- X f_ignorelink = 1;
- X break;
- X case 'R':
- X f_recursive = 1;
- X break;
- X case 'a':
- X f_listalldot = 1;
- X /* FALLTHROUGH */
- X case 'A':
- X f_listdot = 1;
- X break;
- X case 'd':
- X f_listdir = 1;
- X break;
- X case 'f':
- X f_nosort = 1;
- X break;
- X case 'g':
- X f_group = 1;
- X break;
- X case 'i':
- X f_inode = 1;
- X break;
- X case 'k':
- X f_kblocks = 1;
- X break;
- X case 'q':
- X f_nonprint = 1;
- X break;
- X case 'r':
- X f_reversesort = 1;
- X break;
- X case 's':
- X f_size = 1;
- X break;
- X case 't':
- X f_timesort = 1;
- X break;
- X default:
- X case '?':
- X usage();
- X }
- X }
- X argc -= optind;
- X argv += optind;
- X
- X /* -d turns off -R */
- X if (f_listdir)
- X f_recursive = 0;
- X
- X /* if need to stat files */
- X f_needstat = f_longform || f_recursive || f_timesort ||
- X f_size || f_type;
- X
- X /* select a sort function */
- X if (f_reversesort) {
- X if (!f_timesort)
- X sortfcn = revnamecmp;
- X else if (f_accesstime)
- X sortfcn = revacccmp;
- X else if (f_statustime)
- X sortfcn = revstatcmp;
- X else /* use modification time */
- X sortfcn = revmodcmp;
- X } else {
- X if (!f_timesort)
- X sortfcn = namecmp;
- X else if (f_accesstime)
- X sortfcn = acccmp;
- X else if (f_statustime)
- X sortfcn = statcmp;
- X else /* use modification time */
- X sortfcn = modcmp;
- X }
- X
- X /* select a print function */
- X if (f_singlecol)
- X printfcn = printscol;
- X else if (f_longform)
- X printfcn = printlong;
- X else
- X printfcn = printcol;
- X
- X if (!argc) {
- X argc = 1;
- X argv[0] = ".";
- X argv[1] = NULL;
- X }
- X doargs(argc, argv);
- X}
- X
- Xstatic char path[2*1024 + 1];
- Xstatic char *endofpath = path;
- X
- Xdoargs(argc, argv)
- X int argc;
- X char **argv;
- X{
- X register LS *dstatp, *rstatp;
- X register int cnt, dircnt, dirmax, maxlen, regcnt, regmax;
- X LS *dstats, *rstats;
- X struct stat sb;
- X char top[2*1024 + 1], **av, *av2[2];
- X unsigned long blocks;
- X extern char **glob();
- X
- X /*
- X * walk through the operands, building separate arrays of LS
- X * structures for directory and non-directory files.
- X */
- X dstats = rstats = NULL;
- X dirmax = regmax = 0;
- X
- X for (dircnt = regcnt = 0; *argv; ++argv)
- X {
- X if(!(av = glob(*argv))) { av = av2; av2[0] = *argv; av2[1] = 0; }
- X
- X for( ; *av; av++)
- X {
- X if (util_stat(*av, &sb)) {
- X perror(*av);
- X if (errno == ENOENT)
- X continue;
- X ls_bad(1);
- X }
- X if ((S_IFDIR & sb.st_mode) && !f_listdir) {
- X if(dirmax == dircnt)
- X {
- X dirmax += 10;
- X if (!dstats)
- X {
- X dstatp = dstats = (LS *)emalloc(dirmax *
- X (sizeof(LS)));
- X } else
- X {
- X dstats = (LS *)realloc(dstats,
- X dirmax * (sizeof(LS)));
- X dstatp = dstats + dircnt;
- X }
- X }
- X dstatp->name = *av;
- X dstatp->lstat = sb;
- X ++dstatp;
- X ++dircnt;
- X }
- X else {
- X if(regmax == regcnt)
- X {
- X regmax += 10;
- X
- X if (!rstats)
- X {
- X blocks = 0;
- X maxlen = -1;
- X rstatp = rstats = (LS *)emalloc(regmax *
- X (sizeof(LS)));
- X } else
- X {
- X rstats = (LS *)realloc(rstats,
- X regmax * (sizeof(LS)));
- X rstatp = rstats + regcnt;
- X }
- X }
- X rstatp->name = *av;
- X rstatp->lstat = sb;
- X
- X /* save name length for -C format */
- X rstatp->len = strlen(*av);
- X
- X if (f_nonprint)
- X prcopy(*av, *av, rstatp->len);
- X
- X /* calculate number of blocks if -l/-s formats */
- X if (f_longform || f_size)
- X blocks += (sb.st_size + 1023)/1024;
- X
- X /* save max length if -C format */
- X if (f_column && maxlen < rstatp->len)
- X maxlen = rstatp->len;
- X
- X ++rstatp;
- X ++regcnt;
- X }
- X }
- X }
- X /* display regular files */
- X if (regcnt) {
- X rstats[0].lstat.st_btotal = blocks;
- X rstats[0].lstat.st_maxlen = maxlen;
- X displaydir(rstats, regcnt);
- X f_newline = f_dirname = 1;
- X }
- X /* display directories */
- X if (dircnt) {
- X register char *p;
- X
- X f_total = 1;
- X if (dircnt > 1) {
- X (void)util_getwd(top);
- X qsort((char *)dstats, dircnt, sizeof(LS), sortfcn);
- X f_dirname = 1;
- X }
- X for (cnt = 0; cnt < dircnt; ++dstats) {
- X for (endofpath = path, p = dstats->name;
- X *endofpath = *p++; ++endofpath);
- X subdir(dstats);
- X f_newline = 1;
- X if (++cnt < dircnt && util_cd2(top)) {
- X perror(top);
- X ls_bad(1);
- X }
- X }
- X }
- X}
- X
- Xdisplaydir(stats, num)
- X LS *stats;
- X register int num;
- X{
- X register char *p, *savedpath;
- X LS *lp;
- X
- X if (num > 1 && !f_nosort) {
- X unsigned long save1, save2;
- X
- X save1 = stats[0].lstat.st_btotal;
- X save2 = stats[0].lstat.st_maxlen;
- X qsort((char *)stats, num, sizeof(LS), sortfcn);
- X stats[0].lstat.st_btotal = save1;
- X stats[0].lstat.st_maxlen = save2;
- X }
- X
- X printfcn(stats, num);
- X
- X if (f_recursive) {
- X savedpath = endofpath;
- X for (lp = stats; num--; ++lp) {
- X if (!(S_IFDIR & lp->lstat.st_mode))
- X continue;
- X p = lp->name;
- X if (p[0] == '.' && (!p[1] || p[1] == '.' && !p[2]))
- X continue;
- X if (endofpath != path && endofpath[-1] != '/')
- X *endofpath++ = '/';
- X for (; *endofpath = *p++; ++endofpath);
- X f_newline = f_dirname = f_total = 1;
- X subdir(lp);
- X *(endofpath = savedpath) = '\0';
- X }
- X }
- X}
- X
- Xsubdir(lp)
- X LS *lp;
- X{
- X LS *stats;
- X int num;
- X
- X if (f_newline)
- X (void)putchar('\n');
- X if (f_dirname)
- X (void)printf("%s:\n", path);
- X
- X if (util_cd2(lp->name)) {
- X perror(lp->name);
- X return;
- X }
- X if (num = tabdir(lp, &stats)) {
- X displaydir(stats, num);
- X (void)free((char *)stats);
- X }
- X if (util_cd2("..")) {
- X perror("..");
- X ls_bad(1);
- X }
- X}
- X
- Xtabdir(lp, s_stats)
- X LS *lp, **s_stats;
- X{
- X register RDIR *dirp;
- X register int cnt, maxentry, maxlen;
- X register char *p;
- X struct rdirent *dp;
- X unsigned long blocks;
- X LS *stats;
- X
- X if (!(dirp = util_opendir("."))) {
- X perror(lp->name);
- X return(0);
- X }
- X blocks = maxentry = maxlen = 0;
- X stats = NULL;
- X for (cnt = 0; dp = util_readdir(dirp);) {
- X /* this does -A and -a */
- X p = dp->d_name;
- X if (p[0] == '.') {
- X if (!f_listdot)
- X continue;
- X if (!f_listalldot && (!p[1] || p[1] == '.' && !p[2]))
- X continue;
- X }
- X if (cnt == maxentry) {
- X#define DEFNUM 256
- X maxentry += DEFNUM;
- X if(stats)
- X {
- X if (!(*s_stats = stats = (LS *)realloc((char *)stats,
- X (unsigned int)maxentry * sizeof(LS))))
- X nomem();
- X } else
- X {
- X if (!(*s_stats = stats = (LS *)malloc(
- X (unsigned int)maxentry * sizeof(LS))))
- X nomem();
- X }
- X }
- X if (f_needstat && util_stat(dp->d_name, &stats[cnt].lstat)) {
- X /*
- X * don't exit -- this could be an NFS mount that has
- X * gone away. Flush stdout so the messages line up.
- X */
- X (void)fflush(stdout);
- X perror(dp->d_name);
- X continue;
- X }
- X stats[cnt].name = dp->d_name;
- X
- X /*
- X * get the inode from the directory, so the -f flag
- X * works right.
- X */
- X stats[cnt].lstat.st_ino = dp->d_ino;
- X
- X /* save name length for -C format */
- X stats[cnt].len = dp->d_namlen;
- X
- X /* calculate number of blocks if -l/-s formats */
- X if (f_longform || f_size)
- X blocks += (stats[cnt].lstat.st_size + 1023)/1024;
- X
- X /* save max length if -C format */
- X if (f_column && maxlen < (int)dp->d_namlen)
- X maxlen = dp->d_namlen;
- X ++cnt;
- X }
- X (void)util_closedir(dirp);
- X
- X if (cnt) {
- X stats[0].lstat.st_btotal = blocks;
- X stats[0].lstat.st_maxlen = maxlen;
- X } else if (stats) {
- X (void)free((char *)stats);
- X }
- X return(cnt);
- X}
- END_OF_FILE
- if test 10953 -ne `wc -c <'bsd_src/ls.c'`; then
- echo shar: \"'bsd_src/ls.c'\" unpacked with wrong size!
- fi
- # end of 'bsd_src/ls.c'
- fi
- if test -f 'bsd_src/random.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bsd_src/random.c'\"
- else
- echo shar: Extracting \"'bsd_src/random.c'\" \(12955 characters\)
- sed "s/^X//" >'bsd_src/random.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1983 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that: (1) source distributions retain this entire copyright
- X * notice and comment, and (2) distributions including binaries display
- X * the following acknowledgement: ``This product includes software
- X * developed by the University of California, Berkeley and its contributors''
- X * in the documentation or other materials provided with the distribution
- X * and in all advertising materials mentioning features or use of this
- X * software. Neither the name of the University nor the names of its
- X * contributors may be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#if defined(LIBC_SCCS) && !defined(lint)
- Xstatic char sccsid[] = "@(#)random.c 5.7 (Berkeley) 6/1/90";
- X#endif /* LIBC_SCCS and not lint */
- X
- X#include <stdio.h>
- X
- X/*
- X * random.c:
- X * An improved random number generation package. In addition to the standard
- X * rand()/srand() like interface, this package also has a special state info
- X * interface. The initstate() routine is called with a seed, an array of
- X * bytes, and a count of how many bytes are being passed in; this array is then
- X * initialized to contain information for random number generation with that
- X * much state information. Good sizes for the amount of state information are
- X * 32, 64, 128, and 256 bytes. The state can be switched by calling the
- X * setstate() routine with the same array as was initiallized with initstate().
- X * By default, the package runs with 128 bytes of state information and
- X * generates far better random numbers than a linear congruential generator.
- X * If the amount of state information is less than 32 bytes, a simple linear
- X * congruential R.N.G. is used.
- X * Internally, the state information is treated as an array of longs; the
- X * zeroeth element of the array is the type of R.N.G. being used (small
- X * integer); the remainder of the array is the state information for the
- X * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
- X * state information, which will allow a degree seven polynomial. (Note: the
- X * zeroeth word of state information also has some other information stored
- X * in it -- see setstate() for details).
- X * The random number generation technique is a linear feedback shift register
- X * approach, employing trinomials (since there are fewer terms to sum up that
- X * way). In this approach, the least significant bit of all the numbers in
- X * the state table will act as a linear feedback shift register, and will have
- X * period 2^deg - 1 (where deg is the degree of the polynomial being used,
- X * assuming that the polynomial is irreducible and primitive). The higher
- X * order bits will have longer periods, since their values are also influenced
- X * by pseudo-random carries out of the lower bits. The total period of the
- X * generator is approximately deg*(2**deg - 1); thus doubling the amount of
- X * state information has a vast influence on the period of the generator.
- X * Note: the deg*(2**deg - 1) is an approximation only good for large deg,
- X * when the period of the shift register is the dominant factor. With deg
- X * equal to seven, the period is actually much longer than the 7*(2**7 - 1)
- X * predicted by this formula.
- X */
- X
- X
- X
- X/*
- X * For each of the currently supported random number generators, we have a
- X * break value on the amount of state information (you need at least this
- X * many bytes of state info to support this random number generator), a degree
- X * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
- X * the separation between the two lower order coefficients of the trinomial.
- X */
- X
- X#define TYPE_0 0 /* linear congruential */
- X#define BREAK_0 8
- X#define DEG_0 0
- X#define SEP_0 0
- X
- X#define TYPE_1 1 /* x**7 + x**3 + 1 */
- X#define BREAK_1 32
- X#define DEG_1 7
- X#define SEP_1 3
- X
- X#define TYPE_2 2 /* x**15 + x + 1 */
- X#define BREAK_2 64
- X#define DEG_2 15
- X#define SEP_2 1
- X
- X#define TYPE_3 3 /* x**31 + x**3 + 1 */
- X#define BREAK_3 128
- X#define DEG_3 31
- X#define SEP_3 3
- X
- X#define TYPE_4 4 /* x**63 + x + 1 */
- X#define BREAK_4 256
- X#define DEG_4 63
- X#define SEP_4 1
- X
- X
- X/*
- X * Array versions of the above information to make code run faster -- relies
- X * on fact that TYPE_i == i.
- X */
- X
- X#define MAX_TYPES 5 /* max number of types above */
- X
- Xstatic int degrees[ MAX_TYPES ] = { DEG_0, DEG_1, DEG_2,
- X DEG_3, DEG_4 };
- X
- Xstatic int seps[ MAX_TYPES ] = { SEP_0, SEP_1, SEP_2,
- X SEP_3, SEP_4 };
- X
- X
- X
- X/*
- X * Initially, everything is set up as if from :
- X * initstate( 1, &randtbl, 128 );
- X * Note that this initialization takes advantage of the fact that srandom()
- X * advances the front and rear pointers 10*rand_deg times, and hence the
- X * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
- X * element of the state information, which contains info about the current
- X * position of the rear pointer is just
- X * MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3.
- X */
- X
- Xstatic long randtbl[ DEG_3 + 1 ] = { TYPE_3,
- X 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
- X 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb,
- X 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
- X 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86,
- X 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7,
- X 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
- X 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b,
- X 0xf5ad9d0e, 0x8999220b, 0x27fb47b9 };
- X
- X/*
- X * fptr and rptr are two pointers into the state info, a front and a rear
- X * pointer. These two pointers are always rand_sep places aparts, as they cycle
- X * cyclically through the state information. (Yes, this does mean we could get
- X * away with just one pointer, but the code for random() is more efficient this
- X * way). The pointers are left positioned as they would be from the call
- X * initstate( 1, randtbl, 128 )
- X * (The position of the rear pointer, rptr, is really 0 (as explained above
- X * in the initialization of randtbl) because the state table pointer is set
- X * to point to randtbl[1] (as explained below).
- X */
- X
- Xstatic long *fptr = &randtbl[ SEP_3 + 1 ];
- Xstatic long *rptr = &randtbl[ 1 ];
- X
- X
- X
- X/*
- X * The following things are the pointer to the state information table,
- X * the type of the current generator, the degree of the current polynomial
- X * being used, and the separation between the two pointers.
- X * Note that for efficiency of random(), we remember the first location of
- X * the state information, not the zeroeth. Hence it is valid to access
- X * state[-1], which is used to store the type of the R.N.G.
- X * Also, we remember the last location, since this is more efficient than
- X * indexing every time to find the address of the last element to see if
- X * the front and rear pointers have wrapped.
- X */
- X
- Xstatic long *state = &randtbl[ 1 ];
- X
- Xstatic int rand_type = TYPE_3;
- Xstatic int rand_deg = DEG_3;
- Xstatic int rand_sep = SEP_3;
- X
- Xstatic long *end_ptr = &randtbl[ DEG_3 + 1 ];
- X
- X
- X
- X/*
- X * srandom:
- X * Initialize the random number generator based on the given seed. If the
- X * type is the trivial no-state-information type, just remember the seed.
- X * Otherwise, initializes state[] based on the given "seed" via a linear
- X * congruential generator. Then, the pointers are set to known locations
- X * that are exactly rand_sep places apart. Lastly, it cycles the state
- X * information a given number of times to get rid of any initial dependencies
- X * introduced by the L.C.R.N.G.
- X * Note that the initialization of randtbl[] for default usage relies on
- X * values produced by this routine.
- X */
- X
- Xsrandom( x )
- X
- X unsigned x;
- X{
- X register int i, j;
- X long random();
- X
- X if( rand_type == TYPE_0 ) {
- X state[ 0 ] = x;
- X }
- X else {
- X j = 1;
- X state[ 0 ] = x;
- X for( i = 1; i < rand_deg; i++ ) {
- X state[i] = 1103515245*state[i - 1] + 12345;
- X }
- X fptr = &state[ rand_sep ];
- X rptr = &state[ 0 ];
- X for( i = 0; i < 10*rand_deg; i++ ) random();
- X }
- X}
- X
- X
- X
- X/*
- X * initstate:
- X * Initialize the state information in the given array of n bytes for
- X * future random number generation. Based on the number of bytes we
- X * are given, and the break values for the different R.N.G.'s, we choose
- X * the best (largest) one we can and set things up for it. srandom() is
- X * then called to initialize the state information.
- X * Note that on return from srandom(), we set state[-1] to be the type
- X * multiplexed with the current value of the rear pointer; this is so
- X * successive calls to initstate() won't lose this information and will
- X * be able to restart with setstate().
- X * Note: the first thing we do is save the current state, if any, just like
- X * setstate() so that it doesn't matter when initstate is called.
- X * Returns a pointer to the old state.
- X */
- X
- Xchar *
- Xinitstate( seed, arg_state, n )
- X
- X unsigned seed; /* seed for R. N. G. */
- X char *arg_state; /* pointer to state array */
- X int n; /* # bytes of state info */
- X{
- X register char *ostate = (char *)( &state[ -1 ] );
- X
- X if( rand_type == TYPE_0 ) state[ -1 ] = rand_type;
- X else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
- X if( n < BREAK_1 ) {
- X if( n < BREAK_0 ) {
- X fprintf( stderr, "initstate: not enough state (%d bytes); ignored.\n", n );
- X return 0;
- X }
- X rand_type = TYPE_0;
- X rand_deg = DEG_0;
- X rand_sep = SEP_0;
- X }
- X else {
- X if( n < BREAK_2 ) {
- X rand_type = TYPE_1;
- X rand_deg = DEG_1;
- X rand_sep = SEP_1;
- X }
- X else {
- X if( n < BREAK_3 ) {
- X rand_type = TYPE_2;
- X rand_deg = DEG_2;
- X rand_sep = SEP_2;
- X }
- X else {
- X if( n < BREAK_4 ) {
- X rand_type = TYPE_3;
- X rand_deg = DEG_3;
- X rand_sep = SEP_3;
- X }
- X else {
- X rand_type = TYPE_4;
- X rand_deg = DEG_4;
- X rand_sep = SEP_4;
- X }
- X }
- X }
- X }
- X state = &( ( (long *)arg_state )[1] ); /* first location */
- X end_ptr = &state[ rand_deg ]; /* must set end_ptr before srandom */
- X srandom( seed );
- X if( rand_type == TYPE_0 ) state[ -1 ] = rand_type;
- X else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
- X return( ostate );
- X}
- X
- X
- X
- X/*
- X * setstate:
- X * Restore the state from the given state array.
- X * Note: it is important that we also remember the locations of the pointers
- X * in the current state information, and restore the locations of the pointers
- X * from the old state information. This is done by multiplexing the pointer
- X * location into the zeroeth word of the state information.
- X * Note that due to the order in which things are done, it is OK to call
- X * setstate() with the same state as the current state.
- X * Returns a pointer to the old state information.
- X */
- X
- Xchar *
- Xsetstate( arg_state )
- X
- X char *arg_state;
- X{
- X register long *new_state = (long *)arg_state;
- X register int type = new_state[0]%MAX_TYPES;
- X register int rear = new_state[0]/MAX_TYPES;
- X char *ostate = (char *)( &state[ -1 ] );
- X
- X if( rand_type == TYPE_0 ) state[ -1 ] = rand_type;
- X else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
- X switch( type ) {
- X case TYPE_0:
- X case TYPE_1:
- X case TYPE_2:
- X case TYPE_3:
- X case TYPE_4:
- X rand_type = type;
- X rand_deg = degrees[ type ];
- X rand_sep = seps[ type ];
- X break;
- X
- X default:
- X fprintf( stderr, "setstate: state info has been munged; not changed.\n" );
- X }
- X state = &new_state[ 1 ];
- X if( rand_type != TYPE_0 ) {
- X rptr = &state[ rear ];
- X fptr = &state[ (rear + rand_sep)%rand_deg ];
- X }
- X end_ptr = &state[ rand_deg ]; /* set end_ptr too */
- X return( ostate );
- X}
- X
- X
- X
- X/*
- X * random:
- X * If we are using the trivial TYPE_0 R.N.G., just do the old linear
- X * congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
- X * same in all ther other cases due to all the global variables that have been
- X * set up. The basic operation is to add the number at the rear pointer into
- X * the one at the front pointer. Then both pointers are advanced to the next
- X * location cyclically in the table. The value returned is the sum generated,
- X * reduced to 31 bits by throwing away the "least random" low bit.
- X * Note: the code takes advantage of the fact that both the front and
- X * rear pointers can't wrap on the same call by not testing the rear
- X * pointer if the front one has wrapped.
- X * Returns a 31-bit random number.
- X */
- X
- Xlong
- Xrandom()
- X{
- X long i;
- X
- X if( rand_type == TYPE_0 ) {
- X i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff;
- X }
- X else {
- X *fptr += *rptr;
- X i = (*fptr >> 1)&0x7fffffff; /* chucking least random bit */
- X if( ++fptr >= end_ptr ) {
- X fptr = state;
- X ++rptr;
- X }
- X else {
- X if( ++rptr >= end_ptr ) rptr = state;
- X }
- X }
- X return( i );
- X}
- X
- END_OF_FILE
- if test 12955 -ne `wc -c <'bsd_src/random.c'`; then
- echo shar: \"'bsd_src/random.c'\" unpacked with wrong size!
- fi
- # end of 'bsd_src/random.c'
- fi
- if test -f 'client_lock.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'client_lock.c'\"
- else
- echo shar: Extracting \"'client_lock.c'\" \(5943 characters\)
- sed "s/^X//" >'client_lock.c' <<'END_OF_FILE'
- X /*********************************************************************\
- X * Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) *
- X * *
- X * You may copy or modify this file in any manner you wish, provided *
- X * that this notice is always included, and that you hold the author *
- X * harmless for any loss or damage resulting from the installation or *
- X * use of this software. *
- X \*********************************************************************/
- X
- X#include "client_def.h"
- X
- X#ifndef NOLOCKING
- Xstatic char key_string[sizeof(KEY_PREFIX)+32];
- X
- Xstatic char code_str[] =
- X "0123456789:_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- X
- Xstatic make_key_string(server_addr,server_port)
- X unsigned long server_addr;
- X unsigned short server_port;
- X{
- X unsigned long v1, v2;
- X char *p;
- X
- X strcpy(key_string,KEY_PREFIX);
- X for(p = key_string; *p; p++);
- X v1 = server_addr;
- X v2 = server_port;
- X
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6; v1 = v1 | (v2 << (32-3*6));
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
- X *p = 0;
- X}
- X#endif
- X
- X/********************************************************************/
- X/******* For those systems that has flock function call *************/
- X/********************************************************************/
- X#ifdef USE_FLOCK
- X
- X#include <sys/file.h>
- X
- Xint key_persists = 1;
- Xstatic unsigned int lock_fd;
- Xstatic unsigned short okey;
- X
- Xclient_get_key()
- X{
- X if(flock(lock_fd,LOCK_EX) == -1) { perror("flock"); exit(1); }
- X if(read(lock_fd,&okey,sizeof(okey)) == -1) { perror("readk"); exit(1); }
- X if(lseek(lock_fd,0L,0) == -1) { perror("seek"); exit(1); }
- X return(okey);
- X}
- X
- Xclient_put_key(key)
- X unsigned short key;
- X{
- X if(write(lock_fd,&key,sizeof(key)) == -1) { perror("write"); exit(1); }
- X if(lseek(lock_fd,0L,0) == -1) { perror("seek"); exit(1); }
- X if(flock(lock_fd,LOCK_UN) == -1) { perror("unflock"); exit(1); }
- X}
- X
- Xclient_init_key(server_addr,server_port,key)
- X unsigned long server_addr;
- X unsigned short server_port;
- X unsigned short key;
- X{
- X unsigned long omask;
- X okey = key;
- X
- X make_key_string(server_addr,server_port);
- X
- X omask = umask(0);
- X lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
- X umask(omask);
- X}
- X
- X#endif
- X/********************************************************************/
- X/******* For those systems that has lockf function call *************/
- X/********************************************************************/
- X#ifdef USE_LOCKF
- X
- X#include <unistd.h>
- X
- Xint key_persists = 1;
- Xstatic unsigned int lock_fd;
- Xstatic unsigned short okey;
- X
- Xclient_get_key()
- X{
- X if(lockf(lock_fd,F_LOCK,sizeof(okey)) == -1) { perror("lockf"); exit(1); }
- X if(read(lock_fd,&okey,sizeof(okey)) == -1) { perror("readlk"); exit(1); }
- X if(lseek(lock_fd,0L,0) == -1) { perror("seek"); exit(1); }
- X return(okey);
- X}
- X
- Xclient_put_key(key)
- X unsigned short key;
- X{
- X if(write(lock_fd,&key,sizeof(key)) == -1) { perror("write"); exit(1); }
- X if(lseek(lock_fd,0L,0) == -1) { perror("seek"); exit(1); }
- X if(lockf(lock_fd,F_ULOCK,sizeof(key)) == -1) { perror("unlockf"); exit(1); }
- X}
- X
- Xclient_init_key(server_addr,server_port,key)
- X unsigned long server_addr;
- X unsigned short server_port;
- X unsigned short key;
- X{
- X unsigned long omask;
- X okey = key;
- X
- X make_key_string(server_addr,server_port);
- X
- X omask = umask(0);
- X lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
- X umask(omask);
- X}
- X
- X#endif
- X/********************************************************************/
- X/******* For those systems that has SysV shared memory + lockf ******/
- X/********************************************************************/
- X#ifdef USE_SHAREMEM_AND_LOCKF
- X
- X#include <unistd.h>
- X#include <sys/ipc.h>
- Xextern char *shmat();
- X
- Xint key_persists = 0;
- Xstatic unsigned short *share_key;
- Xstatic unsigned int lock_fd;
- X
- Xclient_get_key()
- X{
- X if(lockf(lock_fd,F_LOCK,2) == -1) { perror("lockf"); exit(1); }
- X return(*share_key);
- X}
- X
- Xclient_put_key(key)
- X unsigned short key;
- X{
- X *share_key = key;
- X if(lockf(lock_fd,F_ULOCK,2) == -1) { perror("unlockf"); exit(1); }
- X}
- X
- Xclient_init_key(server_addr,server_port,key)
- X unsigned long server_addr;
- X unsigned short server_port;
- X unsigned short key;
- X{
- X unsigned long omask;
- X key_t lock_key;
- X int lock_shm;
- X
- X make_key_string(server_addr,server_port);
- X
- X omask = umask(0);
- X lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
- X umask(omask);
- X
- X if((lock_key = ftok(key_string,3432)) == -1){ perror("ftok"); exit(1); }
- X if((lock_shm = shmget(lock_key,sizeof(short),IPC_CREAT|0666)) == -1)
- X { perror("shmget"); exit(1); }
- X if(!(share_key = (unsigned short *) shmat(lock_shm,(char*)0,0)))
- X { perror("shmat"); exit(1); }
- X}
- X
- X#endif
- X/********************************************************************/
- X/******* For those who does not want to use locking *****************/
- X/********************************************************************/
- X#ifdef NOLOCKING
- X
- Xint key_persists = 0;
- Xstatic unsigned short okey;
- X
- Xclient_get_key()
- X{
- X return(okey);
- X}
- X
- Xclient_put_key(key)
- X unsigned short key;
- X{
- X okey = key;
- X}
- X
- Xclient_init_key(server_addr,server_port,key)
- X unsigned long server_addr;
- X unsigned short server_port;
- X unsigned short key;
- X{
- X okey = key;
- X}
- X
- X#endif
- X/********************************************************************/
- X/********************************************************************/
- X/********************************************************************/
- END_OF_FILE
- if test 5943 -ne `wc -c <'client_lock.c'`; then
- echo shar: \"'client_lock.c'\" unpacked with wrong size!
- fi
- # end of 'client_lock.c'
- fi
- if test -f 'client_util.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'client_util.c'\"
- else
- echo shar: Extracting \"'client_util.c'\" \(11516 characters\)
- sed "s/^X//" >'client_util.c' <<'END_OF_FILE'
- X /*********************************************************************\
- X * Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) *
- X * *
- X * You may copy or modify this file in any manner you wish, provided *
- X * that this notice is always included, and that you hold the author *
- X * harmless for any loss or damage resulting from the installation or *
- X * use of this software. *
- X \*********************************************************************/
- X
- X#include "client_def.h"
- X
- Xextern char *realloc(), *malloc(), *getenv();
- Xextern long atol();
- Xextern int errno;
- X
- Xstatic int env_dir_malloced = 0;
- Xchar *env_dir = "/";
- Xchar *env_myport;
- Xchar *env_host;
- Xchar *env_port;
- Xunsigned short client_buf_len;
- Xunsigned short client_net_len;
- X
- Xchar *util_abs_path(s2)
- X char *s2;
- X{
- X char *path, *s, *d, *t;
- X
- X if(!env_dir) env_dir = "";
- X if(!s2) s2 = "";
- X
- X if(*s2 == '/')
- X {
- X path = malloc(strlen(s2)+2);
- X sprintf(path,"/%s",s2);
- X } else
- X {
- X path = malloc(strlen(env_dir)+strlen(s2)+3);
- X sprintf(path,"/%s/%s",env_dir,s2);
- X }
- X
- X for(t = path; *t; )
- X {
- X if(t[0] == '/')
- X {
- X while(t[1] == '/') for(d = t, s = t+1; *d++ = *s++; );
- X if(t != path && t[1] == 0) { t[0] = 0; return(path); }
- X }
- X if(t[0] == '.' && t[1] == '.')
- X {
- X if(t-1 == path && t[2] == 0 ) { *t = 0; return(path); }
- X if(t-1 == path && t[2] == '/')
- X {
- X for(d = t, s = t + 3; *d++ = *s++; );
- X continue;
- X }
- X if(t[-1] == '/' && (t[2] == '/' || t[2] == 0))
- X {
- X s = t + 2; /* point to either slash or nul */
- X t -= 2; /* guaranteed that t >= path here */
- X while(t > path && t[0] != '/') t--;
- X if(t != path || *s == '/') { for(d = t; *d++ = *s++; ); }
- X else { t[1] = 0; return(path); }
- X continue;
- X }
- X }
- X if(t[0] == '.')
- X {
- X if(t-1 == path && t[1] == 0 ) { *t = 0; return(path); }
- X if(t-1 == path && t[1] == '/')
- X {
- X for(d = t, s = t + 2; *d++ = *s++; );
- X continue;
- X }
- X if(t[-1] == '/' && (t[1] == '/' || t[1] == 0))
- X {
- X s = t + 1; /* point to either slash or nul */
- X for(d = t-1; *d++ = *s++; );
- X t--;
- X continue;
- X }
- X }
- X t++;
- X }
- X return(path);
- X}
- X
- Xchar *util_getwd(p)
- X char *p;
- X{
- X if(p) strcpy(p,env_dir);
- X return(p);
- X}
- X
- XRDIRENT **get_dir_blk(path)
- X char *path;
- X{
- X RDIRENT **dp;
- X char *p1, *p2, *fpath, buf[2*UBUF_SPACE];
- X unsigned long pos;
- X int cnt, k, len, rem, acc, at_eof;
- X UBUF *ub;
- X
- X fpath = util_abs_path(path);
- X
- X for(pos = 0, at_eof = acc = cnt = 0; ; )
- X {
- X while((acc < UBUF_SPACE) && !at_eof)
- X {
- X ub = client_interact(CC_GET_DIR,pos,
- X strlen(fpath),fpath+1, 2,&client_net_len);
- X
- X if(ub->cmd == CC_ERR)
- X {
- X fprintf(stderr,"directory reading error: %s\n",ub->buf);
- X free(fpath);
- X errno = EACCES;
- X return((RDIRENT **) 0);
- X }
- X
- X if(ub->len < client_buf_len) at_eof = 1;
- X for(p1 = ub->buf, p2 = buf + acc, k = ub->len; k--; ) *p2++ = *p1++;
- X acc += ub->len;
- X pos += ub->len;
- X }
- X
- X if(acc >= UBUF_SPACE) len = UBUF_SPACE;
- X else len = acc;
- X
- X for(p2 = buf, rem = len, k = 0; ; k++)
- X {
- X if(rem < RDHSIZE) break;
- X if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
- X if(((RDIRENT *) p2)->type == RDTYPE_END ) { k++; break; }
- X p2 += RDHSIZE; rem -= (RDHSIZE+1);
- X while(*p2++ ) { rem--; }
- X while((p2 - buf) & 3) { p2++; rem--; }
- X }
- X
- X p1 = malloc(p2-buf);
- X if(cnt) dp = (RDIRENT **) realloc(dp,(cnt+k+1)*sizeof(RDIRENT *));
- X else dp = (RDIRENT **) malloc( (cnt+k+1)*sizeof(RDIRENT *));
- X
- X if(!p1 || !dp) { free(fpath);
- X fputs("directory reading out of memory\n",stderr);
- X return((RDIRENT **) 0); }
- X
- X for(p2 = buf, rem = len; ; cnt++)
- X {
- X if(rem < RDHSIZE) break;
- X if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
- X if(((RDIRENT *) p2)->type == RDTYPE_END )
- X { dp[cnt] = 0; return(dp); }
- X dp[cnt] = (RDIRENT *) p1;
- X ((RDIRENT *) p1)->time = ntohl(((RDIRENT *) p2)->time);
- X ((RDIRENT *) p1)->size = ntohl(((RDIRENT *) p2)->size);
- X ((RDIRENT *) p1)->type = ((RDIRENT *) p2)->type ;
- X
- X p2 += RDHSIZE; p1 += RDHSIZE; rem -= (RDHSIZE+1);
- X while(*p1++ = *p2++ ) { rem--; }
- X while((p2 - buf) & 3) { p2++; p1++; rem--; }
- X }
- X
- X if(acc < UBUF_SPACE) { dp[cnt] = 0; return(dp); }
- X for(p1 = buf + UBUF_SPACE, p2 = buf, k = (acc -= UBUF_SPACE); k--; )
- X *p2++ = *p1++;
- X }
- X}
- X
- Xutil_download_main(path,fpath,fp,cmd)
- X char *path, *fpath;
- X FILE *fp;
- X int cmd;
- X{
- X unsigned long pos;
- X unsigned tmax, wrote, sent_time;
- X UBUF *ub;
- X
- X for(tmax = 1, pos = 0, sent_time = 0; ; )
- X {
- X ub = client_interact(cmd,pos, strlen(fpath),fpath+1, 2,&client_net_len);
- X
- X if(client_trace && (udp_sent_time != sent_time))
- X {
- X sent_time = udp_sent_time;
- X if(client_buf_len == UBUF_SPACE)
- X fprintf(stderr,"\r%luk ",1+(pos>>10));
- X else fprintf(stderr,"\r%lu ", pos );
- X fflush(stderr);
- X }
- X
- X if(ub->cmd == CC_ERR)
- X {
- X fprintf(stderr,"downloading %s: %s\n",path,ub->buf);
- X return(-1);
- X }
- X
- X wrote = fwrite(ub->buf,1,ub->len,fp);
- X pos += wrote;
- X
- X if(ub->len < client_buf_len || ub->len != wrote) break;
- X }
- X
- X if(client_trace) { fprintf(stderr,"\r%luk : %s \n",1+(pos>>10),path);
- X fflush(stderr); }
- X
- X return(0);
- X}
- X
- Xutil_download(path,fp)
- X char *path;
- X FILE *fp;
- X{
- X int code;
- X char *fpath;
- X
- X fpath = util_abs_path(path);
- X code = util_download_main(path,fpath,fp,CC_GET_FILE);
- X free(fpath);
- X return(code);
- X}
- X
- Xutil_grab_file(path,fp)
- X char *path;
- X FILE *fp;
- X{
- X int code;
- X char *fpath;
- X UBUF *ub;
- X
- X fpath = util_abs_path(path);
- X code = util_download_main(path,fpath,fp,CC_GRAB_FILE);
- X if(code) { free(fpath); return(code); }
- X
- X ub = client_interact(CC_GRAB_DONE,0L, strlen(fpath),fpath+1, 0,NULLP);
- X
- X if(ub->cmd == CC_ERR)
- X {
- X fprintf(stderr,"Warning, unexpected grab error: %s\n",ub->buf);
- X }
- X
- X free(fpath);
- X return(code);
- X}
- X
- Xutil_upload(path,fp)
- X char *path;
- X FILE *fp;
- X{
- X unsigned long pos;
- X unsigned bytes, first, tmax, sent_time;
- X char *fpath, buf[UBUF_SPACE];
- X UBUF *ub;
- X
- X fpath = util_abs_path(path);
- X
- X for(tmax = 1, sent_time = 0, pos = 0, first = 1; ; first = 0)
- X {
- X if((bytes = fread(buf,1,client_buf_len,fp)) || first)
- X {
- X ub = client_interact(CC_UP_LOAD,pos, bytes,buf, 0,NULLP);
- X
- X if(client_trace && (udp_sent_time != sent_time))
- X {
- X sent_time = udp_sent_time;
- X if(client_buf_len == UBUF_SPACE)
- X fprintf(stderr,"\r%luk ",1+(pos>>10));
- X else fprintf(stderr,"\r%lu ", pos );
- X fflush(stderr);
- X }
- X
- X } else
- X {
- X ub = client_interact(CC_INSTALL,pos,strlen(fpath),fpath+1,0,NULLP);
- X }
- X
- X if(ub->cmd == CC_ERR)
- X {
- X fprintf(stderr,"uploading %s: %s\n",path,ub->buf);
- X free(fpath); return(1);
- X }
- X
- X if(!bytes && !first) break;
- X pos += bytes;
- X }
- X
- X if(client_trace) { fprintf(stderr,"\r%luk : %s \n",1+(pos>>10),path);
- X fflush(stderr); }
- X
- X free(fpath); return(0);
- X}
- X
- Xutil_get_env()
- X{
- X char *p;
- X
- X if(!(env_host = getenv("FSP_HOST")))
- X { fputs("Env var FSP_HOST not defined\n",stderr); exit(1); }
- X if(!(env_port = getenv("FSP_PORT")))
- X { fputs("Env var FSP_PORT not defined\n",stderr); exit(1); }
- X if(!(env_dir = getenv("FSP_DIR")))
- X { fputs("Env var FSP_DIR not defined\n",stderr); exit(1); }
- X
- X if(!(env_myport = getenv("FSP_LOCALPORT"))) env_myport = "0";
- X
- X client_trace = !!getenv("FSP_TRACE");
- X
- X if(p = getenv("FSP_BUF_SIZE")) client_buf_len = atoi(p);
- X else client_buf_len = UBUF_SPACE;
- X
- X if(client_buf_len > UBUF_SPACE) client_buf_len = UBUF_SPACE;
- X client_net_len = htons(client_buf_len);
- X
- X if(p = getenv("FSP_DELAY")) target_delay = atol(p);
- X}
- X
- Xvoid client_intr()
- X{
- X switch(client_intr_state)
- X {
- X case 0: exit(2);
- X case 1: client_intr_state = 2; break;
- X case 2: exit(3);
- X }
- X}
- X
- Xenv_client()
- X{
- X util_get_env();
- X init_client(env_host,atoi(env_port),atoi(env_myport));
- X signal(SIGINT,client_intr);
- X}
- X
- X/*****************************************************************************/
- X
- Xstatic DDLIST *ddroot = 0;
- X
- XRDIR *util_opendir(path)
- X char *path;
- X{
- X char *fpath;
- X RDIRENT **dep;
- X DDLIST *ddp;
- X RDIR *rdirp;
- X
- X fpath = util_abs_path(path);
- X
- X for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
- X
- X if(!ddp)
- X {
- X if(!(dep = get_dir_blk(fpath))) return((RDIR *) 0);
- X ddp = (DDLIST *) malloc(sizeof(DDLIST));
- X ddp->dep_root = dep;
- X ddp->path = fpath;
- X ddp->ref_cnt = 0;
- X ddp->next = ddroot;
- X ddroot = ddp;
- X
- X } else free(fpath);
- X
- X ddp->ref_cnt++;
- X
- X rdirp = (RDIR *) malloc(sizeof(RDIR));
- X rdirp->ddp = ddp;
- X rdirp->dep = ddp->dep_root;
- X return(rdirp);
- X}
- X
- Xutil_closedir(rdirp)
- X RDIR *rdirp;
- X{
- X rdirp->ddp->ref_cnt--;
- X free(rdirp);
- X}
- X
- Xrdirent *util_readdir(rdirp)
- X RDIR *rdirp;
- X{
- X static rdirent rde;
- X RDIRENT **dep;
- X
- X dep = rdirp->dep;
- X
- X if(!*dep) return((rdirent *) 0);
- X
- X rde.d_fileno = 10;
- X rde.d_reclen = 10;
- X rde.d_namlen = strlen((*dep)->name);
- X rde.d_name = (*dep)->name;
- X rdirp->dep = dep+1;
- X
- X return(&rde);
- X}
- X
- Xutil_split_path(path,p1,p2,p3)
- X char *path, **p1, **p2, **p3;
- X{
- X char *s;
- X static char junk;
- X
- X *p1 = "/";
- X if(*path == '/') { *p2 = path; *p3 = path+1; }
- X else { *p2 = &junk; *p3 = path ; }
- X
- X for(s = *p3; *s; s++)
- X {
- X if(*s == '/')
- X {
- X *p1 = path;
- X *p2 = s;
- X *p3 = s+1;
- X }
- X }
- X
- X if (**p3 == '\0') *p3 = ".";
- X return(1);
- X}
- X
- Xutil_stat(path,sbuf)
- X char *path;
- X struct stat *sbuf;
- X{
- X RDIR *drp;
- X RDIRENT **dep;
- X char *fpath, *ppath, *p1, *pfile;
- X
- X fpath = util_abs_path(path);
- X
- X if(!strcmp(fpath,env_dir))
- X {
- X ppath = fpath;
- X pfile = ".";
- X
- X } else
- X {
- X util_split_path(fpath,&ppath,&p1,&pfile); *p1 = 0;
- X }
- X
- X if(drp = util_opendir(ppath))
- X {
- X for(dep = drp->dep; *dep; dep++)
- X {
- X if(!strcmp((*dep)->name,pfile))
- X {
- X if((*dep)->type & RDTYPE_DIR) sbuf->st_mode = 0777 | S_IFDIR;
- X else sbuf->st_mode = 0666 | S_IFREG;
- X
- X if((*dep)->type & RDTYPE_DIR) sbuf->st_nlink = 2;
- X else sbuf->st_nlink = 1;
- X sbuf->st_uid = 0;
- X sbuf->st_gid = 0;
- X sbuf->st_size = (*dep)->size;
- X sbuf->st_atime = (*dep)->time;
- X sbuf->st_mtime = (*dep)->time;
- X sbuf->st_ctime = (*dep)->time;
- X util_closedir(drp); free(fpath); return(0);
- X }
- X }
- X util_closedir(drp);
- X }
- X
- X free(fpath); errno = ENOENT; return(-1);
- X}
- X
- Xutil_cd(p)
- X char *p;
- X{
- X char *fpath;
- X UBUF *ub;
- X DDLIST *ddp;
- X
- X fpath = util_abs_path(p);
- X for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
- X
- X if(!ddp && strcmp(p,".") && strcmp(p,".."))
- X {
- X ub = client_interact(CC_GET_DIR,0L, strlen(fpath),fpath+1,
- X 2,&client_net_len);
- X if(ub->cmd == CC_ERR)
- X {
- X free(fpath);
- X fprintf(stderr,"cd error: %s\n",ub->buf);
- X errno = EACCES;
- X return(-1);
- X }
- X }
- X
- X if(env_dir_malloced) free(env_dir);
- X env_dir_malloced = 1;
- X env_dir = fpath;
- X return(0);
- X}
- X
- Xutil_cd2(p) /* Perform a cd, but don't verify path. Assume the path */
- X char *p; /* has been verified by another mechanism. */
- X{
- X char *fpath;
- X
- X fpath = util_abs_path(p);
- X
- X if(env_dir_malloced) free(env_dir);
- X env_dir_malloced = 1;
- X env_dir = fpath;
- X return(0);
- X}
- END_OF_FILE
- if test 11516 -ne `wc -c <'client_util.c'`; then
- echo shar: \"'client_util.c'\" unpacked with wrong size!
- fi
- # end of 'client_util.c'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-