diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-01-30 00:19:41 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-01-30 00:19:41 +0000 |
commit | de069631fd3bce2e513ee8613a94038f23afe1b3 (patch) | |
tree | 0b8d9d99cdfb52e8d0c3f85c45859a42ed004bd3 /gnu/usr.bin/cvs/os2 | |
parent | 2b9936f3f7ab47a89436d4fa3b70e4c09dd2398e (diff) |
Upgrade to 1.7.1 snapshot
Diffstat (limited to 'gnu/usr.bin/cvs/os2')
-rw-r--r-- | gnu/usr.bin/cvs/os2/.cvsignore | 3 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/ChangeLog | 589 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/Makefile.in | 303 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/README | 31 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/dirent.c | 180 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/dirent.h | 50 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/filesubr.c | 737 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/getdate.c | 1578 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/getpass.c | 25 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/mkdir.c | 17 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/options.h | 276 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/popen.c | 380 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/popen.h | 6 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/porttcp.c | 227 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/pwd.c | 205 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/pwd.h | 77 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/rcmd.c | 66 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/rcmd.h | 30 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/run.c | 602 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/strippath.c | 60 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/stripslash.c | 31 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/tcpip.h | 107 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/test-makefile | 40 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/os2/waitpid.c | 36 |
24 files changed, 5656 insertions, 0 deletions
diff --git a/gnu/usr.bin/cvs/os2/.cvsignore b/gnu/usr.bin/cvs/os2/.cvsignore new file mode 100644 index 00000000000..fc6daa165c6 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/.cvsignore @@ -0,0 +1,3 @@ +Makefile +cvs.exe +icc.in diff --git a/gnu/usr.bin/cvs/os2/ChangeLog b/gnu/usr.bin/cvs/os2/ChangeLog new file mode 100644 index 00000000000..0a6070f4b08 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/ChangeLog @@ -0,0 +1,589 @@ +Sun Jan 28 12:31:03 1996 Jim Kingdon (kingdon@beezley) + + * filesubr.c (unlink_file): Use xchmod, not chmod, to make the + file read-write. + (xchmod): Translate / to \ in file name. If file doesn't exist, + return ENOENT rather than passing it to attrib (which will print an + error message). + +Sun Jan 28 01:51:27 1996 Jim Kingdon (kingdon@beezley) + + * config.h: Fix unclosed comment. + +Sun Jan 28 00:16:58 1996 Karl Fogel (kfogel@floss.cyclic.com) + + * filesubr.c (xchmod): rewritten for OS/2. + +Sat Jan 27 16:18:20 1996 Karl Fogel (kfogel@floss.cyclic.com) + + * config.h (CHMOD_BROKEN): define to 1. + + * filesubr.c (rename_file): rename() returns non-zero error codes, + not necessarily negative. + +Fri Jan 26 00:52:12 1996 unknown (unknown@beezley) + + * filesubr.c (copy_file): Open the file we are writing, not + just the one we are reading, in binary mode. + +Thu Jan 18 14:53:58 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (CFLAGS): Don't use +=. This makefile must be + portable because it is used on all platforms (e.g. for "make dist"). + +Thu Jan 11 12:04:42 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * options.h: remove CVS_NOADMIN + +Wed Jan 10 15:56:46 1996 Karl Fogel <kfogel@floss.red-bean.com> + + * options.h, config.h: moved NO_SOCKET_TO_FD definition from + options.h to config.h, which is where it belongs. + +Tue Jan 9 16:43:15 1996 Karl Fogel <kfogel@floss.red-bean.com> + + * run.c (sleep): commented out this definition. + * config.h: #define sleep() in terms of DosSleep(), unless sleep() + is defined already. Normally it's defined in + tcpip/include/utils.h, however on beezley that definition is + commented out for some reason. + Don't prototype sleep(). + +Tue Jan 9 16:22:35 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * .cvsignore: Add cvs.exe and icc.in. + +Tue Jan 09 16:43:59 1996 Jim Kingdon (kingdon@beezley.cyclic.com) + + * filesubr.c (link_file): New function (copied from + ../windows-NT/filesubr.c) + +Fri Jan 5 17:03:09 1996 Karl Fogel <kfogel@floss.red-bean.com> + + * Makefile.in: "lib_dir", not "libdir", to avoid conflict with + top-level Makefile. + +Mon Jan 1 22:59:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): Makefile is not in srcdir. + +Sat Dec 23 23:08:43 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * README: adjust for below change. + + * Makefile.in (install-cvs): replaces `install', which must remain + a dummy rule so it will work under Unix. + +Wed Dec 20 15:18:06 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in: build scramble.obj. + +Mon Dec 18 22:49:28 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Reverted all changes between Mon Dec 18 14:54:04 1995 and + present, non-inclusive. + +Mon Dec 18 21:59:07 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * getpass.c: removed -- getpass() lives in os2/login.c now. + + * cvslogin.c: filled in. + + * login.c: new file. + + * Makefile.in: moved login.c and login.obj from COMMON to OS2 + section. + +Mon Dec 18 19:55:43 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * cvslogin.c: added long explanatory comment. + +Mon Dec 18 18:13:57 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (DISTFILES): include cvslogin.c. + +Mon Dec 18 18:07:26 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * README: updated. + + * Makefile.in (cvslogin.exe): new rule. + (install): new rule. + (install_dir): new var. + + * cvslogin.c: new file. + +Mon Dec 18 14:54:04 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * getpass.c (getpass): removed debugging garbage. + + * options.h (NO_SOCKET_TO_FD): fixed comment (Windows 95, not NT, + has this problem). + (AUTH_CLIENT_SUPPORT): on by default. + + * porttcp.c (SockStrError): fixed typo. + (IbmSockSend): `Buffer' arg is const void * again. + (IbmSockRecv): `Buffer' arg is const void * again. + + * tcpip.h (send): move send/recv redef section farther down to + avoid type conflicts with the real send() and recv(). + (IbmSockSend, IbmSockRecv): adjust prototype. + +Mon Dec 18 12:31:22 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * tcpip.h: reformatted. + (send, recv): redefine to IbmSockSend and IbmSockRecv. + + * porttcp.c: reformatted. + +Mon Dec 18 04:59:52 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * tcpip.h (send, recv): don't define these to be anything else. + + * porttcp.c (IbmSockSend, IbmSockRecv): make `Buffer' argument + char * instead of void *, to evade an over-eager compiler. + +Sun Dec 17 21:16:17 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * options.h (NO_SOCKET_TO_FD): define to 1. + +Sat Dec 16 21:31:02 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * run.c: mark unimplemented routines more clearly. Hopefully I'll + get time to implement them soon. + +Fri Dec 15 17:50:17 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * tcpip.h, porttcp.c: new files. + + * makefile.in: added new files (for the "cvs watch" and "cvs edit" + commands just checked in by Jim Kingdon). + +Thu Dec 14 12:18:20 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * config.h (RSH_NEEDS_BINARY_FLAG): define to 1. + + * run.c (filter_stream_through_program): die, rather than return + -1, if spawn failed. + + * options.h (AUTH_CLIENT_SUPPORT): leave unset by default. + +Wed Dec 13 21:31:10 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * waitpid.c (waitpid): Don't deal specially with statusp after all. + The problem lies elsewhere. + +Wed Dec 13 20:58:12 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * waitpid.c (waitpid): oops, make sure there is storage for + local_statusp. + Don't assign to *statusp if statusp is NULL. + +Wed Dec 13 19:52:08 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * waitpid.c (waitpid): be more careful about child's exit status, + and about return status of this function. + +Wed Dec 13 20:10:50 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * makefile.in (clean): pass /NOE to the linker, to avoid duplicate + symbols when linking with setargv.obj. + +Wed Dec 13 18:44:47 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (ARGVLIB): new lib, link with this so command-line + wildcard expansion works. No, I'm not making this up. + +Tue Dec 12 20:43:56 1995 Karl Fogel (kfogel@floss.cyclic.com) + + * getpass.c (getpass): new file and function. + + * options.h: prototype getpass() for OS/2. + + * makefile.in: include new file getpass.c. + +Tue Dec 12 19:21:05 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * options.h (RCSBIN_DFLT): expand comment. + (AUTH_CLIENT_SUPPORT, AUTH_SERVER_SUPPORT): replace obsolete + CVS_AUTH_CLIENT_SUPPORT and CVS_AUTH_SERVER_SUPPORT. + +Mon Dec 11 16:03:01 1995 Karl Fogel (kfogel@beezley.cyclic.com) + + * makefile.in: removed various and sundry cruft... + +Mon Dec 11 15:57:03 1995 Karl Fogel (kfogel@beezley.cyclic.com) + + * Removed cvs.exe; we don't need to keep the binary in the + repository, now that binary file handling has been tested. + +Mon Dec 11 15:53:51 1995 Karl Fogel (kfogel@beezley.cyclic.com) + + * rcmd.c (init_sockets): use sock_init(), not SockInit(). + +Mon Dec 11 12:43:35 1995 Adam Glass <adamg@microsoft.com> + + * config.h: Remove NEED_CALL_SOCKINIT macro in favor of the more + generic INITIALIZE_SOCKET_SUBSYSTEM. + * rcmd.c: Move old NEED_CALL_SOCKINIT code here and wrap it in a + function, i.e init_sockets() + +Sat Dec 09 21:16:09 1995 Karl Fogel (kfogel@beezley.cyclic.com) + + * Added cvs.exe, mainly to test binary file handling. Once we + know it works, we can remove it. + +Sat Dec 09 15:29:16 1995 Karl Fogel (kfogel@beezley.cyclic.com) + + * options.h (DIFF, GREP): don't expect autoconf to help us out. + +Sat Dec 09 15:05:41 1995 Karl Fogel (kfogel@beezley.cyclic.com) + + * makefile.in (libdir): Fixed. + + * options.h: define CVS_AUTH_CLIENT_SUPPORT and + CVS_AUTH_SERVER_SUPPORT, instead of CVS_LOGIN. + +Thu Dec 7 14:49:16 1995 Jim Meyering (meyering@comco.com) + + * filesubr.c (isaccessible): Rename from isaccessable. + +Mon Dec 4 11:28:10 1995 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (DISTFILES): prefix all filenames with + ${srcdir}${PS} + (dist-dir): remove ${srcdir}${PS} (some files already had this + prefix, now all have it) + +Fri Dec 1 14:29:44 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (srcdir, libdir, cvs_srcdir): use autoconf vars. + (dist-dir): use above vars now that they are autoconf-friendly. + (clean): same. + +Thu Nov 30 18:09:50 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * waitpid.c (waitpid): if _cwait() returns -1, test errno. If + ECHILD, then just return pid, else return -1. This is for OS/2, + which doesn't have zombie processes, or any other way of + remembering a child process after it exits, as far as I can tell. + + * run.c (close_on_exec): don't error, just silently do nothing. + + * Makefile.in: use src/client.c, not os2/client.c. + + * config.h (EXECUTE_PERMISSION_LOSES): define to 1 (see + src/client.c for why). + (START_RSH_WITH_POPEN_RW): define to 1 (see src/client.c). + +Wed Nov 29 16:34:34 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * client.c (start_server): declare pipes[] as int, not FILE *. + Kinda nice that it worked anyway, but scary. Ugh. + +Wed Nov 22 11:29:11 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * config.h (KFF_DEBUG): expand to nothing; we don't want to print + out debugging messages in a production copy. + +Tue Nov 21 17:36:16 1995 unknown (unknown@beezley) + + * popen.c: #include <fcntl.h>. + +Tue Nov 21 16:18:37 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * popen.h (popenRW): prototype popenRW()... why wasn't I doing + this before? + + * client.c (start_server): set tofd and fromfd with popenRW, now + that it handles int file descriptors. + Log to a file if asked, now that we have + filter_stream_through_program(). + + * popen.c (popenRW): put int file descriptors into the `pipes' + array, not FILE *'s. We'll fdopen in start_server, just like + the good old days. + +Tue Nov 21 16:34:37 1995 unknown (unknown@beezley) + + * run.c (filter_stream_through_program): defined for OS/2. + + * client.c (start_server): pass a char **argv to popenRW and get a + pid in return (instead of a return code). + + * popen.c (popenRW): use a char **argv and spawnvp(), instead of a + char *command and DosExecPgm(). + +Mon Nov 20 23:31:54 1995 unknown (unknown@beezley) + + * filesubr.c (convert_file): pass (S_IREAD | S_IWRITE) to open(); + we need it if O_CREAT, and it won't hurt if not. + +Sun Nov 19 13:43:02 1995 unknown (unknown@beezley) + + * makefile.in (clean): remove obj files in src/ and lib/ dirs too. + +Sun Nov 19 12:35:08 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * client.c (start_server): took out old debug statements. + + * dirent.c, dirent.h: took out ^M's. + +Sat Nov 18 13:39:06 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * client.c (start_server): took out debug statements. + + * filesubr.c (make_directories): compare errno to EACCESS, not + EEXIST, to see if the dir already exists. + + * client.c, filesubr.c: Use new macro `existence_error', instead + of comparing errno to ENOENT directly. + + * popen.c (popenRW): fixed misleading comment. + + * client.c: + (rsh_pid): no more need for this var; the handle-to-PID library in + popen.c manages PID's for us now. + (start_rsh_server): removed this func, since we don't use it -- we + do use `rsh', but we call it directly from popenRW(). + (get_responses_and_close): removed cruft that doesn't apply to + this port -- i.e., blocks conditional on HAVE_KERBEROS or + RSH_NOT_TRANSPARENT. + (start_server): Just check return code, instead of recording + rsh_pid. + +Fri Nov 17 21:13:22 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * client.c (call_in_directory): Ask EACCESS even though we're + looking for EEXIST. That's just The Way Things Are Done here, + apparently. Ick. + + * getdate.c: took out some cruft that the more portable versions + need. + + * Makefile.in: use getdate.c from os2/ subdir, not lib/. + We don't use startserver.c anymore, so don't build it. + + * client.c (change_mode): never set anything executable, until we + understand what that means in OS/2. + + * config.h (NEED_DECOY_PERMISSIONS): define to 1 (& see + system.h). + +Fri Nov 17 15:02:05 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * client.c: fixed up more error codes. + + * client.c: (send_repository): take into account the cornucopia of + error codes so generously offered by OS/2. + +Fri Nov 17 14:53:22 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * client.c, client.h: new files, copied from ../src/. + + * config.h (HAVE_POPEN_RW): don't define this anymore, since we'll + just be using our own version of client.c. + + * Makefile.in: reflect the fact that os2/client.c is now used + instead of src/client.c. + +Thu Nov 16 21:47:22 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * startserver.c: removed. We don't need this anymore. + + * config.h (RSH_NOT_TRANSPARENT): undef this. We have a + transparent rsh. + (HAVE_POPEN_RW): define to 1. + + * popen.c (popenRW): open writing and reading streams in binary + mode (i.e., "wb" and "rb"). + + * Makefile.in (clean): use `rm' not `del' to remove files. + +Wed Nov 15 15:21:53 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * config.h: don't prototype gethostname() here anymore. + (USE_OWN_TCPIP_H): define to 1. + (NEED_CALL_SOCKINIT): define to 1. + (KFF_DEBUG): debugging macro. + +Tue Nov 14 12:20:22 1995 Greg A. Woods <woods@most.weird.com> + + * .cvsignore: "Makefile" generated by ../configure + +Mon Nov 13 13:21:43 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (PS): note to maintainers about this var. + +Mon Nov 13 07:28:04 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * README: updated. + + * rcmd.c: #include <stdio.h>. + + * Makefile.in: Include lib/regex, lib/getdate, strippath. + (PS): default to "/", since we always "make dist" on Unix + systems. + Ahem, "save-cwd" with a hyphen, not an underscore. Oops. + + * strippath.c: new file. + + * popen.c: set DIAGNOSTIC off. Reformat for readability. + + * popen.h: new file. + + * config.h (USE_OWN_POPEN): define to 1. + + * run.c (Popen): make this work now that we have popen(). + +Mon Nov 13 01:23:27 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in: + (cvs.exe): broke up OBJECTS into components to create icc.in in + more steps. OBJECTS had gotten so big that it formed too long a + command line all by itself. Sheesh. + Include stripslash (see below), lib/save_cwd, lib/sighandle, + lib/yesno, startserver (see below), rcmd (see below), lib/xgetwd, + lib/md5, waitpid (see below), lib/fnmatch, popen (see below). + + * popen.c, rcmd.c, rcmd.h, startserver.c, stripslash.c, waitpid.c: + New files. + + * run.c (close_on_exec): new func (skeleton). + (sleep): new func (OS/2 doesn't seem to have this). + + * pwd.c (getlogin): Don't call win32getlogin(), obviously. + + * config.h (W_OK, R_OK, X_OK, F_OK): define masks for access(). + Include <process.h> for getpid(). + + * filesubr.c (isaccessable): define. Don't know why I left it out + before. For that matter, I don't know how the Windows NT port + gets along without it. Hmmm. + +Sat Nov 11 15:00:01 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in: Use backslashes in pathnames, so ICC doesn't + mistake them for options. + + * run.c (run_setup): cleared away Windows NT stuff, left skeleton + functions that just complain and die for now. + (run_exec): correctly check return of spawn under OS/2; return + child's exit status. + (run_args): declare as returning void, in agreement with cvs.h. + +Fri Nov 10 14:21:14 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (COMMON_SOURCES, COMMON_OBJECTS): removed filesubr + and run, since we have OS/2-specific versions of them now. + (DISTFILES): Include Makefile in distribution, since people won't + be running configure on their OS/2 systems. + (LIB_SOURCES, LIB_OBJECTS): new vars; we'll just build stuff in + the lib directory and link it in directly. + Made rules for compiling objects and for the full executable. + (SHELL): got rid of this var, no need for it here. + Use a pattern rule for obj files. + Some other minor tweaks for OS/2. + + * threads.c: new file. + +Wed Nov 8 11:14:46 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * run.c: include <stdarg.h> and <stdio.h>. + Change all VA_START to va_start. + Don't ask HAVE_VPRINTF -- this is an OS/2-specific file and we can + take things for granted. + Started simplifying old NT `HANDLE' code. + + * Makefile.in (OS2_SOURCES): added run.c. + + * run.c: new file, copied from ../windows-NT/run.c. Started + making changes for OS/2. + + * test-makefile (all): don't bother to echo $CFLAGS; we can just + read the compilation command. + + * filesubr.c (unlink_file): make this work on OS/2. + (unlink_file_dir): don't ask if errno == EISDIR. We ain't + got EISDIR in OS/2. + (deep_remove_dir): use EACCESS to determine if directory + nonempty. We ain't got ENOTEMPTY in OS/2. + (that_swing): removed references. We ain't got that_swing in + OS/2. + (rename_file): just use unlink_file(); move to after definition of + unlink_file() so we don't have to deal with IBM C/C++'s strange + prototyping rituals. + (link_file): removed this function -- no one uses it anymore. + It still exists in src/filesubr.c, though. + (OS2_filename_classes): new table (well, old table, new name). + All references changed. + + * config.h (HAVE_SYS_UTIME_H): define to 1. + + * options.h: undef SETXID_SUPPORT, to correspond with Norbert + Kiesel's recent change to ../src/options.h.in, etc. + +Mon Nov 6 16:29:00 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * test-makefile (CFLAGS): -DHAVE_CONFIG_H -- this turns out to be + important for stuff in lib/. + Other trivial changes. + + * config.h (HAVE_DIRENT_H): define to 1, now that we have our own + dirent.h and dirent.c. + + * Makefile.in (OS2_SOURCES): added filesubr.c; this may not be + permanent. + +Sun Nov 5 16:17:33 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (OS2_HEADERS, OS2_SOURCES): added dirent.h and + dirent.c, respectively. + + * dirent.c, dirent.h: new files. + +Sat Oct 28 14:41:38 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (DISTFILES): include `test-makefile'. + + * test-makefile: new file; to be removed when the port is done. + +Fri Oct 27 13:03:28 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (OS2_HEADERS, OS2_SOURCES): adjust as necessary for + below changes. + + * config.h: oops, don't forget second argument, MODE. + + * mkdir.c (os2_mkdir): new file, new function. + Can probably be merged with wnt_mkdir at some point. + + * config.h (ALLOCA_IN_STDLIB): new #define. + + * pwd.h, pwd.c: new files (for now, copied from ../windows-NT + directory. We'll modify/merge them as necessary.) + + * config.h: don't use __stdcall in declaration of gethostname(). + + * Makefile.in (DISTFILES): include config.h and options.h. + +Wed Oct 25 12:52:54 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * config.h: new file; will maintain by hand. + Made first pass through to cast it into OS/2-ish condition. + + * Makefile.in: started adding lots of OS/2 gunk. + Took out autoconf stuff; just don't want to fool around with that + until after it compiles on beezley. + (cvs.exe): moved this rule to bottom. + +Tue Oct 24 13:51:05 1995 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in: add autoconf variables + + * Makefile.in (dist): use $(srcdir) + +Mon Oct 23 17:37:36 1995 Karl Fogel <kfogel@floss.cyclic.com> + + * Makefile.in (clean): new rule. + + * init os2 directory. Made dummy Makefile.in, README. diff --git a/gnu/usr.bin/cvs/os2/Makefile.in b/gnu/usr.bin/cvs/os2/Makefile.in new file mode 100644 index 00000000000..dfa66b4fd80 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/Makefile.in @@ -0,0 +1,303 @@ +# Makefile for OS/2. Generated from Makefile.in when CVS is +# configured for a dist-build. Configure never gets run on OS/2, so +# we must include the generated Makefile in the distribution. See the +# `dist-dir' rule. + +project: cvs.exe +# .SUFFIXES .c .obj .exe + +# path slash +# Maintainers: always leave this set to "/", because `make dist' has +# to work on Unix systems. See os2/README to find out why we have +# this var. +SL = / + +# Directory in which to install executables. +install_dir = s:${SL}gnu${SL}util + +# srcdir is usually "." +srcdir = @srcdir@ + +# top_srcdir is usually ".." +top_srcdir = @top_srcdir@ + +lib_dir = @top_srcdir@${SL}lib +cvs_srcdir = @top_srcdir@${SL}src + +# Do we need these? +# prefix = /usr/local +# exec_prefix = ${prefix} + +# taken straight from the example project +LIB = s:${SL}ibmcpp${SL}lib;s:${SL}toolkt21${SL}os2lib; +CINC = -Is:${SL}ibmcpp${SL}include -Is:${SL}toolkt21${SL}c${SL}os2h +# This says we are building an object file, not a full executable. +OBJ_CFLAGS = -C+ +CFLAGS = -W3 -Wpro+rea+tru+use+ -Ti+ -Ss+ -Gd+ -Gm+ -G4 -Q+ -Sm ${CINC} \ + -I${srcdir} -I${lib_dir} -I${cvs_srcdir} \ + -DIBM_CPP -DHAVE_CONFIG_H \ + -DTCPIP_IBM -Is:${SL}ibmtcpip${SL}include + +# needed to make command-line wildcard expansion work right. That's +# right, DOS-descendants handle this from the program, not the shell. +ARGVLIB = s:${SL}ibmcpp${SL}lib${SL}setargv.obj + +# TCP/IP stuff +TCPIPLIB = s:${SL}ibmtcpip${SL}lib${SL}tcp32dll.lib s:${SL}ibmtcpip${SL}lib${SL}so32dll.lib + + +# headers specific to OS/2 + +# We list OS2_HEADERS so we know what to include when we make dist-dir +# here. +OS2_HEADERS = \ + ${srcdir}${SL}tcpip.h \ + ${srcdir}${SL}config.h \ + ${srcdir}${SL}options.h \ + ${srcdir}${SL}pwd.h \ + ${srcdir}${SL}dirent.h \ + ${srcdir}${SL}rcmd.h \ + ${srcdir}${SL}popen.h + +# headers we use from the common src dir, ..${SL}src +COMMON_HEADERS = \ + ${cvs_srcdir}${SL}client.h \ + ${cvs_srcdir}${SL}cvs.h \ + ${cvs_srcdir}${SL}rcs.h \ + ${cvs_srcdir}${SL}hash.h \ + ${cvs_srcdir}${SL}myndbm.h \ + ${cvs_srcdir}${SL}patchlevel.h \ + ${cvs_srcdir}${SL}update.h \ + ${cvs_srcdir}${SL}server.h \ + ${cvs_srcdir}${SL}error.h + +# sources specific to OS/2 +OS2_SOURCES = \ + ${srcdir}${SL}mkdir.c \ + ${srcdir}${SL}pwd.c \ + ${srcdir}${SL}filesubr.c \ + ${srcdir}${SL}dirent.c \ + ${srcdir}${SL}run.c \ + ${srcdir}${SL}stripslash.c \ + ${srcdir}${SL}rcmd.c \ + ${srcdir}${SL}waitpid.c \ + ${srcdir}${SL}popen.c \ + ${srcdir}${SL}porttcp.c \ + ${srcdir}${SL}strippath.c \ + ${srcdir}${SL}getdate.c \ + ${srcdir}${SL}getpass.c + +# sources we use from the common src dir, ..${SL}src +COMMON_SOURCES = \ + ${cvs_srcdir}${SL}add.c \ + ${cvs_srcdir}${SL}admin.c \ + ${cvs_srcdir}${SL}checkin.c \ + ${cvs_srcdir}${SL}checkout.c \ + ${cvs_srcdir}${SL}classify.c \ + ${cvs_srcdir}${SL}client.c \ + ${cvs_srcdir}${SL}commit.c \ + ${cvs_srcdir}${SL}create_adm.c \ + ${cvs_srcdir}${SL}cvsrc.c \ + ${cvs_srcdir}${SL}diff.c \ + ${cvs_srcdir}${SL}edit.c \ + ${cvs_srcdir}${SL}entries.c \ + ${cvs_srcdir}${SL}error.c \ + ${cvs_srcdir}${SL}expand_path.c \ + ${cvs_srcdir}${SL}fileattr.c \ + ${cvs_srcdir}${SL}find_names.c \ + ${cvs_srcdir}${SL}hash.c \ + ${cvs_srcdir}${SL}history.c \ + ${cvs_srcdir}${SL}ignore.c \ + ${cvs_srcdir}${SL}import.c \ + ${cvs_srcdir}${SL}lock.c \ + ${cvs_srcdir}${SL}log.c \ + ${cvs_srcdir}${SL}login.c \ + ${cvs_srcdir}${SL}logmsg.c \ + ${cvs_srcdir}${SL}main.c \ + ${cvs_srcdir}${SL}modules.c \ + ${cvs_srcdir}${SL}myndbm.c \ + ${cvs_srcdir}${SL}no_diff.c \ + ${cvs_srcdir}${SL}parseinfo.c \ + ${cvs_srcdir}${SL}patch.c \ + ${cvs_srcdir}${SL}rcs.c \ + ${cvs_srcdir}${SL}rcscmds.c \ + ${cvs_srcdir}${SL}recurse.c \ + ${cvs_srcdir}${SL}release.c \ + ${cvs_srcdir}${SL}remove.c \ + ${cvs_srcdir}${SL}repos.c \ + ${cvs_srcdir}${SL}root.c \ + ${cvs_srcdir}${SL}rtag.c \ + ${cvs_srcdir}${SL}scramble.c \ + ${cvs_srcdir}${SL}server.c \ + ${cvs_srcdir}${SL}status.c \ + ${cvs_srcdir}${SL}subr.c \ + ${cvs_srcdir}${SL}tag.c \ + ${cvs_srcdir}${SL}update.c \ + ${cvs_srcdir}${SL}watch.c \ + ${cvs_srcdir}${SL}wrapper.c \ + ${cvs_srcdir}${SL}vers_ts.c \ + ${cvs_srcdir}${SL}version.c +# end of $COMMON_SOURCES + +# sources from ..${SL}lib +LIB_SOURCES = \ + ${lib_dir}${SL}getopt.c \ + ${lib_dir}${SL}getopt1.c \ + ${lib_dir}${SL}getline.c \ + ${lib_dir}${SL}getwd.c \ + ${lib_dir}${SL}save-cwd.c \ + ${lib_dir}${SL}sighandle.c \ + ${lib_dir}${SL}yesno.c \ + ${lib_dir}${SL}xgetwd.c \ + ${lib_dir}${SL}md5.c \ + ${lib_dir}${SL}fnmatch.c \ + ${lib_dir}${SL}regex.c + +# object files from OS/2 sources +OS2_OBJECTS = \ + ${srcdir}${SL}mkdir.obj \ + ${srcdir}${SL}pwd.obj \ + ${srcdir}${SL}filesubr.obj \ + ${srcdir}${SL}dirent.obj \ + ${srcdir}${SL}run.obj \ + ${srcdir}${SL}stripslash.obj \ + ${srcdir}${SL}rcmd.obj \ + ${srcdir}${SL}waitpid.obj \ + ${srcdir}${SL}popen.obj \ + ${srcdir}${SL}porttcp.obj \ + ${srcdir}${SL}strippath.obj \ + ${srcdir}${SL}getdate.obj \ + ${srcdir}${SL}getpass.obj + +# object files from ..${SL}src +COMMON_OBJECTS = \ + ${cvs_srcdir}${SL}add.obj \ + ${cvs_srcdir}${SL}admin.obj \ + ${cvs_srcdir}${SL}checkin.obj \ + ${cvs_srcdir}${SL}checkout.obj \ + ${cvs_srcdir}${SL}classify.obj \ + ${cvs_srcdir}${SL}client.obj \ + ${cvs_srcdir}${SL}commit.obj \ + ${cvs_srcdir}${SL}create_adm.obj \ + ${cvs_srcdir}${SL}cvsrc.obj \ + ${cvs_srcdir}${SL}diff.obj \ + ${cvs_srcdir}${SL}edit.obj \ + ${cvs_srcdir}${SL}entries.obj \ + ${cvs_srcdir}${SL}error.obj \ + ${cvs_srcdir}${SL}expand_path.obj \ + ${cvs_srcdir}${SL}fileattr.obj \ + ${cvs_srcdir}${SL}find_names.obj \ + ${cvs_srcdir}${SL}hash.obj \ + ${cvs_srcdir}${SL}history.obj \ + ${cvs_srcdir}${SL}ignore.obj \ + ${cvs_srcdir}${SL}import.obj \ + ${cvs_srcdir}${SL}lock.obj \ + ${cvs_srcdir}${SL}log.obj \ + ${cvs_srcdir}${SL}login.obj \ + ${cvs_srcdir}${SL}logmsg.obj \ + ${cvs_srcdir}${SL}main.obj \ + ${cvs_srcdir}${SL}modules.obj \ + ${cvs_srcdir}${SL}myndbm.obj \ + ${cvs_srcdir}${SL}no_diff.obj \ + ${cvs_srcdir}${SL}parseinfo.obj \ + ${cvs_srcdir}${SL}patch.obj \ + ${cvs_srcdir}${SL}rcs.obj \ + ${cvs_srcdir}${SL}rcscmds.obj \ + ${cvs_srcdir}${SL}recurse.obj \ + ${cvs_srcdir}${SL}release.obj \ + ${cvs_srcdir}${SL}remove.obj \ + ${cvs_srcdir}${SL}repos.obj \ + ${cvs_srcdir}${SL}root.obj \ + ${cvs_srcdir}${SL}rtag.obj \ + ${cvs_srcdir}${SL}scramble.obj \ + ${cvs_srcdir}${SL}server.obj \ + ${cvs_srcdir}${SL}status.obj \ + ${cvs_srcdir}${SL}subr.obj \ + ${cvs_srcdir}${SL}tag.obj \ + ${cvs_srcdir}${SL}update.obj \ + ${cvs_srcdir}${SL}watch.obj \ + ${cvs_srcdir}${SL}wrapper.obj \ + ${cvs_srcdir}${SL}vers_ts.obj \ + ${cvs_srcdir}${SL}version.obj +# end of $COMMON_OBJECTS + +# objects from ..${SL}lib +LIB_OBJECTS = \ + ${lib_dir}${SL}getopt.obj \ + ${lib_dir}${SL}getopt1.obj \ + ${lib_dir}${SL}getline.obj \ + ${lib_dir}${SL}getwd.obj \ + ${lib_dir}${SL}save-cwd.obj \ + ${lib_dir}${SL}sighandle.obj \ + ${lib_dir}${SL}yesno.obj \ + ${lib_dir}${SL}xgetwd.obj \ + ${lib_dir}${SL}md5.obj \ + ${lib_dir}${SL}fnmatch.obj \ + ${lib_dir}${SL}regex.obj + +SOURCES = ${COMMON_SOURCES} ${LIB_SOURCES} ${OS2_SOURCES} +HEADERS = ${COMMON_HEADERS} ${OS2_HEADERS} +OBJECTS = ${COMMON_OBJECTS} ${LIB_OBJECTS} ${OS2_OBJECTS} + +DISTFILES = ${OS2_HEADERS} ${OS2_SOURCES} \ + ${srcdir}${SL}README ${srcdir}${SL}ChangeLog \ + ${srcdir}${SL}Makefile.in ${srcdir}${SL}.cvsignore \ + ${srcdir}${SL}test-makefile Makefile + +all: + +.PHONY: all install uninstall +all install uninstall: + +.PHONY: tags TAGS +tags TAGS: + +.PHONY: ls +ls: + @echo ${DISTFILES} + +.PHONY: clean distclean realclean mostlyclean +clean distclean realclean mostlyclean: + +.PHONY: lint +lint: + +.PHONY: dist-dir +dist-dir: + mkdir ${DISTDIR} + for i in ${DISTFILES}; do \ + ln $${i} ${DISTDIR}; \ + done + +# We don't have a real distclean or anything like that, but at least +# we can get rid of the obj files and cvs.exe. +clean: + rm -f cvs.exe + rm -f ${srcdir}${SL}*.obj + rm -f ${lib_dir}${SL}*.obj + rm -f ${cvs_srcdir}${SL}*.obj + +install-cvs: cvs.exe + cp ${srcdir}${SL}cvs.exe ${install_dir}${SL}cvs.exe + +%.obj: %.c + icc ${OBJ_CFLAGS} ${CFLAGS} /Fo$@ $*.c + +# There seems to be no ICC option for specifying library locations, so +# we must `set' the path in the compilation environment. Urgkle. +cvs.exe: ${OBJECTS} + echo Creating icc.in... + echo -Q+ -Ti+ -Fe$@ -B"/batch" -B"/NOE" > icc.in + echo ${OS2_OBJECTS} >> icc.in + echo ${LIB_OBJECTS} >> icc.in + echo ${COMMON_OBJECTS} >> icc.in + echo ${TCPIPLIB} >> icc.in + echo ${ARGVLIB} >> icc.in + echo Creating icc.in... done. + set LIB=${LIB} & icc @icc.in + +# cvs.obj: ${OBJECTS} ${SOURCES} ${HEADERS} + +subdir = os2 +Makefile: ../config.status $(srcdir)/Makefile.in + cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status diff --git a/gnu/usr.bin/cvs/os2/README b/gnu/usr.bin/cvs/os2/README new file mode 100644 index 00000000000..50ed61625fd --- /dev/null +++ b/gnu/usr.bin/cvs/os2/README @@ -0,0 +1,31 @@ + This port requires IBM C/C++ and the IBM TCPIP library. +You'll need to edit the makefile to reflect your system's paths +(unless you're our customer for this port, in which case the paths +are correct because we did the port on your machine. :-) ). + + I'm having some weird problem with "\" vs. "/". If I build +with "\" as the path separator in the makefile, the compiler dumps +core. Go figure. If I build with "/" as the path separator, the +object files compile fine but the linker thinks the "/" is indicating +options and gets all confused (though at least it doesn't dump core). + + Right now the solution is to have a makefile variable called +SL, which must be set to "/" for the first invocation of make and "\" +for the second (the first pass will successfully build the object +files, but you can expect it do die with "unknown options" errors at +link time). + + $SL is defined near the top of the makefile. If you're going +to set $SL in the makefile itself, make sure to quote it ("\\"). On +the command line (i.e., "make SL=\"), I believe just one will do. + + That should be all -- edit the makefile, do "make" twice +(changing $SL the second time), and get os2\cvs.exe. Assuming you +have edited the `install_dir' variable in the Makefile, you may type +"make install-cvs" to put cvs.exe in the right place. + + You will get warnings during the compilation; ignore them. +Report bugs to <bug-cvs@prep.ai.mit.edu>. + +-Karl + <kfogel@cyclic.com> diff --git a/gnu/usr.bin/cvs/os2/dirent.c b/gnu/usr.bin/cvs/os2/dirent.c new file mode 100644 index 00000000000..01bd92f56e7 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/dirent.c @@ -0,0 +1,180 @@ +/* + * Author: Bob Withers + * Copyright (c) 1993, All Rights Reserved + * + * NOTICE + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * The author makes no representations about the suitability of this + * software for any purpose. This software is provided ``as is'' + * without express or implied warranty. + */ + +#include <stdlib.h> +#include <string.h> + +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#include <os2.h> + +#include "dirent.h" + + +#define DIRENT_INCR 25 + + +DIR *opendir(char *filename) +{ + auto size_t len; + auto DIR *dirp; + auto char *p; + auto HDIR hdir; + +#ifdef OS2_16 + auto USHORT rc; /* for 16 bit OS/2 */ + auto FILEFINDBUF ff; + auto USHORT cnt; +#else + auto APIRET rc; /* for 32 bit OS/2 */ + auto FILEFINDBUF3 ff; + auto ULONG cnt; +#endif /* OS2_16 */ + + if (NULL == filename || '\0' == filename[0]) + filename = "."; + + dirp = malloc(sizeof(*dirp)); + if (NULL == dirp) + return(NULL); + + len = strlen(filename); + dirp->dirname = malloc(len + 5); + if (NULL == dirp->dirname) + { + free(dirp); + return(NULL); + } + + dirp->max_ent = 0; + dirp->tot_ent = 0; + dirp->cur_ent = 0; + dirp->entp = NULL; + strcpy(dirp->dirname, filename); + for (p = dirp->dirname; *p; ++p) + { + if ('/' == *p) + *p = '\\'; + } + + if ('\\' != dirp->dirname[len - 1]) + strcat(dirp->dirname, "\\"); + + strcat(dirp->dirname, "*.*"); + + hdir = HDIR_SYSTEM; + cnt = 1; + rc = DosFindFirst(dirp->dirname, &hdir, + FILE_NORMAL | FILE_READONLY | FILE_HIDDEN | + FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED, + &ff, sizeof(ff), &cnt, FIL_STANDARD); + + while (NO_ERROR == rc) + { + auto struct dirent *entp; + + if (dirp->tot_ent >= dirp->max_ent) + { + auto struct dirent **p; + + dirp->max_ent += DIRENT_INCR; + p = realloc(dirp->entp, dirp->max_ent * sizeof(entp)); + if (NULL == p) + { + rc = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + dirp->entp = p; + } + + entp = malloc(sizeof(*entp) + (size_t) ff.cchName); + if (NULL == entp) + { + rc = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + entp->d_ino = 0; + entp->d_off = dirp->tot_ent; + entp->d_namlen = (unsigned short) ff.cchName; + memcpy(entp->d_name, ff.achName, entp->d_namlen); + entp->d_name[entp->d_namlen] = '\0'; + dirp->entp[dirp->tot_ent++] = entp; + + cnt = 1; + rc = DosFindNext(hdir, &ff, sizeof(ff), &cnt); + } + + DosFindClose(hdir); + if (ERROR_NO_MORE_FILES == rc) + return(dirp); + + closedir(dirp); + return(NULL); +} + + +struct dirent *readdir(DIR *dirp) +{ + if (dirp->cur_ent < 0 || dirp->cur_ent >= dirp->tot_ent) + return(NULL); + + return(dirp->entp[dirp->cur_ent++]); +} + + +long telldir(DIR *dirp) +{ + return((long) dirp->cur_ent); +} + + +void seekdir(DIR *dirp, long loc) +{ + dirp->cur_ent = (int) loc; + return; +} + + +void rewinddir(DIR *dirp) +{ + dirp->cur_ent = 0; + return; +} + + +void closedir(DIR *dirp) +{ + if (dirp) + { + if (dirp->dirname) + free(dirp->dirname); + + if (dirp->entp) + { + register int i; + + for (i = 0; i < dirp->tot_ent; ++i) + free(dirp->entp[i]); + + free(dirp->entp); + } + } + + return; +} diff --git a/gnu/usr.bin/cvs/os2/dirent.h b/gnu/usr.bin/cvs/os2/dirent.h new file mode 100644 index 00000000000..bc218b5fdc6 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/dirent.h @@ -0,0 +1,50 @@ +/* + * Author: Bob Withers + * Copyright (c) 1993, All Rights Reserved + * + * NOTICE + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * The author makes no representations about the suitability of this + * software for any purpose. This software is provided ``as is'' + * without express or implied warranty. + */ + +#ifndef DIRENT_H +#define DIRENT_H + +/* Unix style directory(3C) support for OS/2 V2.x */ + +struct dirent +{ + long d_ino; /* not used in this implementation */ + long d_off; /* not used in this implementation */ + unsigned short d_namlen; + char d_name[1]; +}; + + +struct S_Dir +{ + char *dirname; + int max_ent; + int tot_ent; + int cur_ent; + struct dirent **entp; +}; +typedef struct S_Dir DIR; + + +DIR * opendir(char *filename); +struct dirent * readdir(DIR *dirp); +long telldir(DIR *dirp); +void seekdir(DIR *dirp, long loc); +void rewinddir(DIR *dirp); +void closedir(DIR *dirp); + +#endif /* DIRENT_H */ diff --git a/gnu/usr.bin/cvs/os2/filesubr.c b/gnu/usr.bin/cvs/os2/filesubr.c new file mode 100644 index 00000000000..849915afa3a --- /dev/null +++ b/gnu/usr.bin/cvs/os2/filesubr.c @@ -0,0 +1,737 @@ +/* filesubr.c --- subroutines for dealing with files under OS/2 + Jim Blandy <jimb@cyclic.com> and Karl Fogel <kfogel@cyclic.com> + + This file is part of GNU CVS. + + GNU CVS is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* These functions were moved out of subr.c because they need different + definitions under operating systems (like, say, Windows NT) with different + file system semantics. */ + +#include <io.h> + +#include "cvs.h" + +#ifndef lint +static const char rcsid[] = "$CVSid:$"; +USE(rcsid); +#endif + +/* + * I don't know of a convenient way to test this at configure time, or else + * I'd certainly do it there. -JimB + */ +#if defined(NeXT) +#define LOSING_TMPNAM_FUNCTION +#endif + +static int deep_remove_dir PROTO((const char *path)); + +/* + * Copies "from" to "to". + */ +void +copy_file (from, to) + const char *from; + const char *to; +{ + struct stat sb; + struct utimbuf t; + int fdin, fdout; + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> copy(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); +#endif + if (noexec) + return; + + if ((fdin = open (from, O_RDONLY | O_BINARY)) < 0) + error (1, errno, "cannot open %s for copying", from); + if (fstat (fdin, &sb) < 0) + error (1, errno, "cannot fstat %s", from); + if ((fdout = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, + (int) sb.st_mode & 07777)) < 0) + error (1, errno, "cannot create %s for copying", to); + if (sb.st_size > 0) + { + char buf[BUFSIZ]; + int n; + + for (;;) + { + n = read (fdin, buf, sizeof(buf)); + if (n == -1) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + error (1, errno, "cannot read file %s for copying", from); + } + else if (n == 0) + break; + + if (write(fdout, buf, n) != n) { + error (1, errno, "cannot write file %s for copying", to); + } + } + +#ifdef HAVE_FSYNC + if (fsync (fdout)) + error (1, errno, "cannot fsync file %s after copying", to); +#endif + } + + if (close (fdin) < 0) + error (0, errno, "cannot close %s", from); + if (close (fdout) < 0) + error (1, errno, "cannot close %s", to); + + /* now, set the times for the copied file to match those of the original */ + memset ((char *) &t, 0, sizeof (t)); + t.actime = sb.st_atime; + t.modtime = sb.st_mtime; + (void) utime (to, &t); +} + +/* + * link a file, if possible. Warning: the Windows NT version of this + * function just copies the file, so only use this function in ways + * that can deal with either a link or a copy. + */ +int +link_file (from, to) + const char *from; + const char *to; +{ + copy_file (from, to); + return 0; +} + +/* FIXME-krp: these functions would benefit from caching the char * & + stat buf. */ + +/* + * Returns non-zero if the argument file is a directory, or is a symbolic + * link which points to a directory. + */ +int +isdir (file) + const char *file; +{ + struct stat sb; + + if (stat (file, &sb) < 0) + return (0); + return (S_ISDIR (sb.st_mode)); +} + +/* + * Returns non-zero if the argument file is a symbolic link. + */ +int +islink (file) + const char *file; +{ +#ifdef S_ISLNK + struct stat sb; + + if (lstat (file, &sb) < 0) + return (0); + return (S_ISLNK (sb.st_mode)); +#else + return (0); +#endif +} + +/* + * Returns non-zero if the argument file exists. + */ +int +isfile (file) + const char *file; +{ + struct stat sb; + + if (stat (file, &sb) < 0) + return (0); + return (1); +} + +/* + * Returns non-zero if the argument file is readable. + * XXX - must be careful if "cvs" is ever made setuid! + */ +int +isreadable (file) + const char *file; +{ + return (access (file, R_OK) != -1); +} + +/* + * Returns non-zero if the argument file is writable + * XXX - muct be careful if "cvs" is ever made setuid! + */ +int +iswritable (file) + const char *file; +{ + return (access (file, W_OK) != -1); +} + +/* + * Returns non-zero if the argument file is accessable according to + * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid + * bits set. + */ +int +isaccessible (file, mode) + const char *file; + const int mode; +{ + return access(file, mode) == 0; +} + + +/* + * Open a file and die if it fails + */ +FILE * +open_file (name, mode) + const char *name; + const char *mode; +{ + FILE *fp; + + if ((fp = fopen (name, mode)) == NULL) + error (1, errno, "cannot open %s", name); + return (fp); +} + +/* + * Make a directory and die if it fails + */ +void +make_directory (name) + const char *name; +{ + struct stat buf; + + if (stat (name, &buf) == 0 && (!S_ISDIR (buf.st_mode))) + error (0, 0, "%s already exists but is not a directory", name); + if (!noexec && mkdir (name) < 0) + error (1, errno, "cannot make directory %s", name); +} + +/* + * Make a path to the argument directory, printing a message if something + * goes wrong. + */ +void +make_directories (name) + const char *name; +{ + char *cp; + + if (noexec) + return; + + if (mkdir (name) == 0 || errno == EACCESS) + return; + if (! existence_error (errno)) + { + error (0, errno, "cannot make path to %s", name); + return; + } + if ((cp = strrchr (name, '/')) == NULL) + return; + *cp = '\0'; + make_directories (name); + *cp++ = '/'; + if (*cp == '\0') + return; + (void) mkdir (name); +} + +/* + * Change the mode of a file, either adding write permissions, or removing + * all write permissions. Adding write permissions honors the current umask + * setting. + */ +void +xchmod (fname, writable) + char *fname; + int writable; +{ + char *attrib_cmd; + char *attrib_option; + char *whole_cmd; + char *p; + char *q; + + if (!isfile (fname)) + return ENOENT; + + attrib_cmd = "attrib "; /* No, really? */ + + if (writable) + attrib_option = "-r "; /* make writeable */ + else + attrib_option = "+r "; /* make read-only */ + + whole_cmd = xmalloc (strlen (attrib_cmd) + + strlen (attrib_option) + + strlen (fname) + + 1); + + strcpy (whole_cmd, attrib_cmd); + strcat (whole_cmd, attrib_option); + + /* Copy fname to the end of whole_cmd, translating / to \. + Attrib doesn't take / but many parts of CVS rely + on being able to use it. */ + p = whole_cmd + strlen (whole_cmd); + q = fname; + while (*q) + { + if (*q == '/') + *p++ = '\\'; + else + *p++ = *q; + ++q; + } + *p = '\0'; + + system (whole_cmd); + free (whole_cmd); +} + + +/* Read the value of a symbolic link. + Under OS/2, this function always returns EINVAL. */ +int +readlink (char *path, char *buf, int buf_size) +{ + errno = EINVAL; + return -1; +} + +/* + * unlink a file, if possible. + */ +int +unlink_file (f) + const char *f; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> unlink(%s)\n", + (server_active) ? 'S' : ' ', f); +#else + (void) fprintf (stderr, "-> unlink(%s)\n", f); +#endif + if (noexec) + return (0); + + /* Win32 unlink is stupid - it fails if the file is read-only. + * OS/2 is similarly stupid. It does have a remove() function, + * but the documentation does not make clear why remove() is or + * isn't preferable to unlink(). I'll use unlink() because the + * name is closer to our interface, what the heck. Also, we know + * unlink()'s error code when trying to remove a directory. + */ + xchmod (f, 1); + return (unlink (f)); +} + +/* + * Unlink a file or dir, if possible. If it is a directory do a deep + * removal of all of the files in the directory. Return -1 on error + * (in which case errno is set). + */ +int +unlink_file_dir (f) + const char *f; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", + (server_active) ? 'S' : ' ', f); +#else + (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); +#endif + if (noexec) + return (0); + + if (unlink_file (f) != 0) + { + /* under OS/2, unlink returns EACCESS if the path + is a directory. */ + if (errno == EACCESS) + return deep_remove_dir (f); + else + /* The file wasn't a directory and some other + * error occured + */ + return -1; + } + /* We were able to remove the file from the disk */ + return 0; +} + +/* Remove a directory and everything it contains. Returns 0 for + * success, -1 for failure (in which case errno is set). + */ + +static int +deep_remove_dir (path) + const char *path; +{ + DIR *dirp; + struct dirent *dp; + char buf[PATH_MAX]; + + if ( rmdir (path) != 0 && errno == EACCESS ) + { + if ((dirp = opendir (path)) == NULL) + /* If unable to open the directory return + * an error + */ + return -1; + + while ((dp = readdir (dirp)) != NULL) + { + if (strcmp (dp->d_name, ".") == 0 || + strcmp (dp->d_name, "..") == 0) + continue; + + sprintf (buf, "%s/%s", path, dp->d_name); + + if (unlink_file (buf) != 0 ) + { + if (errno == EACCES) + { + if (deep_remove_dir (buf)) + { + closedir (dirp); + return -1; + } + } + else + { + /* buf isn't a directory, or there are + * some sort of permision problems + */ + closedir (dirp); + return -1; + } + } + } + closedir (dirp); + return rmdir (path); + } + /* Was able to remove the directory return 0 */ + return 0; +} + + +/* + * Rename a file and die if it fails + */ +void +rename_file (from, to) + const char *from; + const char *to; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> rename(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); +#endif + if (noexec) + return; + + unlink_file (to); + if (rename (from, to) != 0) + error (1, errno, "cannot rename file %s to %s", from, to); +} + + +/* Read NCHARS bytes from descriptor FD into BUF. + Return the number of characters successfully read. + The number returned is always NCHARS unless end-of-file or error. */ +static size_t +block_read (fd, buf, nchars) + int fd; + char *buf; + size_t nchars; +{ + char *bp = buf; + size_t nread; + + do + { + nread = read (fd, bp, nchars); + if (nread == (size_t)-1) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + return (size_t)-1; + } + + if (nread == 0) + break; + + bp += nread; + nchars -= nread; + } while (nchars != 0); + + return bp - buf; +} + + +/* + * Compare "file1" to "file2". Return non-zero if they don't compare exactly. + */ +int +xcmp (file1, file2) + const char *file1; + const char *file2; +{ + char *buf1, *buf2; + struct stat sb1, sb2; + int fd1, fd2; + int ret; + + if ((fd1 = open (file1, O_RDONLY | O_BINARY)) < 0) + error (1, errno, "cannot open file %s for comparing", file1); + if ((fd2 = open (file2, O_RDONLY | O_BINARY)) < 0) + error (1, errno, "cannot open file %s for comparing", file2); + if (fstat (fd1, &sb1) < 0) + error (1, errno, "cannot fstat %s", file1); + if (fstat (fd2, &sb2) < 0) + error (1, errno, "cannot fstat %s", file2); + + /* A generic file compare routine might compare st_dev & st_ino here + to see if the two files being compared are actually the same file. + But that won't happen in CVS, so we won't bother. */ + + if (sb1.st_size != sb2.st_size) + ret = 1; + else if (sb1.st_size == 0) + ret = 0; + else + { + /* FIXME: compute the optimal buffer size by computing the least + common multiple of the files st_blocks field */ + size_t buf_size = 8 * 1024; + size_t read1; + size_t read2; + + buf1 = xmalloc (buf_size); + buf2 = xmalloc (buf_size); + + do + { + read1 = block_read (fd1, buf1, buf_size); + if (read1 == (size_t)-1) + error (1, errno, "cannot read file %s for comparing", file1); + + read2 = block_read (fd2, buf2, buf_size); + if (read2 == (size_t)-1) + error (1, errno, "cannot read file %s for comparing", file2); + + /* assert (read1 == read2); */ + + ret = memcmp(buf1, buf2, read1); + } while (ret == 0 && read1 == buf_size); + + free (buf1); + free (buf2); + } + + (void) close (fd1); + (void) close (fd2); + return (ret); +} + + +/* The equivalence class mapping for filenames. + OS/2 filenames are case-insensitive, but case-preserving. Both / + and \ are path element separators. + Thus, this table maps both upper and lower case to lower case, and + both / and \ to /. + + Much thanks to Jim Blandy, who already invented this wheel in the + Windows NT port. */ + +#if 0 +main () +{ + int c; + + for (c = 0; c < 256; c++) + { + int t; + + if (c == '\\') + t = '/'; + else + t = tolower (c); + + if ((c & 0x7) == 0x0) + printf (" "); + printf ("0x%02x,", t); + if ((c & 0x7) == 0x7) + putchar ('\n'); + else if ((c & 0x7) == 0x3) + putchar (' '); + } +} +#endif + + +unsigned char +OS2_filename_classes[] = +{ + 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, + 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f, + 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, + 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, + 0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f, + 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, + 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, + 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, + 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f, + 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf, + 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7, + 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf, + 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7, + 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7, + 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf, + 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7, + 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef, + 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, +}; + +/* Like strcmp, but with the appropriate tweaks for file names. + Under OS/2, filenames are case-insensitive but case-preserving, and + both \ and / are path element separators. */ +int +fncmp (const char *n1, const char *n2) +{ + while (*n1 && *n2 + && (OS2_filename_classes[(unsigned char) *n1] + == OS2_filename_classes[(unsigned char) *n2])) + n1++, n2++; + return (OS2_filename_classes[(unsigned char) *n1] + - OS2_filename_classes[(unsigned char) *n1]); +} + +/* Fold characters in FILENAME to their canonical forms. + If FOLD_FN_CHAR is not #defined, the system provides a default + definition for this. */ +void +fnfold (char *filename) +{ + while (*filename) + { + *filename = FOLD_FN_CHAR (*filename); + filename++; + } +} + + +/* Return non-zero iff FILENAME is absolute. + Trivial under Unix, but more complicated under other systems. */ +int +isabsolute (filename) + const char *filename; +{ + return (ISDIRSEP (filename[0]) + || (filename[0] != '\0' + && filename[1] == ':' + && ISDIRSEP (filename[2]))); +} + +/* Return a pointer into PATH's last component. */ +char * +last_component (char *path) +{ + char *scan; + char *last = 0; + + for (scan = path; *scan; scan++) + if (ISDIRSEP (*scan)) + last = scan; + + if (last) + return last + 1; + else + return path; +} + + +/* Read data from INFILE, and copy it to OUTFILE. + Open INFILE using INFLAGS, and OUTFILE using OUTFLAGS. + This is useful for converting between CRLF and LF line formats. */ +void +convert_file (char *infile, int inflags, + char *outfile, int outflags) +{ + int infd, outfd; + char buf[8192]; + int len; + + if ((infd = open (infile, inflags, S_IREAD | S_IWRITE)) < 0) + error (1, errno, "couldn't read %s", infile); + if ((outfd = open (outfile, outflags, S_IREAD | S_IWRITE)) < 0) + error (1, errno, "couldn't write %s", outfile); + + while ((len = read (infd, buf, sizeof (buf))) > 0) + if (write (outfd, buf, len) < 0) + error (1, errno, "error writing %s", outfile); + if (len < 0) + error (1, errno, "error reading %s", infile); + + if (close (outfd) < 0) + error (0, errno, "warning: couldn't close %s", outfile); + if (close (infd) < 0) + error (0, errno, "warning: couldn't close %s", infile); +} diff --git a/gnu/usr.bin/cvs/os2/getdate.c b/gnu/usr.bin/cvs/os2/getdate.c new file mode 100644 index 00000000000..dcfcdf39e9c --- /dev/null +++ b/gnu/usr.bin/cvs/os2/getdate.c @@ -0,0 +1,1578 @@ +/* stolen from lib/getdate.c */ + +#include "config.h" +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> + +/* The code at the top of get_date which figures out the offset of the + current time zone checks various CPP symbols to see if special + tricks are need, but defaults to using the gettimeofday system call. + Include <sys/time.h> if that will be used. */ + +#if defined(vms) + +#include <types.h> +#include <time.h> + +#else + +#include <sys/types.h> + +#ifdef TIME_WITH_SYS_TIME +#include <sys/time.h> +#include <time.h> +#else +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#else +#include <time.h> +#endif +#endif + +#ifdef timezone +#undef timezone /* needed for sgi */ +#endif + +#if defined(HAVE_SYS_TIMEB_H) +#include <sys/timeb.h> +#else +/* +** We use the obsolete `struct timeb' as part of our interface! +** Since the system doesn't have it, we define it here; +** our callers must do likewise. +*/ +struct timeb { + time_t time; /* Seconds since the epoch */ + unsigned short millitm; /* Field not used */ + short timezone; /* Minutes west of GMT */ + short dstflag; /* Field not used */ +}; +#endif /* defined(HAVE_SYS_TIMEB_H) */ + +#endif /* defined(vms) */ + +#if defined (STDC_HEADERS) || defined (USG) +#include <string.h> +#endif + +/* Some old versions of bison generate parsers that use bcopy. + That loses on systems that don't provide the function, so we have + to redefine it here. */ +#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy) +#define bcopy(from, to, len) memcpy ((to), (from), (len)) +#endif + +#if defined (STDC_HEADERS) +#include <stdlib.h> +#endif + +#if defined (HAVE_ALLOCA_H) +#include <alloca.h> +#endif + +extern struct tm *gmtime(); +extern struct tm *localtime(); + +#define yyparse getdate_yyparse +#define yylex getdate_yylex +#define yyerror getdate_yyerror + +#if !defined(lint) && !defined(SABER) +static char RCS[] = "$CVSid: @(#)getdate.y 1.11 94/09/21 $"; +#endif /* !defined(lint) && !defined(SABER) */ + +static int yylex (); +static int yyerror (); + +#define EPOCH 1970 +#define HOUR(x) ((time_t)(x) * 60) +#define SECSPERDAY (24L * 60L * 60L) + + +/* +** An entry in the lexical lookup table. +*/ +typedef struct _TABLE { + char *name; + int type; + time_t value; +} TABLE; + + +/* +** Daylight-savings mode: on, off, or not yet known. +*/ +typedef enum _DSTMODE { + DSTon, DSToff, DSTmaybe +} DSTMODE; + +/* +** Meridian: am, pm, or 24-hour style. +*/ +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; + + +/* +** Global variables. We could get rid of most of these by using a good +** union as the yacc stack. (This routine was originally written before +** yacc had the %union construct.) Maybe someday; right now we only use +** the %union very rarely. +*/ +static char *yyInput; +static DSTMODE yyDSTmode; +static time_t yyDayOrdinal; +static time_t yyDayNumber; +static int yyHaveDate; +static int yyHaveDay; +static int yyHaveRel; +static int yyHaveTime; +static int yyHaveZone; +static time_t yyTimezone; +static time_t yyDay; +static time_t yyHour; +static time_t yyMinutes; +static time_t yyMonth; +static time_t yySeconds; +static time_t yyYear; +static MERIDIAN yyMeridian; +static time_t yyRelMonth; +static time_t yyRelSeconds; + + +typedef union { + time_t Number; + enum _MERIDIAN Meridian; +} YYSTYPE; +# define tAGO 257 +# define tDAY 258 +# define tDAYZONE 259 +# define tID 260 +# define tMERIDIAN 261 +# define tMINUTE_UNIT 262 +# define tMONTH 263 +# define tMONTH_UNIT 264 +# define tSEC_UNIT 265 +# define tSNUMBER 266 +# define tUNUMBER 267 +# define tZONE 268 +# define tDST 269 +#define yyclearin yychar = -1 +#define yyerrok yyerrflag = 0 +extern int yychar; +extern int yyerrflag; +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 150 +#endif +YYSTYPE yylval, yyval; +# define YYERRCODE 256 + + + +/* Month and day table. */ +static TABLE const MonthDayTable[] = { + { "january", tMONTH, 1 }, + { "february", tMONTH, 2 }, + { "march", tMONTH, 3 }, + { "april", tMONTH, 4 }, + { "may", tMONTH, 5 }, + { "june", tMONTH, 6 }, + { "july", tMONTH, 7 }, + { "august", tMONTH, 8 }, + { "september", tMONTH, 9 }, + { "sept", tMONTH, 9 }, + { "october", tMONTH, 10 }, + { "november", tMONTH, 11 }, + { "december", tMONTH, 12 }, + { "sunday", tDAY, 0 }, + { "monday", tDAY, 1 }, + { "tuesday", tDAY, 2 }, + { "tues", tDAY, 2 }, + { "wednesday", tDAY, 3 }, + { "wednes", tDAY, 3 }, + { "thursday", tDAY, 4 }, + { "thur", tDAY, 4 }, + { "thurs", tDAY, 4 }, + { "friday", tDAY, 5 }, + { "saturday", tDAY, 6 }, + { NULL } +}; + +/* Time units table. */ +static TABLE const UnitsTable[] = { + { "year", tMONTH_UNIT, 12 }, + { "month", tMONTH_UNIT, 1 }, + { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 }, + { "week", tMINUTE_UNIT, 7 * 24 * 60 }, + { "day", tMINUTE_UNIT, 1 * 24 * 60 }, + { "hour", tMINUTE_UNIT, 60 }, + { "minute", tMINUTE_UNIT, 1 }, + { "min", tMINUTE_UNIT, 1 }, + { "second", tSEC_UNIT, 1 }, + { "sec", tSEC_UNIT, 1 }, + { NULL } +}; + +/* Assorted relative-time words. */ +static TABLE const OtherTable[] = { + { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, + { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, + { "today", tMINUTE_UNIT, 0 }, + { "now", tMINUTE_UNIT, 0 }, + { "last", tUNUMBER, -1 }, + { "this", tMINUTE_UNIT, 0 }, + { "next", tUNUMBER, 2 }, + { "first", tUNUMBER, 1 }, +/* { "second", tUNUMBER, 2 }, */ + { "third", tUNUMBER, 3 }, + { "fourth", tUNUMBER, 4 }, + { "fifth", tUNUMBER, 5 }, + { "sixth", tUNUMBER, 6 }, + { "seventh", tUNUMBER, 7 }, + { "eighth", tUNUMBER, 8 }, + { "ninth", tUNUMBER, 9 }, + { "tenth", tUNUMBER, 10 }, + { "eleventh", tUNUMBER, 11 }, + { "twelfth", tUNUMBER, 12 }, + { "ago", tAGO, 1 }, + { NULL } +}; + +/* The timezone table. */ +/* Some of these are commented out because a time_t can't store a float. */ +static TABLE const TimezoneTable[] = { + { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ + { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */ + { "utc", tZONE, HOUR( 0) }, + { "wet", tZONE, HOUR( 0) }, /* Western European */ + { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ + { "wat", tZONE, HOUR( 1) }, /* West Africa */ + { "at", tZONE, HOUR( 2) }, /* Azores */ +#if 0 + /* For completeness. BST is also British Summer, and GST is + * also Guam Standard. */ + { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */ + { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */ +#endif +#if 0 + { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */ + { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */ + { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */ +#endif + { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ + { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ + { "est", tZONE, HOUR( 5) }, /* Eastern Standard */ + { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ + { "cst", tZONE, HOUR( 6) }, /* Central Standard */ + { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ + { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ + { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ + { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ + { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ + { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ + { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ + { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ + { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */ + { "cat", tZONE, HOUR(10) }, /* Central Alaska */ + { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */ + { "nt", tZONE, HOUR(11) }, /* Nome */ + { "idlw", tZONE, HOUR(12) }, /* International Date Line West */ + { "cet", tZONE, -HOUR(1) }, /* Central European */ + { "met", tZONE, -HOUR(1) }, /* Middle European */ + { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ + { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ + { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ + { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ + { "fwt", tZONE, -HOUR(1) }, /* French Winter */ + { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ + { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */ + { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */ +#if 0 + { "it", tZONE, -HOUR(3.5) },/* Iran */ +#endif + { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ + { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ +#if 0 + { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */ +#endif + { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ +#if 0 + /* For completeness. NST is also Newfoundland Stanard, and SST is + * also Swedish Summer. */ + { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */ + { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */ +#endif /* 0 */ + { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */ + { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */ +#if 0 + { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */ +#endif + { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */ + { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */ +#if 0 + { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */ + { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */ +#endif + { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ + { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ + { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */ + { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ + { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ + { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ + { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ + { NULL } +}; + +/* Military timezone table. */ +static TABLE const MilitaryTable[] = { + { "a", tZONE, HOUR( 1) }, + { "b", tZONE, HOUR( 2) }, + { "c", tZONE, HOUR( 3) }, + { "d", tZONE, HOUR( 4) }, + { "e", tZONE, HOUR( 5) }, + { "f", tZONE, HOUR( 6) }, + { "g", tZONE, HOUR( 7) }, + { "h", tZONE, HOUR( 8) }, + { "i", tZONE, HOUR( 9) }, + { "k", tZONE, HOUR( 10) }, + { "l", tZONE, HOUR( 11) }, + { "m", tZONE, HOUR( 12) }, + { "n", tZONE, HOUR(- 1) }, + { "o", tZONE, HOUR(- 2) }, + { "p", tZONE, HOUR(- 3) }, + { "q", tZONE, HOUR(- 4) }, + { "r", tZONE, HOUR(- 5) }, + { "s", tZONE, HOUR(- 6) }, + { "t", tZONE, HOUR(- 7) }, + { "u", tZONE, HOUR(- 8) }, + { "v", tZONE, HOUR(- 9) }, + { "w", tZONE, HOUR(-10) }, + { "x", tZONE, HOUR(-11) }, + { "y", tZONE, HOUR(-12) }, + { "z", tZONE, HOUR( 0) }, + { NULL } +}; + + + + +/* ARGSUSED */ +static int +yyerror(s) + char *s; +{ + return 0; +} + + +static time_t +ToSeconds(Hours, Minutes, Seconds, Meridian) + time_t Hours; + time_t Minutes; + time_t Seconds; + MERIDIAN Meridian; +{ + if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) + return -1; + switch (Meridian) { + case MER24: + if (Hours < 0 || Hours > 23) + return -1; + return (Hours * 60L + Minutes) * 60L + Seconds; + case MERam: + if (Hours < 1 || Hours > 12) + return -1; + return (Hours * 60L + Minutes) * 60L + Seconds; + case MERpm: + if (Hours < 1 || Hours > 12) + return -1; + return ((Hours + 12) * 60L + Minutes) * 60L + Seconds; + default: + abort (); + } + /* NOTREACHED */ +} + + +static time_t +Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode) + time_t Month; + time_t Day; + time_t Year; + time_t Hours; + time_t Minutes; + time_t Seconds; + MERIDIAN Meridian; + DSTMODE DSTmode; +{ + static int DaysInMonth[12] = { + 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + time_t tod; + time_t Julian; + int i; + + if (Year < 0) + Year = -Year; + if (Year < 100) + Year += 1900; + DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) + ? 29 : 28; + if (Year < EPOCH || Year > 1999 + || Month < 1 || Month > 12 + /* Lint fluff: "conversion from long may lose accuracy" */ + || Day < 1 || Day > DaysInMonth[(int)--Month]) + return -1; + + for (Julian = Day - 1, i = 0; i < Month; i++) + Julian += DaysInMonth[i]; + for (i = EPOCH; i < Year; i++) + Julian += 365 + (i % 4 == 0); + Julian *= SECSPERDAY; + Julian += yyTimezone * 60L; + if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) + return -1; + Julian += tod; + if (DSTmode == DSTon + || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) + Julian -= 60 * 60; + return Julian; +} + + +static time_t +DSTcorrect(Start, Future) + time_t Start; + time_t Future; +{ + time_t StartDay; + time_t FutureDay; + + StartDay = (localtime(&Start)->tm_hour + 1) % 24; + FutureDay = (localtime(&Future)->tm_hour + 1) % 24; + return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; +} + + +static time_t +RelativeDate(Start, DayOrdinal, DayNumber) + time_t Start; + time_t DayOrdinal; + time_t DayNumber; +{ + struct tm *tm; + time_t now; + + now = Start; + tm = localtime(&now); + now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); + now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); + return DSTcorrect(Start, now); +} + + +static time_t +RelativeMonth(Start, RelMonth) + time_t Start; + time_t RelMonth; +{ + struct tm *tm; + time_t Month; + time_t Year; + + if (RelMonth == 0) + return 0; + tm = localtime(&Start); + Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; + Year = Month / 12; + Month = Month % 12 + 1; + return DSTcorrect(Start, + Convert(Month, (time_t)tm->tm_mday, Year, + (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, + MER24, DSTmaybe)); +} + + +static int +LookupWord(buff) + char *buff; +{ + register char *p; + register char *q; + register const TABLE *tp; + int i; + int abbrev; + + /* Make it lowercase. */ + for (p = buff; *p; p++) + if (isupper(*p)) + *p = tolower(*p); + + if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) { + yylval.Meridian = MERam; + return tMERIDIAN; + } + if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) { + yylval.Meridian = MERpm; + return tMERIDIAN; + } + + /* See if we have an abbreviation for a month. */ + if (strlen(buff) == 3) + abbrev = 1; + else if (strlen(buff) == 4 && buff[3] == '.') { + abbrev = 1; + buff[3] = '\0'; + } + else + abbrev = 0; + + for (tp = MonthDayTable; tp->name; tp++) { + if (abbrev) { + if (strncmp(buff, tp->name, 3) == 0) { + yylval.Number = tp->value; + return tp->type; + } + } + else if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + } + + for (tp = TimezoneTable; tp->name; tp++) + if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + if (strcmp(buff, "dst") == 0) + return tDST; + + for (tp = UnitsTable; tp->name; tp++) + if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + /* Strip off any plural and try the units table again. */ + i = strlen(buff) - 1; + if (buff[i] == 's') { + buff[i] = '\0'; + for (tp = UnitsTable; tp->name; tp++) + if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + buff[i] = 's'; /* Put back for "this" in OtherTable. */ + } + + for (tp = OtherTable; tp->name; tp++) + if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + /* Military timezones. */ + if (buff[1] == '\0' && isalpha(*buff)) { + for (tp = MilitaryTable; tp->name; tp++) + if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + } + + /* Drop out any periods and try the timezone table again. */ + for (i = 0, p = q = buff; *q; q++) + if (*q != '.') + *p++ = *q; + else + i++; + *p = '\0'; + if (i) + for (tp = TimezoneTable; tp->name; tp++) + if (strcmp(buff, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + return tID; +} + + +static int +yylex() +{ + register char c; + register char *p; + char buff[20]; + int Count; + int sign; + + for ( ; ; ) { + while (isspace(*yyInput)) + yyInput++; + + if (isdigit(c = *yyInput) || c == '-' || c == '+') { + if (c == '-' || c == '+') { + sign = c == '-' ? -1 : 1; + if (!isdigit(*++yyInput)) + /* skip the '-' sign */ + continue; + } + else + sign = 0; + for (yylval.Number = 0; isdigit(c = *yyInput++); ) + yylval.Number = 10 * yylval.Number + c - '0'; + yyInput--; + if (sign < 0) + yylval.Number = -yylval.Number; + return sign ? tSNUMBER : tUNUMBER; + } + if (isalpha(c)) { + for (p = buff; isalpha(c = *yyInput++) || c == '.'; ) + if (p < &buff[sizeof buff - 1]) + *p++ = c; + *p = '\0'; + yyInput--; + return LookupWord(buff); + } + if (c != '(') + return *yyInput++; + Count = 0; + do { + c = *yyInput++; + if (c == '\0') + return c; + if (c == '(') + Count++; + else if (c == ')') + Count--; + } while (Count > 0); + } +} + +#define TM_YEAR_ORIGIN 1900 + +/* Yield A - B, measured in seconds. */ +static long +difftm (a, b) + struct tm *a, *b; +{ + int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); + int by = b->tm_year + (TM_YEAR_ORIGIN - 1); + int days = ( + /* difference in day of year */ + a->tm_yday - b->tm_yday + /* + intervening leap days */ + + ((ay >> 2) - (by >> 2)) + - (ay/100 - by/100) + + ((ay/100 >> 2) - (by/100 >> 2)) + /* + difference in years * 365 */ + + (long)(ay-by) * 365 + ); + return (60*(60*(24*days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} + +time_t +get_date(p, now) + char *p; + struct timeb *now; +{ + struct tm *tm, gmt; + struct timeb ftz; + time_t Start; + time_t tod; + + yyInput = p; + if (now == NULL) { + now = &ftz; + (void)time(&ftz.time); + + if (! (tm = gmtime (&ftz.time))) + return -1; + gmt = *tm; /* Make a copy, in case localtime modifies *tm. */ + + if (! (tm = localtime (&ftz.time))) + return -1; + + ftz.timezone = difftm (&gmt, tm) / 60; + if(tm->tm_isdst) + ftz.timezone += 60; + } + + tm = localtime(&now->time); + yyYear = tm->tm_year; + yyMonth = tm->tm_mon + 1; + yyDay = tm->tm_mday; + yyTimezone = now->timezone; + yyDSTmode = DSTmaybe; + yyHour = 0; + yyMinutes = 0; + yySeconds = 0; + yyMeridian = MER24; + yyRelSeconds = 0; + yyRelMonth = 0; + yyHaveDate = 0; + yyHaveDay = 0; + yyHaveRel = 0; + yyHaveTime = 0; + yyHaveZone = 0; + + if (yyparse() + || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) + return -1; + + if (yyHaveDate || yyHaveTime || yyHaveDay) { + Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, + yyMeridian, yyDSTmode); + if (Start < 0) + return -1; + } + else { + Start = now->time; + if (!yyHaveRel) + Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; + } + + Start += yyRelSeconds; + Start += RelativeMonth(Start, yyRelMonth); + + if (yyHaveDay && !yyHaveDate) { + tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber); + Start += tod; + } + + /* Have to do *something* with a legitimate -1 so it's distinguishable + * from the error return value. (Alternately could set errno on error.) */ + return Start == -1 ? 0 : Start; +} + + +#if defined(TEST) + +/* ARGSUSED */ +int +main(ac, av) + int ac; + char *av[]; +{ + char buff[128]; + time_t d; + + (void)printf("Enter date, or blank line to exit.\n\t> "); + (void)fflush(stdout); + while (gets(buff) && buff[0]) { + d = get_date(buff, (struct timeb *)NULL); + if (d == -1) + (void)printf("Bad format - couldn't convert.\n"); + else + (void)printf("%s", ctime(&d)); + (void)printf("\t> "); + (void)fflush(stdout); + } + exit(0); + /* NOTREACHED */ +} +#endif /* defined(TEST) */ +int yyexca[] ={ +-1, 1, + 0, -1, + -2, 0, + }; +# define YYNPROD 42 +# define YYLAST 228 +int yyact[]={ + + 13, 11, 22, 28, 16, 12, 18, 17, 15, 9, + 10, 38, 39, 20, 48, 44, 47, 46, 36, 43, + 50, 32, 35, 34, 33, 29, 37, 31, 41, 45, + 40, 30, 14, 8, 7, 6, 5, 4, 3, 2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 19, 25, 24, 27, + 26, 23, 44, 0, 0, 0, 0, 42 }; +int yypact[]={ + + -1000, -258, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -45, + -266, -1000, -242, -13, -230, -241, -1000, -1000, -1000, -1000, + -245, -1000, -249, -240, -255, -1000, -1000, -1000, -1000, -14, + -1000, -1000, -1000, -1000, -1000, -39, -18, -1000, -1000, -1000, + -250, -1000, -1000, -251, -1000, -253, -1000, -246, -1000, -1000, + -1000 }; +int yypgo[]={ + + 0, 28, 40, 39, 38, 37, 36, 35, 34, 33, + 32 }; +int yyr1[]={ + + 0, 2, 2, 3, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 4, 5, 5, 5, 7, 7, 7, + 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, + 1, 1 }; +int yyr2[]={ + + 0, 0, 4, 3, 3, 3, 3, 3, 2, 5, + 9, 9, 13, 13, 3, 3, 5, 3, 5, 5, + 7, 11, 7, 7, 5, 9, 5, 7, 5, 2, + 5, 5, 3, 5, 5, 3, 5, 5, 3, 3, + 1, 3 }; +int yychk[]={ + + -1000, -2, -3, -4, -5, -6, -7, -8, -9, 267, + 268, 259, 263, 258, -10, 266, 262, 265, 264, 261, + 58, 258, 47, 266, 263, 262, 265, 264, 269, 267, + 44, 257, 262, 265, 264, 267, 267, 266, 266, 267, + 44, -1, 266, 58, 261, 47, 267, 267, 267, -1, + 266 }; +int yydef[]={ + + 1, -2, 2, 3, 4, 5, 6, 7, 8, 39, + 14, 15, 0, 17, 29, 0, 32, 35, 38, 9, + 0, 19, 0, 0, 26, 30, 34, 37, 16, 24, + 18, 28, 31, 33, 36, 40, 20, 22, 23, 27, + 0, 10, 11, 0, 41, 0, 25, 40, 21, 12, + 13 }; +typedef struct { char *t_name; int t_val; } yytoktype; +#ifndef YYDEBUG +# define YYDEBUG 0 /* don't allow debugging */ +#endif + +#if YYDEBUG + +yytoktype yytoks[] = +{ + "tAGO", 257, + "tDAY", 258, + "tDAYZONE", 259, + "tID", 260, + "tMERIDIAN", 261, + "tMINUTE_UNIT", 262, + "tMONTH", 263, + "tMONTH_UNIT", 264, + "tSEC_UNIT", 265, + "tSNUMBER", 266, + "tUNUMBER", 267, + "tZONE", 268, + "tDST", 269, + "-unknown-", -1 /* ends search */ +}; + +char * yyreds[] = +{ + "-no such reduction-", + "spec : /* empty */", + "spec : spec item", + "item : time", + "item : zone", + "item : date", + "item : day", + "item : rel", + "item : number", + "time : tUNUMBER tMERIDIAN", + "time : tUNUMBER ':' tUNUMBER o_merid", + "time : tUNUMBER ':' tUNUMBER tSNUMBER", + "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid", + "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER", + "zone : tZONE", + "zone : tDAYZONE", + "zone : tZONE tDST", + "day : tDAY", + "day : tDAY ','", + "day : tUNUMBER tDAY", + "date : tUNUMBER '/' tUNUMBER", + "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER", + "date : tUNUMBER tSNUMBER tSNUMBER", + "date : tUNUMBER tMONTH tSNUMBER", + "date : tMONTH tUNUMBER", + "date : tMONTH tUNUMBER ',' tUNUMBER", + "date : tUNUMBER tMONTH", + "date : tUNUMBER tMONTH tUNUMBER", + "rel : relunit tAGO", + "rel : relunit", + "relunit : tUNUMBER tMINUTE_UNIT", + "relunit : tSNUMBER tMINUTE_UNIT", + "relunit : tMINUTE_UNIT", + "relunit : tSNUMBER tSEC_UNIT", + "relunit : tUNUMBER tSEC_UNIT", + "relunit : tSEC_UNIT", + "relunit : tSNUMBER tMONTH_UNIT", + "relunit : tUNUMBER tMONTH_UNIT", + "relunit : tMONTH_UNIT", + "number : tUNUMBER", + "o_merid : /* empty */", + "o_merid : tMERIDIAN", +}; +#endif /* YYDEBUG */ +/* @(#)yaccpar 1.10 89/04/04 SMI; from S5R3 1.10 */ + +/* +** Skeleton parser driver for yacc output +*/ + +/* +** yacc user known macros and defines +*/ +#define YYERROR goto yyerrlab +#define YYACCEPT { free(yys); free(yyv); return(0); } +#define YYABORT { free(yys); free(yyv); return(1); } +#define YYBACKUP( newtoken, newvalue )\ +{\ + if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ + {\ + yyerror( "syntax error - cannot backup" );\ + goto yyerrlab;\ + }\ + yychar = newtoken;\ + yystate = *yyps;\ + yylval = newvalue;\ + goto yynewstate;\ +} +#define YYRECOVERING() (!!yyerrflag) +#ifndef YYDEBUG +# define YYDEBUG 1 /* make debugging available */ +#endif + +/* +** user known globals +*/ +int yydebug; /* set to 1 to get debugging */ + +/* +** driver internal defines +*/ +#define YYFLAG (-1000) + +/* +** static variables used by the parser +*/ +static YYSTYPE *yyv; /* value stack */ +static int *yys; /* state stack */ + +static YYSTYPE *yypv; /* top of value stack */ +static int *yyps; /* top of state stack */ + +static int yystate; /* current state */ +static int yytmp; /* extra var (lasts between blocks) */ + +int yynerrs; /* number of errors */ + +int yyerrflag; /* error recovery flag */ +int yychar; /* current input token number */ + + +/* +** yyparse - return 0 if worked, 1 if syntax error not recovered from +*/ +int +yyparse() +{ + register YYSTYPE *yypvt; /* top of value stack for $vars */ + unsigned yymaxdepth = YYMAXDEPTH; + + /* + ** Initialize externals - yyparse may be called more than once + */ + yyv = (YYSTYPE*)malloc(yymaxdepth*sizeof(YYSTYPE)); + yys = (int*)malloc(yymaxdepth*sizeof(int)); + if (!yyv || !yys) + { + yyerror( "out of memory" ); + return(1); + } + yypv = &yyv[-1]; + yyps = &yys[-1]; + yystate = 0; + yytmp = 0; + yynerrs = 0; + yyerrflag = 0; + yychar = -1; + + goto yystack; + { + register YYSTYPE *yy_pv; /* top of value stack */ + register int *yy_ps; /* top of state stack */ + register int yy_state; /* current state */ + register int yy_n; /* internal state number info */ + + /* + ** get globals into registers. + ** branch to here only if YYBACKUP was called. + */ + yynewstate: + yy_pv = yypv; + yy_ps = yyps; + yy_state = yystate; + goto yy_newstate; + + /* + ** get globals into registers. + ** either we just started, or we just finished a reduction + */ + yystack: + yy_pv = yypv; + yy_ps = yyps; + yy_state = yystate; + + /* + ** top of for (;;) loop while no reductions done + */ + yy_stack: + /* + ** put a state and value onto the stacks + */ +#if YYDEBUG + /* + ** if debugging, look up token value in list of value vs. + ** name pairs. 0 and negative (-1) are special values. + ** Note: linear search is used since time is not a real + ** consideration while debugging. + */ + if ( yydebug ) + { + register int yy_i; + + (void)printf( "State %d, token ", yy_state ); + if ( yychar == 0 ) + (void)printf( "end-of-file\n" ); + else if ( yychar < 0 ) + (void)printf( "-none-\n" ); + else + { + for ( yy_i = 0; yytoks[yy_i].t_val >= 0; + yy_i++ ) + { + if ( yytoks[yy_i].t_val == yychar ) + break; + } + (void)printf( "%s\n", yytoks[yy_i].t_name ); + } + } +#endif /* YYDEBUG */ + if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ + { + /* + ** reallocate and recover. Note that pointers + ** have to be reset, or bad things will happen + */ + int yyps_index = (yy_ps - yys); + int yypv_index = (yy_pv - yyv); + int yypvt_index = (yypvt - yyv); + yymaxdepth += YYMAXDEPTH; + yyv = (YYSTYPE*)realloc((char*)yyv, + yymaxdepth * sizeof(YYSTYPE)); + yys = (int*)realloc((char*)yys, + yymaxdepth * sizeof(int)); + if (!yyv || !yys) + { + yyerror( "yacc stack overflow" ); + return(1); + } + yy_ps = yys + yyps_index; + yy_pv = yyv + yypv_index; + yypvt = yyv + yypvt_index; + } + *yy_ps = yy_state; + *++yy_pv = yyval; + + /* + ** we have a new state - find out what to do + */ + yy_newstate: + if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) + goto yydefault; /* simple state */ +#if YYDEBUG + /* + ** if debugging, need to mark whether new token grabbed + */ + yytmp = yychar < 0; +#endif + if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) + yychar = 0; /* reached EOF */ +#if YYDEBUG + if ( yydebug && yytmp ) + { + register int yy_i; + + (void)printf( "Received token " ); + if ( yychar == 0 ) + (void)printf( "end-of-file\n" ); + else if ( yychar < 0 ) + (void)printf( "-none-\n" ); + else + { + for ( yy_i = 0; yytoks[yy_i].t_val >= 0; + yy_i++ ) + { + if ( yytoks[yy_i].t_val == yychar ) + break; + } + (void)printf( "%s\n", yytoks[yy_i].t_name ); + } + } +#endif /* YYDEBUG */ + if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) + goto yydefault; + if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ + { + yychar = -1; + yyval = yylval; + yy_state = yy_n; + if ( yyerrflag > 0 ) + yyerrflag--; + goto yy_stack; + } + + yydefault: + if ( ( yy_n = yydef[ yy_state ] ) == -2 ) + { +#if YYDEBUG + yytmp = yychar < 0; +#endif + if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) + yychar = 0; /* reached EOF */ +#if YYDEBUG + if ( yydebug && yytmp ) + { + register int yy_i; + + (void)printf( "Received token " ); + if ( yychar == 0 ) + (void)printf( "end-of-file\n" ); + else if ( yychar < 0 ) + (void)printf( "-none-\n" ); + else + { + for ( yy_i = 0; + yytoks[yy_i].t_val >= 0; + yy_i++ ) + { + if ( yytoks[yy_i].t_val + == yychar ) + { + break; + } + } + (void)printf( "%s\n", yytoks[yy_i].t_name ); + } + } +#endif /* YYDEBUG */ + /* + ** look through exception table + */ + { + register int *yyxi = yyexca; + + while ( ( *yyxi != -1 ) || + ( yyxi[1] != yy_state ) ) + { + yyxi += 2; + } + while ( ( *(yyxi += 2) >= 0 ) && + ( *yyxi != yychar ) ) + ; + if ( ( yy_n = yyxi[1] ) < 0 ) + YYACCEPT; + } + } + + /* + ** check for syntax error + */ + if ( yy_n == 0 ) /* have an error */ + { + /* no worry about speed here! */ + switch ( yyerrflag ) + { + case 0: /* new error */ + yyerror( "syntax error" ); + goto skip_init; + yyerrlab: + /* + ** get globals into registers. + ** we have a user generated syntax type error + */ + yy_pv = yypv; + yy_ps = yyps; + yy_state = yystate; + yynerrs++; + skip_init: + case 1: + case 2: /* incompletely recovered error */ + /* try again... */ + yyerrflag = 3; + /* + ** find state where "error" is a legal + ** shift action + */ + while ( yy_ps >= yys ) + { + yy_n = yypact[ *yy_ps ] + YYERRCODE; + if ( yy_n >= 0 && yy_n < YYLAST && + yychk[yyact[yy_n]] == YYERRCODE) { + /* + ** simulate shift of "error" + */ + yy_state = yyact[ yy_n ]; + goto yy_stack; + } + /* + ** current state has no shift on + ** "error", pop stack + */ +#if YYDEBUG +# define _POP_ "Error recovery pops state %d, uncovers state %d\n" + if ( yydebug ) + (void)printf( _POP_, *yy_ps, + yy_ps[-1] ); +# undef _POP_ +#endif + yy_ps--; + yy_pv--; + } + /* + ** there is no state on stack with "error" as + ** a valid shift. give up. + */ + YYABORT; + case 3: /* no shift yet; eat a token */ +#if YYDEBUG + /* + ** if debugging, look up token in list of + ** pairs. 0 and negative shouldn't occur, + ** but since timing doesn't matter when + ** debugging, it doesn't hurt to leave the + ** tests here. + */ + if ( yydebug ) + { + register int yy_i; + + (void)printf( "Error recovery discards " ); + if ( yychar == 0 ) + (void)printf( "token end-of-file\n" ); + else if ( yychar < 0 ) + (void)printf( "token -none-\n" ); + else + { + for ( yy_i = 0; + yytoks[yy_i].t_val >= 0; + yy_i++ ) + { + if ( yytoks[yy_i].t_val + == yychar ) + { + break; + } + } + (void)printf( "token %s\n", + yytoks[yy_i].t_name ); + } + } +#endif /* YYDEBUG */ + if ( yychar == 0 ) /* reached EOF. quit */ + YYABORT; + yychar = -1; + goto yy_newstate; + } + }/* end if ( yy_n == 0 ) */ + /* + ** reduction by production yy_n + ** put stack tops, etc. so things right after switch + */ +#if YYDEBUG + /* + ** if debugging, print the string that is the user's + ** specification of the reduction which is just about + ** to be done. + */ + if ( yydebug ) + (void)printf( "Reduce by (%d) \"%s\"\n", + yy_n, yyreds[ yy_n ] ); +#endif + yytmp = yy_n; /* value to switch over */ + yypvt = yy_pv; /* $vars top of value stack */ + /* + ** Look in goto table for next state + ** Sorry about using yy_state here as temporary + ** register variable, but why not, if it works... + ** If yyr2[ yy_n ] doesn't have the low order bit + ** set, then there is no action to be done for + ** this reduction. So, no saving & unsaving of + ** registers done. The only difference between the + ** code just after the if and the body of the if is + ** the goto yy_stack in the body. This way the test + ** can be made before the choice of what to do is needed. + */ + { + /* length of production doubled with extra bit */ + register int yy_len = yyr2[ yy_n ]; + + if ( !( yy_len & 01 ) ) + { + yy_len >>= 1; + yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ + yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + + *( yy_ps -= yy_len ) + 1; + if ( yy_state >= YYLAST || + yychk[ yy_state = + yyact[ yy_state ] ] != -yy_n ) + { + yy_state = yyact[ yypgo[ yy_n ] ]; + } + goto yy_stack; + } + yy_len >>= 1; + yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ + yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + + *( yy_ps -= yy_len ) + 1; + if ( yy_state >= YYLAST || + yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) + { + yy_state = yyact[ yypgo[ yy_n ] ]; + } + } + /* save until reenter driver code */ + yystate = yy_state; + yyps = yy_ps; + yypv = yy_pv; + } + /* + ** code supplied by user is placed in this switch + */ + switch( yytmp ) + { + +case 3: +{ + yyHaveTime++; + } break; +case 4: +{ + yyHaveZone++; + } break; +case 5: +{ + yyHaveDate++; + } break; +case 6: +{ + yyHaveDay++; + } break; +case 7: +{ + yyHaveRel++; + } break; +case 9: +{ + yyHour = yypvt[-1].Number; + yyMinutes = 0; + yySeconds = 0; + yyMeridian = yypvt[-0].Meridian; + } break; +case 10: +{ + yyHour = yypvt[-3].Number; + yyMinutes = yypvt[-1].Number; + yySeconds = 0; + yyMeridian = yypvt[-0].Meridian; + } break; +case 11: +{ + yyHour = yypvt[-3].Number; + yyMinutes = yypvt[-1].Number; + yyMeridian = MER24; + yyDSTmode = DSToff; + yyTimezone = - (yypvt[-0].Number % 100 + (yypvt[-0].Number / 100) * 60); + } break; +case 12: +{ + yyHour = yypvt[-5].Number; + yyMinutes = yypvt[-3].Number; + yySeconds = yypvt[-1].Number; + yyMeridian = yypvt[-0].Meridian; + } break; +case 13: +{ + yyHour = yypvt[-5].Number; + yyMinutes = yypvt[-3].Number; + yySeconds = yypvt[-1].Number; + yyMeridian = MER24; + yyDSTmode = DSToff; + yyTimezone = - (yypvt[-0].Number % 100 + (yypvt[-0].Number / 100) * 60); + } break; +case 14: +{ + yyTimezone = yypvt[-0].Number; + yyDSTmode = DSToff; + } break; +case 15: +{ + yyTimezone = yypvt[-0].Number; + yyDSTmode = DSTon; + } break; +case 16: +{ + yyTimezone = yypvt[-1].Number; + yyDSTmode = DSTon; + } break; +case 17: +{ + yyDayOrdinal = 1; + yyDayNumber = yypvt[-0].Number; + } break; +case 18: +{ + yyDayOrdinal = 1; + yyDayNumber = yypvt[-1].Number; + } break; +case 19: +{ + yyDayOrdinal = yypvt[-1].Number; + yyDayNumber = yypvt[-0].Number; + } break; +case 20: +{ + yyMonth = yypvt[-2].Number; + yyDay = yypvt[-0].Number; + } break; +case 21: +{ + yyMonth = yypvt[-4].Number; + yyDay = yypvt[-2].Number; + yyYear = yypvt[-0].Number; + } break; +case 22: +{ + /* ISO 8601 format. yyyy-mm-dd. */ + yyYear = yypvt[-2].Number; + yyMonth = -yypvt[-1].Number; + yyDay = -yypvt[-0].Number; + } break; +case 23: +{ + /* e.g. 17-JUN-1992. */ + yyDay = yypvt[-2].Number; + yyMonth = yypvt[-1].Number; + yyYear = -yypvt[-0].Number; + } break; +case 24: +{ + yyMonth = yypvt[-1].Number; + yyDay = yypvt[-0].Number; + } break; +case 25: +{ + yyMonth = yypvt[-3].Number; + yyDay = yypvt[-2].Number; + yyYear = yypvt[-0].Number; + } break; +case 26: +{ + yyMonth = yypvt[-0].Number; + yyDay = yypvt[-1].Number; + } break; +case 27: +{ + yyMonth = yypvt[-1].Number; + yyDay = yypvt[-2].Number; + yyYear = yypvt[-0].Number; + } break; +case 28: +{ + yyRelSeconds = -yyRelSeconds; + yyRelMonth = -yyRelMonth; + } break; +case 30: +{ + yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number * 60L; + } break; +case 31: +{ + yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number * 60L; + } break; +case 32: +{ + yyRelSeconds += yypvt[-0].Number * 60L; + } break; +case 33: +{ + yyRelSeconds += yypvt[-1].Number; + } break; +case 34: +{ + yyRelSeconds += yypvt[-1].Number; + } break; +case 35: +{ + yyRelSeconds++; + } break; +case 36: +{ + yyRelMonth += yypvt[-1].Number * yypvt[-0].Number; + } break; +case 37: +{ + yyRelMonth += yypvt[-1].Number * yypvt[-0].Number; + } break; +case 38: +{ + yyRelMonth += yypvt[-0].Number; + } break; +case 39: +{ + if (yyHaveTime && yyHaveDate && !yyHaveRel) + yyYear = yypvt[-0].Number; + else { + if(yypvt[-0].Number>10000) { + yyHaveDate++; + yyDay= (yypvt[-0].Number)%100; + yyMonth= (yypvt[-0].Number/100)%100; + yyYear = yypvt[-0].Number/10000; + } + else { + yyHaveTime++; + if (yypvt[-0].Number < 100) { + yyHour = yypvt[-0].Number; + yyMinutes = 0; + } + else { + yyHour = yypvt[-0].Number / 100; + yyMinutes = yypvt[-0].Number % 100; + } + yySeconds = 0; + yyMeridian = MER24; + } + } + } break; +case 40: +{ + yyval.Meridian = MER24; + } break; +case 41: +{ + yyval.Meridian = yypvt[-0].Meridian; + } break; + } + goto yystack; /* reset registers in driver code */ +} diff --git a/gnu/usr.bin/cvs/os2/getpass.c b/gnu/usr.bin/cvs/os2/getpass.c new file mode 100644 index 00000000000..b1113aedfc2 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/getpass.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <string.h> +#include "cvs.h" + +char * +getpass (char *prompt) +{ + static char passbuf[30]; + int i; + char *p; + int ch; + + printf ("%s", prompt); + fflush (stdout); + + p = passbuf, i = 0; + while (((ch = getchar ()) != '\n') && (ch != EOF)) + { + if (i++ < 24) + *p++ = ch; + } + *p = '\0'; + + return passbuf; +} diff --git a/gnu/usr.bin/cvs/os2/mkdir.c b/gnu/usr.bin/cvs/os2/mkdir.c new file mode 100644 index 00000000000..2c9df546847 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/mkdir.c @@ -0,0 +1,17 @@ +/* mkdir.c --- mkdir for OS/2 + Karl Fogel <kfogel@cyclic.com> --- October 1995 */ + +#include <assert.h> + +#include "cvs.h" + +int +os2_mkdir (const char *path, int mode) +{ + /* This is true for all extant calls to CVS_MKDIR. If + someone adds a call that uses something else later, + we should tweak this function to handle that. */ + assert (mode == 0777); + + return mkdir (path); +} diff --git a/gnu/usr.bin/cvs/os2/options.h b/gnu/usr.bin/cvs/os2/options.h new file mode 100644 index 00000000000..d0bbac10cb3 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/options.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 1992, Brian Berliner and Jeff Polk + * Copyright (c) 1989-1992, Brian Berliner + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with the CVS 1.4 kit. + * + * This file holds (most of) the configuration tweaks that can be made to + * customize CVS for your site. CVS comes configured for a typical SunOS 4.x + * environment. The comments for each configurable item are intended to be + * self-explanatory. All #defines are tested first to see if an over-riding + * option was specified on the "make" command line. + * + * If special libraries are needed, you will have to edit the Makefile.in file + * or the configure script directly. Sorry. + */ + +/* + * CVS provides the most features when used in conjunction with the Version-5 + * release of RCS. Thus, it is the default. This also assumes that GNU diff + * Version-1.15 is being used as well -- you will have to configure your RCS + * V5 release separately to make this the case. If you do not have RCS V5 and + * GNU diff V1.15, comment out this define. You should not try mixing and + * matching other combinations of these tools. + */ +#ifndef HAVE_RCS5 +#define HAVE_RCS5 +#endif + +/* + * If, before installing this version of CVS, you were running RCS V4 AND you + * are installing this CVS and RCS V5 and GNU diff 1.15 all at the same time, + * you should turn on the following define. It only exists to try to do + * reasonable things with your existing checked out files when you upgrade to + * RCS V5, since the keyword expansion formats have changed with RCS V5. + * + * If you already have been running with RCS5, or haven't been running with CVS + * yet at all, or are sticking with RCS V4 for now, leave the commented out. + */ +#ifndef HAD_RCS4 +/* #define HAD_RCS4 */ +#endif + +/* + * For portability and heterogeneity reasons, CVS is shipped by default using + * my own text-file version of the ndbm database library in the src/myndbm.c + * file. If you want better performance and are not concerned about + * heterogeneous hosts accessing your modules file, turn this option off. + */ +#ifndef MY_NDBM +#define MY_NDBM +#endif + +/* + * The "diff" program to execute when creating patch output. This "diff" + * must support the "-c" option for context diffing. Specify a full + * pathname if your site wants to use a particular diff. If you are + * using the GNU version of diff (version 1.15 or later), this should + * be "diff -a". + * + * NOTE: this program is only used for the ``patch'' sub-command (and + * for ``update'' if you are using the server). The other commands + * use rcsdiff which will use whatever version of diff was specified + * when rcsdiff was built on your system. + */ + +#ifndef DIFF +#define DIFF "diff" +#endif + +/* + * The "grep" program to execute when checking to see if a merged file had + * any conflicts. This "grep" must support the "-s" option and a standard + * regular expression as an argument. Specify a full pathname if your site + * wants to use a particular grep. + */ + +#ifndef GREP +#define GREP "grep" +#endif + +/* + * The "rm" program to execute when pruning directories that are not part of + * a release. This "rm" must support the "-fr" options. Specify a full + * pathname if your site wants to use a particular rm. + */ +#ifndef RM +#define RM "rm" +#endif + +/* + * The "sort" program to execute when displaying the module database. Specify + * a full pathname if your site wants to use a particular sort. + */ +#ifndef SORT +#define SORT "sort" +#endif + +/* + * The "patch" program to run when using the CVS server and accepting + * patches across the network. Specify a full pathname if your site + * wants to use a particular patch. + */ +#ifndef PATCH_PROGRAM +#define PATCH_PROGRAM "patch" +#endif + +/* + * By default, RCS programs are executed with the shell or through execlp(), + * so the user's PATH environment variable is searched. If you'd like to + * bind all RCS programs to a certain directory (perhaps one not in most + * people's PATH) then set the default in RCSBIN_DFLT. Note that setting + * this here will cause all RCS programs to be executed from this directory, + * unless the user overrides the default with the RCSBIN environment variable + * or the "-b" option to CVS. + * + * If you're compiling the authenticating server (see + * AUTH_SERVER_SUPPORT farther down), then you probably want to set + * RCSBIN_DFLT. The authenticating server starts out running as root, + * and then switches to run as the appropriate user once + * authentication is complete. No shell is ever started by that user, + * so the PATH environment variable may not contain the directory with + * the RCS binaries, even though if that user logged in normally, PATH + * would include the directory. An alternative to setting RCSBIN_DFLT + * is to make sure that root has the right directory in its path + * already. + * + * This define should be either the empty string ("") or a full pathname to the + * directory containing all the installed programs from the RCS distribution. + */ +#ifndef RCSBIN_DFLT +#define RCSBIN_DFLT "" +#endif + +/* + * The default editor to use, if one does not specify the "-e" option to cvs, + * or does not have an EDITOR environment variable. I set this to just "vi", + * and use the shell to find where "vi" actually is. This allows sites with + * /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that your PATH + * is reasonable). + * + * The notepad program seems to be Windows NT's bare-bones text editor. + */ +#ifndef EDITOR_DFLT +#define EDITOR_DFLT "notepad" +#endif + +/* + * The default umask to use when creating or otherwise setting file or + * directory permissions in the repository. Must be a value in the + * range of 0 through 0777. For example, a value of 002 allows group + * rwx access and world rx access; a value of 007 allows group rwx + * access but no world access. This value is overridden by the value + * of the CVSUMASK environment variable, which is interpreted as an + * octal number. + */ +#ifndef UMASK_DFLT +#define UMASK_DFLT 002 +#endif + +/* + * The cvs admin command is restricted to the members of the group + * CVS_ADMIN_GROUP. If this group does not exist, all users are + * allowed to run cvs admin. To disable the cvs admin for all users, + * create an empty group CVS_ADMIN_GROUP. To disable access control for + * cvs admin, comment out the define below. + * + * Under Windows NT and OS/2, this must not be used because it tries + * to include <grp.h>. + */ +#ifdef CVS_ADMIN_GROUP +/* #define CVS_ADMIN_GROUP "cvsadmin" */ +#endif + +/* + * The Repository file holds the path to the directory within the source + * repository that contains the RCS ,v files for each CVS working directory. + * This path is either a full-path or a path relative to CVSROOT. + * + * The only advantage that I can see to having a relative path is that One can + * change the physical location of the master source repository, change one's + * CVSROOT environment variable, and CVS will work without problems. I + * recommend using full-paths. + */ +#ifndef RELATIVE_REPOS +/* #define RELATIVE_REPOS */ +#endif + +/* + * When committing or importing files, you must enter a log message. + * Normally, you can do this either via the -m flag on the command line or an + * editor will be started for you. If you like to use logging templates (the + * rcsinfo file within the $CVSROOT/CVSROOT directory), you might want to + * force people to use the editor even if they specify a message with -m. + * Enabling FORCE_USE_EDITOR will cause the -m message to be appended to the + * temp file when the editor is started. + */ +#ifndef FORCE_USE_EDITOR +/* #define FORCE_USE_EDITOR */ +#endif + +/* + * When locking the repository, some sites like to remove locks and assume + * the program that created them went away if the lock has existed for a long + * time. This used to be the default for previous versions of CVS. CVS now + * attempts to be much more robust, so lock files should not be left around + * by mistake. The new behaviour will never remove old locks (they must now + * be removed by hand). Enabling CVS_FUDGELOCKS will cause CVS to remove + * locks that are older than CVSLCKAGE seconds. + * Use of this option is NOT recommended. + */ +#ifndef CVS_FUDGELOCKS +/* #define CVS_FUDGELOCKS */ +#endif + +/* + * When committing a permanent change, CVS and RCS make a log entry of + * who committed the change. If you are committing the change logged in + * as "root" (not under "su" or other root-priv giving program), CVS/RCS + * cannot determine who is actually making the change. + * + * As such, by default, CVS disallows changes to be committed by users + * logged in as "root". You can disable this option by commenting + * out the lines below. + * + * Under Windows NT, privileges are associated with groups, not users, + * so the case in which someone has logged in as root does not occur. + * Thus, there is no need for this hack. + * + * todo: I don't know about OS/2 yet. -kff + */ +#undef CVS_BADROOT + +/* + * The "cvs diff" command accepts all the single-character options that GNU + * diff (1.15) accepts. Except -D. GNU diff uses -D as a way to put + * cpp-style #define's around the output differences. CVS, by default, uses + * -D to specify a free-form date (like "cvs diff -D '1 week ago'"). If + * you would prefer that the -D option of "cvs diff" work like the GNU diff + * option, then comment out this define. + */ +#ifndef CVS_DIFFDATE +#define CVS_DIFFDATE +#endif + +/* + * define this to enable the SETXID support (see FAQ 4D.13) + * [ We have no such thing under OS/2, so far as I know. ] + */ +#undef SETXID_SUPPORT + +/* + * Under OS/2, we build the authenticated client by default. + * But not the server, because there is no server support for OS/2 + * yet. + */ +#define AUTH_CLIENT_SUPPORT 1 +/* #define AUTH_SERVER_SUPPORT 1 */ + +/* End of CVS configuration section */ + +/* + * Externs that are included in libc, but are used frequently enough to + * warrant defining here. + */ +#ifndef STDC_HEADERS +extern void exit (); +#endif + +#ifndef getwd +extern char *getwd (); +#endif + +#ifdef AUTH_CLIENT_SUPPORT +char *getpass (char *passbuf); +#endif /* AUTH_CLIENT_SUPPORT */ diff --git a/gnu/usr.bin/cvs/os2/popen.c b/gnu/usr.bin/cvs/os2/popen.c new file mode 100644 index 00000000000..9f8199764d5 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/popen.c @@ -0,0 +1,380 @@ +/* popen.c -- popen/pclose for OS/2. */ + +/* Set to 0 for distribution. + Search for "DIAGNOSTIC" in the code to see what it's for. */ +#define DIAGNOSTIC 0 + +#define INCL_DOSQUEUES +#define INCL_DOSPROCESS +#define INCL_DOSSESMGR +#include <os2.h> +#include <process.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <ctype.h> +#include <string.h> +#include <fcntl.h> + +#define LL_VAL ULONG +#define LL_KEY PID /* also ULONG, really */ + + +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +/* ********************************************************************* * + * * + * First, a little linked-list library to help keep track of pipes: * + * * + * ********************************************************************* */ + +/* Map integer PID's onto integer termination codes. */ +struct pid_list +{ + HFILE pid; /* key */ + ULONG term_code; /* val */ + struct pid_list *next; /* duh */ +}; + +static struct pid_list *pid_ll = (struct pid_list *) NULL; + +/* The ll_*() functions all make use of the global var `pid_ll'. */ + +void +ll_insert (HFILE key, ULONG val) +{ + struct pid_list *new; + new = (struct pid_list *) malloc (sizeof (*new)); + + new->pid = key; + new->term_code = val; + new->next = pid_ll; + + pid_ll = new; +} + + +void +ll_delete (int key) +{ + struct pid_list *this, *last; + + this = pid_ll; + last = (struct pid_list *) NULL; + + while (this) + { + if (this->pid == key) + { + /* Delete this node and leave. */ + if (last) + last->next = this->next; + else + pid_ll = this->next; + free (this); + return; + } + + /* Else no match, so try the next one. */ + last = this; + this = this->next; + } +} + +ULONG +ll_lookup (HFILE key) +{ + struct pid_list *this = pid_ll; + + while (this) + { + if (this->pid == key) + return this->term_code; + + /* Else no match, so try the next one. */ + this = this->next; + } + + /* Zero is special in this context anyway. */ + return 0; +} + +#if DIAGNOSTIC +ULONG +ll_length () +{ + struct pid_list *this = pid_ll; + unsigned long int len; + + for (len = 0; this; len++) + this = this->next; + + return len; +} + +ULONG +ll_print () +{ + struct pid_list *this = pid_ll; + unsigned long int i; + + for (i = 0; this; i++) + { + printf ("pid_ll[%d] == (%5d --> %5d)\n", + i, this->pid, this->term_code); + this = this->next; + } + + if (i == 0) + printf ("No entries.\n"); + + return i; +} +#endif /* DIAGNOSTIC */ + +/* ********************************************************************* * + * * + * End of linked-list library, beginning of popen/pclose: * + * * + * ********************************************************************* */ + +/* + * Routine: popen + * Returns: FILE pointer to pipe. + * Action : Exec program connected via pipe, connect a FILE * to the + * pipe and return it. + * Params : Command - Program to run + * Mode - Mode to open pipe. "r" implies pipe is connected + * to the programs stdout, "w" connects to stdin. + */ +FILE * +popen (const char *Command, const char *Mode) +{ + HFILE End1, End2, Std, Old1, Old2, Tmp; + + FILE *File; + + char Fail[256], + *Args, + CmdLine[256], + *CmdExe; + + RESULTCODES + Result; + + int Rc; + + if (DosCreatePipe (&End1, &End2, 4096)) + return NULL; + + Std = (*Mode == 'w') ? STDIN : STDOUT ; + if (Std == STDIN) + { + Tmp = End1; End1 = End2; End2 = Tmp; + } + + Old1 = -1; /* save stdin or stdout */ + DosDupHandle (Std, &Old1); + DosSetFHState (Old1, OPEN_FLAGS_NOINHERIT); + Tmp = Std; /* redirect stdin or stdout */ + DosDupHandle (End2, &Tmp); + + if (Std == 1) + { + Old2 = -1; /* save stderr */ + DosDupHandle (STDERR, &Old2); + DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT); + Tmp = STDERR; + DosDupHandle (End2, &Tmp); + } + + DosClose (End2); + DosSetFHState (End1, OPEN_FLAGS_NOINHERIT); + + if ((CmdExe = getenv ("COMSPEC")) == NULL ) + CmdExe = "cmd.exe"; + + strcpy (CmdLine, CmdExe); + Args = CmdLine + strlen (CmdLine) + 1; /* skip zero */ + strcpy (Args, "/c "); + strcat (Args, Command); + Args[strlen (Args) + 1] = '\0'; /* two zeroes */ + Rc = DosExecPgm (Fail, sizeof (Fail), EXEC_ASYNCRESULT, + (unsigned char *) CmdLine, 0, &Result, + (unsigned char *) CmdExe); + + Tmp = Std; /* restore stdin or stdout */ + DosDupHandle (Old1, &Tmp); + DosClose (Old1); + + if (Std == STDOUT) + { + Tmp = STDERR; /* restore stderr */ + DosDupHandle (Old2, &Tmp); + DosClose (Old2); + } + + if (Rc) + { + DosClose (End1); + return NULL; + } + + File = fdopen (End1, Mode); + ll_insert ((LL_KEY) End1, (LL_VAL) Result.codeTerminate); + + return File; +} + + +/* + * Routine: popenRW + * Returns: PID of child process + * Action : Exec program connected via pipe, connect int fd's to + * both the stdin and stdout of the process. + * Params : Command - Program to run + * Pipes - Array of 2 ints to store the pipe descriptors + * Pipe[0] writes to child's stdin, + * Pipe[1] reads from child's stdout/stderr + */ +int +popenRW (const char **argv, int *pipes) +{ + HFILE Out1, Out2, In1, In2; + HFILE Old0 = -1, Old1 = -1, Old2 = -1, Tmp; + + PID pid; + + if (DosCreatePipe (&Out2, &Out1, 4096)) + return FALSE; + + if (DosCreatePipe (&In1, &In2, 4096)) + { + DosClose (Out1); + DosClose (Out2); + return FALSE; + } + + /* Save std{in,out,err} */ + DosDupHandle (STDIN, &Old0); + DosSetFHState (Old1, OPEN_FLAGS_NOINHERIT); + DosDupHandle (STDOUT, &Old1); + DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT); + DosDupHandle (STDERR, &Old2); + DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT); + + /* Redirect std{in,out,err} */ + Tmp = STDIN; + DosDupHandle (In1, &Tmp); + Tmp = STDOUT; + DosDupHandle (Out1, &Tmp); + Tmp = STDERR; + DosDupHandle (Out1, &Tmp); + + /* Close file handles not needed in child */ + + DosClose (In1); + DosClose (Out1); + DosSetFHState (In2, OPEN_FLAGS_NOINHERIT); + DosSetFHState (Out2, OPEN_FLAGS_NOINHERIT); + + /* Spawn we now our hoary brood. */ + pid = spawnvp (P_NOWAIT, argv[0], argv); + + /* Restore std{in,out,err} */ + Tmp = STDIN; + DosDupHandle (Old0, &Tmp); + DosClose (Old0); + Tmp = STDOUT; + DosDupHandle (Old1, &Tmp); + DosClose (Old1); + Tmp = STDERR; + DosDupHandle (Old2, &Tmp); + DosClose (Old2); + + if(pid < 0) + { + DosClose (In2); + DosClose (Out2); + return -1; + } + + pipes[0] = In2; + _setmode (pipes[0], O_BINARY); + pipes[1] = Out2; + _setmode (pipes[1], O_BINARY); + + /* Save ID of write-to-child pipe for pclose() */ + ll_insert ((LL_KEY) In2, (LL_VAL) pid); + + return pid; +} + + +/* + * Routine: pclose + * Returns: TRUE on success + * Action : Close a pipe opened with popen(); + * Params : Pipe - pipe to close + */ +int +pclose (FILE *Pipe) +{ + RESULTCODES rc; + PID pid, pid1; + int Handle = fileno (Pipe); + + fclose (Pipe); + + rc.codeTerminate = -1; + + pid1 = (PID) ll_lookup ((LL_KEY) Handle); + /* if pid1 is zero, something's seriously wrong */ + if (pid1 != 0) + { + DosWaitChild (DCWA_PROCESSTREE, DCWW_WAIT, &rc, &pid, pid1); + ll_delete ((LL_KEY) Handle); + } + return rc.codeTerminate == 0 ? rc.codeResult : -1; +} + + +#if DIAGNOSTIC +void +main () +{ + FILE *fp1, *fp2, *fp3; + int c; + + ll_print (); + fp1 = popen ("gcc --version", "r"); + ll_print (); + fp2 = popen ("link386 /?", "r"); + ll_print (); + fp3 = popen ("dir", "r"); + ll_print (); + + while ((c = getc (fp1)) != EOF) + printf ("%c", c); + + while ((c = getc (fp2)) != EOF) + printf ("%c", c); + + while ((c = getc (fp3)) != EOF) + printf ("%c", c); + + pclose (fp1); + ll_print (); + pclose (fp2); + ll_print (); + pclose (fp3); + ll_print (); + + return; +} + +#endif /* DIAGNOSTIC */ diff --git a/gnu/usr.bin/cvs/os2/popen.h b/gnu/usr.bin/cvs/os2/popen.h new file mode 100644 index 00000000000..8daf29eaef0 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/popen.h @@ -0,0 +1,6 @@ +/* We roll our own popen()/pclose() in OS/2. + Thanks, Glenn Gribble! */ + +FILE *popen (char *cmd, char *mode); +int popenRW (char **cmd, int *pipes); +int pclose (FILE *stream); diff --git a/gnu/usr.bin/cvs/os2/porttcp.c b/gnu/usr.bin/cvs/os2/porttcp.c new file mode 100644 index 00000000000..a64b511f82d --- /dev/null +++ b/gnu/usr.bin/cvs/os2/porttcp.c @@ -0,0 +1,227 @@ +/**************************************************************** +** +** PORTTCP.C - Support for portable TCP/IP +** +****************************************************************/ + +#define TCPIP_IBM_NOHIDE +#include <stdio.h> +#include "tcpip.h" + +/* + * Common unknown error buffer + */ +static char ErrUnknownBuf[36]; + +#ifndef SockStrError + +/**************************************************************** + * Routine: SockStrError + * Returns: Pointer to static buffer + * Action : Convert SOCK_ERRNO into error text + ****************************************************************/ + +const char * +SockStrError(int SockErrno) +{ +#if defined (TCPIP_IBM) && defined (IBM_CPP) + switch (SockErrno) + { + case SOCEPERM: return "Not owner"; + case SOCESRCH: return "No such process"; + case SOCEINTR: return "Interrupted system call"; + case SOCENXIO: return "No such device or address"; + case SOCEBADF: return "Bad file number"; + case SOCEACCES: return "Permission denied"; + case SOCEFAULT: return "Bad address"; + case SOCEINVAL: return "Invalid argument"; + case SOCEMFILE: return "Too many open files"; + case SOCEPIPE: return "Broken pipe"; + case SOCEOS2ERR: return "OS/2 Error"; + case SOCEWOULDBLOCK: return "Operation would block"; + case SOCEINPROGRESS: return "Operation now in progress"; + case SOCEALREADY: return "Operation already in progress"; + case SOCENOTSOCK: return "Socket operation on non-socket"; + case SOCEDESTADDRREQ: return "Destination address required"; + case SOCEMSGSIZE: return "Message too long"; + case SOCEPROTOTYPE: return "Protocol wrong type for socket"; + case SOCENOPROTOOPT: return "Protocol not available"; + case SOCEPROTONOSUPPORT: return "Protocol not supported"; + case SOCESOCKTNOSUPPORT: return "Socket type not supported"; + case SOCEOPNOTSUPP: return "Operation not supported on socket"; + case SOCEPFNOSUPPORT: return "Protocol family not supported"; + case SOCEAFNOSUPPORT: + return "Address family not supported by protocol family"; + case SOCEADDRINUSE: return "Address already in use"; + case SOCEADDRNOTAVAIL: return "Can't assign requested address"; + case SOCENETDOWN: return "Network is down"; + case SOCENETUNREACH: return "Network is unreachable"; + case SOCENETRESET: return "Network dropped connection on reset"; + case SOCECONNABORTED: return "Software caused connection abort"; + case SOCECONNRESET: return "Connection reset by peer"; + case SOCENOBUFS: return "No buffer space available"; + case SOCEISCONN: return "Socket is already connected"; + case SOCENOTCONN: return "Socket is not connected"; + case SOCESHUTDOWN: return "Can't send after socket shutdown"; + case SOCETOOMANYREFS: return "Too many references: can't splice"; + case SOCETIMEDOUT: return "Connection timed out"; + case SOCECONNREFUSED: return "Connection refused"; + case SOCELOOP: return "Too many levels of symbolic links"; + case SOCENAMETOOLONG: return "File name too long"; + case SOCEHOSTDOWN: return "Host is down"; + case SOCEHOSTUNREACH: return "No route to host"; + case SOCENOTEMPTY: return "Directory not empty"; + + default: + sprintf( ErrUnknownBuf, "SockStrErrno( %d ) unknown", SockErrno ); + return ErrUnknownBuf; + } +#else +#error SockStrError not supported for this OS +#endif +} + +#endif /* SockStrError */ + + +/**************************************************************** + * Routine: HostStrError + * Returns: Pointer to static buffer + * Action : Convert HOST_ERRNO into error text + ****************************************************************/ + +const char * +HostStrError(int HostErrno) +{ + switch (HostErrno) + { + case HOST_NOT_FOUND: + return "Host not found"; + case TRY_AGAIN: + return "Host not found (suggest try again)"; + case NO_RECOVERY: + return "Non-recoverable error: FORMERR, REFUSED, NOTIMP"; + case NO_DATA: + return "No Data (valid name, but no record of requested type)"; + + default: + sprintf( ErrUnknownBuf, "HostStrErrno( %d ) unknown", HostErrno ); + return ErrUnknownBuf; + } +} + + +#if defined( TCPIP_IBM ) +/**************************************************************** + * Routine: IbmSockSend + * Returns: same as send + * Action : Do the right thing for IBM TCP/IP which includes + * the following two stupidities: + * 1) Never try to send more than 32K + * 2) Never pass a buffer that crosses a 64K boundary + * If Flags is non-zero, this function only attempts + * to deal with condition (1) above. + ****************************************************************/ + +int +IbmSockSend (int Socket, const void *Buffer, int Len, int Flags) +{ + int Sent, ToSend, TotalSent = 0; + + const char *Tmp = Buffer; + + /* + * If Flags have been passed in, the 64K boundary optimization + * can not be performed. For example, MSG_PEEK would not work + * correctly. + */ + if (Flags) + return send (Socket, (char *) Buffer, min (0x7FFF, Len), Flags); + + do + { + /* Never send across a 64K boundary */ + ToSend = min (Len, (int) (0x10000 - (0xFFFF & (long) Tmp))); + + /* Never send more than 32K */ + if (ToSend > 0x7FFF) + ToSend = 0x7FFF; + + Sent = send (Socket, (char *) Tmp, ToSend, 0); + if (Sent < 0) + { + if ((TotalSent > 0) && (SOCK_ERRNO == EWOULDBLOCK)) + return TotalSent; + if (SOCK_ERRNO == EINTR) + continue; + return Sent; + } + if (Sent < ToSend) + return TotalSent + Sent; + + Tmp += Sent; + TotalSent += Sent; + Len -= Sent; + } while (Len > 0); + + return TotalSent; +} + + + +/**************************************************************** + * Routine: IbmSockRecv + * Returns: same as recv + * Action : Do the right thing for IBM TCP/IP which includes + * the following two stupidities: + * 1) Never try to recv more than 32K + * 2) Never pass a buffer that crosses a 64K boundary + * If Flags is non-zero, this function only attempts + * to deal with condition (1) above. + ****************************************************************/ + +int +IbmSockRecv (int Socket, const void *Buffer, int Len, int Flags) +{ + int Recvd, ToRecv, TotalRecvd = 0; + + char *Tmp = Buffer; + + /* If Flags have been passed in, the 64K boundary optimization + probably can not be performed. */ + + if (Flags) + return recv (Socket, Buffer, min (0x7FFF, Len), Flags); + + do + { + /* Never send across a 64K boundary */ + ToRecv = min( Len, (int)( 0x10000 - ( 0xFFFF & (long)Tmp ))); + + /* Never send more than 32K */ + if( ToRecv > 0x7FFF ) + ToRecv = 0x7FFF; + + Recvd = recv (Socket, Tmp, ToRecv, 0); + if (Recvd <= 0) + { + if ((TotalRecvd > 0) + && (Recvd == 0 || (SOCK_ERRNO == EWOULDBLOCK ))) + return TotalRecvd; + if (SOCK_ERRNO == EINTR) + continue; + + return Recvd; + } + if (Recvd < ToRecv) + return TotalRecvd + Recvd; + + Tmp += Recvd; + TotalRecvd += Recvd; + Len -= Recvd; + } while (Len > 0); + + return TotalRecvd; +} +#endif /* defined( TCPIP_IBM ) */ + diff --git a/gnu/usr.bin/cvs/os2/pwd.c b/gnu/usr.bin/cvs/os2/pwd.c new file mode 100644 index 00000000000..5fb989b11ff --- /dev/null +++ b/gnu/usr.bin/cvs/os2/pwd.c @@ -0,0 +1,205 @@ +/* pwd.c - Try to approximate UN*X's getuser...() functions under MS-DOS. + Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Header: /cvs/OpenBSD/src/gnu/usr.bin/cvs/os2/pwd.c,v 1.1.1.1 1996/01/30 00:19:38 tholo Exp $ +*/ + +/* This 'implementation' is conjectured from the use of this functions in + the RCS and BASH distributions. Of course these functions don't do too + much useful things under MS-DOS, but using them avoids many "#ifdef + MSDOS" in ported UN*X code ... */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> + +static char *lookup_env (char **); + +/* where people might scribble their name into the environment ... */ + +static char *login_strings[] = +{ + "LOGIN", "USER", "MAILNAME", (char *) 0 +}; + +static char *group_strings[] = +{ + "GROUP", (char *) 0 +}; + + +static char *anonymous = "anonymous"; /* if all else fails ... */ + +static char *home_dir = "."; /* we feel (no|every)where at home */ +static char *login_shell = "not cmd.exe!"; + +static char *login = (char *) 0;/* cache the names here */ +static char *group = (char *) 0; + +static struct passwd pw; /* should we return a malloc()'d structure */ +static struct group gr; /* instead of pointers to static structures? */ + +/* return something like a username in a (butchered!) passwd structure. */ +struct passwd * +getpwuid (int uid) +{ + pw.pw_name = getlogin (); + pw.pw_dir = home_dir; + pw.pw_shell = login_shell; + pw.pw_uid = 0; + + return &pw; +} + +struct passwd * +getpwnam (char *name) +{ + return (struct passwd *) 0; +} + +/* return something like a groupname in a (butchered!) group structure. */ +struct group * +getgrgid (int uid) +{ + gr.gr_name = getgr_name (); + gr.gr_gid = 0; + + return &gr; +} + +struct group * +getgrnam (char *name) +{ + return (struct group *) 0; +} + +/* return something like a username. */ +char * +getlogin () +{ + if (!login) /* have we been called before? */ + login = lookup_env (login_strings); + + if (!login) /* have we been successful? */ + login = anonymous; + + return login; +} + +/* return something like a group. */ +char * +getgr_name () +{ + if (!group) /* have we been called before? */ + group = lookup_env (group_strings); + + if (!group) /* have we been successful? */ + group = anonymous; + + return group; +} + +/* return something like a uid. */ +int +getuid () +{ + return 0; /* every user is a super user ... */ +} + +int +getgid () +{ + return 0; +} + +int +geteuid () +{ + return 0; +} + +int +getegid () +{ + return 0; +} + +struct passwd * +getpwent () +{ + return (struct passwd *) 0; +} + +void +setpwent () +{ +} + +void +endpwent () +{ +} + +void +endgrent () +{ +} + +/* return groups. */ +int +getgroups (int ngroups, int *groups) +{ + *groups = 0; + return 1; +} + +/* lookup environment. */ +static char * +lookup_env (char *table[]) +{ + char *ptr; + char *entry; + size_t len; + + while (*table && !(ptr = getenv (*table++))) ; /* scan table */ + + if (!ptr) + return (char *) 0; + + len = strcspn (ptr, " \n\t\n\r"); /* any WS? */ + if (!(entry = malloc (len + 1))) + { + fprintf (stderr, "Out of memory.\nStop."); + exit (-1); + } + + strncpy (entry, ptr, len); + entry[len] = '\0'; + + return entry; + +} + +/* + * Local Variables: + * mode:C + * ChangeLog:ChangeLog + * compile-command:make + * End: + */ diff --git a/gnu/usr.bin/cvs/os2/pwd.h b/gnu/usr.bin/cvs/os2/pwd.h new file mode 100644 index 00000000000..d139d30cc04 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/pwd.h @@ -0,0 +1,77 @@ +/* pwd.h - Try to approximate UN*X's getuser...() functions under MS-DOS. + Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Header: /cvs/OpenBSD/src/gnu/usr.bin/cvs/os2/pwd.h,v 1.1.1.1 1996/01/30 00:19:37 tholo Exp $ +*/ + +/* This 'implementation' is conjectured from the use of this functions in + the RCS and BASH distributions. Of course these functions don't do too + much useful things under MS-DOS, but using them avoids many "#ifdef + MSDOS" in ported UN*X code ... */ + +#if 0 +/* This is taken care of in Windows-NT/config.h. */ +typedef int uid_t; +#endif + +struct passwd +{ + /* ... */ + /* missing stuff */ + /* ... */ + char *pw_name; /* login user id */ + char *pw_dir; /* home directory */ + char *pw_shell; /* login shell */ + int pw_uid; +}; + +struct group +{ + /* ... */ + /* missing stuff */ + /* ... */ + char *gr_name; /* login user id */ + int gr_gid; +}; + +extern struct passwd *getpwuid (int); +extern struct passwd *getpwnam (char *); +extern struct group *getgrgid (int); +extern struct group *getgrnam (char *); +extern char *getlogin (void); +extern char *getgr_name (void); +extern int getuid (void); +extern int getgid (void); +extern int geteuid (void); +extern int getegid (void); + +extern int *groups; +extern int ngroups; +extern int getgroups (int, int *); + +extern struct passwd *getpwent (void); +extern void setpwent (void); +extern void endpwent (void); +extern void endgrent (void); + +/* + * Local Variables: + * mode:C + * ChangeLog:ChangeLog + * compile-command:make + * End: + */ diff --git a/gnu/usr.bin/cvs/os2/rcmd.c b/gnu/usr.bin/cvs/os2/rcmd.c new file mode 100644 index 00000000000..36b17516dd5 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/rcmd.c @@ -0,0 +1,66 @@ +/* rcmd.c --- execute a command on a remote host from OS/2 + Karl Fogel <kfogel@cyclic.com> --- November 1995 */ + +#include <io.h> +#include <stdio.h> +#include <fcntl.h> +#include <malloc.h> +#include <errno.h> +/* <sys/socket.h> wants `off_t': */ +#include <sys/types.h> +/* This should get us ibmtcpip\include\sys\socket.h: */ +#include <sys/socket.h> +#include <assert.h> + +#include "rcmd.h" + +void +init_sockets () +{ + int rc; + + rc = sock_init (); + if (rc != 0) + { + fprintf (stderr, "sock_init() failed -- returned %d!\n", rc); + exit (1); + } +} + + +static int +resolve_address (const char **ahost, struct sockaddr_in *sai) +{ + fprintf (stderr, + "Error: resolve_address() doesn't work.\n"); + exit (1); +} + +static int +bind_and_connect (struct sockaddr_in *server_sai) +{ + fprintf (stderr, + "Error: bind_and_connect() doesn't work.\n"); + exit (1); +} + +static int +rcmd_authenticate (int fd, char *locuser, char *remuser, char *command) +{ + fprintf (stderr, + "Error: rcmd_authenticate() doesn't work.\n"); + exit (1); +} + +int +rcmd (const char **ahost, + unsigned short inport, + char *locuser, + char *remuser, + char *cmd, + int *fd2p) +{ + fprintf (stderr, + "Error: rcmd() doesn't work.\n"); + exit (1); +} diff --git a/gnu/usr.bin/cvs/os2/rcmd.h b/gnu/usr.bin/cvs/os2/rcmd.h new file mode 100644 index 00000000000..2bc915a36bd --- /dev/null +++ b/gnu/usr.bin/cvs/os2/rcmd.h @@ -0,0 +1,30 @@ +/* rcmd.h --- interface to executing commands on remote hosts + Karl Fogel <kfogel@cyclic.com> --- November 1995 */ + +/* Run the command CMD on the host *AHOST, and return a file descriptor for + a bidirectional stream socket connected to the command's standard input + and output. + + rcmd looks up *AHOST using gethostbyname, and sets *AHOST to the host's + canonical name. If *AHOST is not found, rcmd returns -1. + + rcmd connects to the remote host at TCP port INPORT. This should + probably be the "shell" service, port 514. + + LOCUSER is the name of the user on the local machine, and REMUSER is + the name of the user on the remote machine; the remote machine uses this, + along with the source address of the TCP connection, to authenticate + the connection. + + CMD is the command to execute. The remote host will tokenize it any way + it damn well pleases. Welcome to Unix. + + FD2P is a feature we don't support, but there's no point in making mindless + deviations from the interface. Callers should always pass this argument + as zero. */ +extern int rcmd (const char **AHOST, + unsigned short INPORT, + char *LOCUSER, + char *REMUSER, + char *CMD, + int *fd2p); diff --git a/gnu/usr.bin/cvs/os2/run.c b/gnu/usr.bin/cvs/os2/run.c new file mode 100644 index 00000000000..358812b3a1f --- /dev/null +++ b/gnu/usr.bin/cvs/os2/run.c @@ -0,0 +1,602 @@ +/* run.c --- routines for executing subprocesses under OS/2. + + This file is part of GNU CVS. + + GNU CVS is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "cvs.h" + +#define INCL_DOSQUEUES +#define INCL_DOSPROCESS +#define INCL_DOSSESMGR +#include <os2.h> +#include <process.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <fcntl.h> +#include <stdarg.h> +#include <errno.h> +#include <io.h> + +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +static void run_add_arg PROTO((const char *s)); +static void run_init_prog PROTO((void)); + +extern char *strtok (); + +/* + * To exec a program under CVS, first call run_setup() to setup any initial + * arguments. The options to run_setup are essentially like printf(). The + * arguments will be parsed into whitespace separated words and added to the + * global run_argv list. + * + * Then, optionally call run_arg() for each additional argument that you'd like + * to pass to the executed program. + * + * Finally, call run_exec() to execute the program with the specified + * arguments. + * The execvp() syscall will be used, so that the PATH is searched correctly. + * File redirections can be performed in the call to run_exec(). + */ +static char *run_prog; +static char **run_argv; +static int run_argc; +static int run_argc_allocated; + +void +run_setup (const char *fmt,...) +{ + va_list args; + char *cp; + int i; + + run_init_prog (); + + /* clean out any malloc'ed values from run_argv */ + for (i = 0; i < run_argc; i++) + { + if (run_argv[i]) + { + free (run_argv[i]); + run_argv[i] = (char *) 0; + } + } + run_argc = 0; + + /* process the varargs into run_prog */ + va_start (args, fmt); + (void) vsprintf (run_prog, fmt, args); + va_end (args); + + /* put each word into run_argv, allocating it as we go */ + for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t")) + run_add_arg (cp); +} + +void +run_arg (s) + const char *s; +{ + run_add_arg (s); +} + +void +run_args (const char *fmt,...) +{ + va_list args; + + run_init_prog (); + + /* process the varargs into run_prog */ + va_start (args, fmt); + (void) vsprintf (run_prog, fmt, args); + va_end (args); + + /* and add the (single) argument to the run_argv list */ + run_add_arg (run_prog); +} + +/* Return a malloc'd copy of s, with double quotes around it. */ +static char * +quote (const char *s) +{ + size_t s_len = strlen (s); + char *copy = xmalloc (s_len + 3); + char *scan = copy; + + *scan++ = '"'; + strcpy (scan, s); + scan += s_len; + *scan++ = '"'; + *scan++ = '\0'; + + return copy; +} + +static void +run_add_arg (s) + const char *s; +{ + /* allocate more argv entries if we've run out */ + if (run_argc >= run_argc_allocated) + { + run_argc_allocated += 50; + run_argv = (char **) xrealloc ((char *) run_argv, + run_argc_allocated * sizeof (char **)); + } + + if (s) + { + run_argv[run_argc] = (run_argc ? quote (s) : xstrdup (s)); + run_argc++; + } + else + /* not post-incremented on purpose! */ + run_argv[run_argc] = (char *) 0; +} + +static void +run_init_prog () +{ + /* make sure that run_prog is allocated once */ + if (run_prog == (char *) 0) + run_prog = xmalloc (10 * 1024); /* 10K of args for _setup and _arg */ +} + + +int +run_exec (stin, stout, sterr, flags) + char *stin; + char *stout; + char *sterr; + int flags; +{ + int shin, shout, sherr; + int sain, saout, saerr; /* saved handles */ + int mode_out, mode_err; + int status = -1; + int rerrno = 0; + int rval = -1; + void (*old_sigint) (int); + + if (trace) /* if in trace mode */ + { + (void) fprintf (stderr, "-> system("); + run_print (stderr); + (void) fprintf (stderr, ")\n"); + } + if (noexec && (flags & RUN_REALLY) == 0) /* if in noexec mode */ + return (0); + + /* + * start the engine and take off + */ + + /* make sure that we are null terminated, since we didn't calloc */ + run_add_arg ((char *) 0); + + /* setup default file descriptor numbers */ + shin = 0; + shout = 1; + sherr = 2; + + /* set the file modes for stdout and stderr */ + mode_out = mode_err = O_WRONLY | O_CREAT; + mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC); + mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC); + + /* open the files as required, shXX are shadows of stdin... */ + if (stin && (shin = open (stin, O_RDONLY)) == -1) + { + rerrno = errno; + error (0, errno, "cannot open %s for reading (prog %s)", + stin, run_argv[0]); + goto out0; + } + if (stout && (shout = open (stout, mode_out, 0666)) == -1) + { + rerrno = errno; + error (0, errno, "cannot open %s for writing (prog %s)", + stout, run_argv[0]); + goto out1; + } + if (sterr && (flags & RUN_COMBINED) == 0) + { + if ((sherr = open (sterr, mode_err, 0666)) == -1) + { + rerrno = errno; + error (0, errno, "cannot open %s for writing (prog %s)", + sterr, run_argv[0]); + goto out2; + } + } + /* now save the standard handles */ + sain = saout = saerr = -1; + sain = dup( 0); /* dup stdin */ + saout = dup( 1); /* dup stdout */ + saerr = dup( 2); /* dup stderr */ + + /* the new handles will be dup'd to the standard handles + * for the spawn. + */ + + if (shin != 0) + { + (void) dup2 (shin, 0); + (void) close (shin); + } + if (shout != 1) + { + (void) dup2 (shout, 1); + (void) close (shout); + } + if (flags & RUN_COMBINED) + (void) dup2 (1, 2); + else if (sherr != 2) + { + (void) dup2 (sherr, 2); + (void) close (sherr); + } + + /* Ignore signals while we're running this. */ + old_sigint = signal (SIGINT, SIG_IGN); + + /* dup'ing is done. try to run it now */ + rval = spawnvp ( P_WAIT, run_argv[0], run_argv); + + /* Restore signal handling. */ + signal (SIGINT, old_sigint); + + /* restore the original file handles */ + if (sain != -1) { + (void) dup2( sain, 0); /* re-connect stdin */ + (void) close( sain); + } + if (saout != -1) { + (void) dup2( saout, 1); /* re-connect stdout */ + (void) close( saout); + } + if (saerr != -1) { + (void) dup2( saerr, 2); /* re-connect stderr */ + (void) close( saerr); + } + + /* Recognize the return code for a failed subprocess. */ + if (rval == -1) + return 2; + else + return rval; /* return child's exit status */ + + /* error cases */ + /* cleanup the open file descriptors */ + out2: + if (stout) + (void) close (shout); + out1: + if (stin) + (void) close (shin); + + out0: + if (rerrno) + errno = rerrno; + return (status); +} + + +void +run_print (fp) + FILE *fp; +{ + int i; + + for (i = 0; i < run_argc; i++) + { + (void) fprintf (fp, "'%s'", run_argv[i]); + if (i != run_argc - 1) + (void) fprintf (fp, " "); + } +} + +static char * +requote (const char *cmd) +{ + char *requoted = xmalloc (strlen (cmd) + 1); + char *p = requoted; + + strcpy (requoted, cmd); + while ((p = strchr (p, '\'')) != NULL) + { + *p++ = '"'; + } + + return requoted; +} + +FILE * +Popen (cmd, mode) + const char *cmd; + const char *mode; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> Popen(%s,%s)\n", + (server_active) ? 'S' : ' ', cmd, mode); +#else + (void) fprintf (stderr, "-> Popen(%s,%s)\n", cmd, mode); +#endif + + if (noexec) + return (NULL); + + /* If the command string uses single quotes, turn them into + double quotes. */ + { + char *requoted = requote (cmd); + FILE *result = popen (requoted, mode); + free (requoted); + return result; + } +} + + +/* Running children with pipes connected to them. */ + +/* Create a pipe. Set READWRITE[0] to its reading end, and + READWRITE[1] to its writing end. */ + +static int +my_pipe (int *readwrite) +{ + fprintf (stderr, + "Error: my_pipe() is unimplemented.\n"); + exit (1); +} + + +/* Create a child process running COMMAND with IN as its standard input, + and OUT as its standard output. Return a handle to the child, or + INVALID_HANDLE_VALUE. */ +static int +start_child (char *command, int in, int out) +{ + fprintf (stderr, + "Error: start_child() is unimplemented.\n"); + exit (1); +} + + +/* Given an array of arguments that one might pass to spawnv, + construct a command line that one might pass to CreateProcess. + Try to quote things appropriately. */ +static char * +build_command (char **argv) +{ + int len; + + /* Compute the total length the command will have. */ + { + int i; + + len = 0; + for (i = 0; argv[i]; i++) + { + char *p; + + len += 2; /* for the double quotes */ + + for (p = argv[i]; *p; p++) + { + if (*p == '"') + len += 2; + else + len++; + } + } + len++; /* for the space or the '\0' */ + } + + { + char *command = (char *) malloc (len); + int i; + char *p; + + if (! command) + { + errno = ENOMEM; + return command; + } + + p = command; + /* copy each element of argv to command, putting each command + in double quotes, and backslashing any quotes that appear + within an argument. */ + for (i = 0; argv[i]; i++) + { + char *a; + *p++ = '"'; + for (a = argv[i]; *a; a++) + { + if (*a == '"') + *p++ = '\\', *p++ = '"'; + else + *p++ = *a; + } + *p++ = '"'; + *p++ = ' '; + } + p[-1] = '\0'; + + return command; + } +} + + +/* Create an asynchronous child process executing ARGV, + with its standard input and output connected to the + parent with pipes. Set *TO to the file descriptor on + which one writes data for the child; set *FROM to + the file descriptor from which one reads data from the child. + Return the handle of the child process (this is what + _cwait and waitpid expect). */ +int +piped_child (char **argv, int *to, int *from) +{ + fprintf (stderr, + "Error: piped_child() is unimplemented.\n"); + exit (1); +} + +/* + * dir = 0 : main proc writes to new proc, which writes to oldfd + * dir = 1 : main proc reads from new proc, which reads from oldfd + * + * If this returns at all, then it was successful and the return value + * is a file descriptor; else it errors and exits. + */ +int +filter_stream_through_program (int oldfd, int dir, + char **prog, int *pidp) +{ + int newfd; /* Gets set to one end of the pipe and returned. */ + HFILE from, to; + HFILE Old0 = -1, Old1 = -1, Old2 = -1, Tmp; + + if (DosCreatePipe (&from, &to, 4096)) + return FALSE; + + /* Save std{in,out,err} */ + DosDupHandle (STDIN, &Old0); + DosSetFHState (Old1, OPEN_FLAGS_NOINHERIT); + DosDupHandle (STDOUT, &Old1); + DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT); + DosDupHandle (STDERR, &Old2); + DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT); + + /* Redirect std{in,out,err} */ + if (dir) /* Who goes where? */ + { + Tmp = STDIN; + DosDupHandle (oldfd, &Tmp); + Tmp = STDOUT; + DosDupHandle (to, &Tmp); + Tmp = STDERR; + DosDupHandle (to, &Tmp); + + newfd = from; + _setmode (newfd, O_BINARY); + + DosClose (oldfd); + DosClose (to); + DosSetFHState (from, OPEN_FLAGS_NOINHERIT); + } + else + { + Tmp = STDIN; + DosDupHandle (from, &Tmp); + Tmp = STDOUT; + DosDupHandle (oldfd, &Tmp); + Tmp = STDERR; + DosDupHandle (oldfd, &Tmp); + + newfd = to; + _setmode (newfd, O_BINARY); + + DosClose (oldfd); + DosClose (from); + DosSetFHState (to, OPEN_FLAGS_NOINHERIT); + } + + /* Spawn we now our hoary brood. */ + *pidp = spawnvp (P_NOWAIT, prog[0], prog); + + /* Restore std{in,out,err} */ + Tmp = STDIN; + DosDupHandle (Old0, &Tmp); + DosClose (Old0); + Tmp = STDOUT; + DosDupHandle (Old1, &Tmp); + DosClose (Old1); + Tmp = STDERR; + DosDupHandle (Old2, &Tmp); + DosClose (Old2); + + if(*pidp < 0) + { + DosClose (from); + DosClose (to); + error (1, 0, "error spawning %s", prog[0]); + } + + return newfd; +} + + +int +pipe (int *filedesc) +{ + /* todo: actually, we can use DosCreatePipe(). Fix this. */ + fprintf (stderr, + "Error: pipe() should not have been called in client.\n"); + exit (1); +} + + +void +close_on_exec (int fd) +{ + /* Just does nothing for now... */ + + /* Actually, we probably *can* implement this one. Let's see... */ + /* Nope. OS/2 has <fcntl.h>, but no fcntl() ! Wow. */ + /* Well, I'll leave this stuff in for future reference. */ +} + + +/* Actually, we #define sleep() in config.h now. */ +#ifndef sleep +unsigned int +sleep (unsigned int seconds) +{ + /* I don't want to interfere with alarm signals, so I'm going to do + this the nasty way. */ + + time_t base; + time_t tick; + int i; + + /* Init. */ + time (&base); + time (&tick); + + /* Loop until time has passed. */ + while (difftime (tick, base) < seconds) + { + /* This might be more civilized than calling time over and over + again. */ + for (i = 0; i < 10000; i++) + ; + time (&tick); + } + + return 0; +} +#endif /* sleep */ diff --git a/gnu/usr.bin/cvs/os2/strippath.c b/gnu/usr.bin/cvs/os2/strippath.c new file mode 100644 index 00000000000..8a61a1ed393 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/strippath.c @@ -0,0 +1,60 @@ +/* strippath.c -- remove unnecessary components from a path specifier + Copyright (C) 1992 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <string.h> + +static void remove_component(char *beginc, char *endc); +void strip_trailing_slashes(char *path); + +/* Remove unnecessary components from PATH. */ + +void +strip_path (path) + char *path; +{ + int stripped = 0; + char *cp, *slash; + + for (cp = path; *(slash = cp + strcspn (cp, "/\\")) != '\0'; cp = slash) + { + *slash = '\0'; + if ((!*cp && (cp != path || stripped)) || + strcmp(cp, ".") == 0 || strcmp(cp, "/") == 0) + { + stripped = 1; + remove_component(cp, slash); + slash = cp; + } + else + { + *slash++ = '/'; + } + } + strip_trailing_slashes(path); +} + +/* Remove the component delimited by BEGINC and ENDC from the path */ + +static void +remove_component (beginc, endc) + char *beginc; + char *endc; +{ + for (endc++; *endc; endc++) + *beginc++ = *endc; + *beginc = '\0'; +} diff --git a/gnu/usr.bin/cvs/os2/stripslash.c b/gnu/usr.bin/cvs/os2/stripslash.c new file mode 100644 index 00000000000..629dad9393d --- /dev/null +++ b/gnu/usr.bin/cvs/os2/stripslash.c @@ -0,0 +1,31 @@ +/* stripslash.c -- remove trailing slashes from a string + Copyright (C) 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Remove trailing slashes from PATH. */ + +void +strip_trailing_slashes (path) + char *path; +{ + int last; + + last = strlen (path) - 1; + while (last > 0 && (path[last] == '/' || path[last] == '\\')) + path[last--] = '\0'; +} diff --git a/gnu/usr.bin/cvs/os2/tcpip.h b/gnu/usr.bin/cvs/os2/tcpip.h new file mode 100644 index 00000000000..4d19448650a --- /dev/null +++ b/gnu/usr.bin/cvs/os2/tcpip.h @@ -0,0 +1,107 @@ +/**************************************************************** + * + * TCPIP.H - Portable TCP/IP header file + * + * TCP/IP on OS/2 is an add-on and thus is not fully integrated + * with the operating system. To ensure portability, follow + * these rules: + * + * * Always call SockInit() at the beginning of your program + * and check that it returns TRUE. + * + * * Use SockSend() & SockRecv() instead of read(), write(), + * send(), or recv() when working with sockets. + * + * * Use SockClose() instead of close() with sockets. + * + * * Use SOCK_ERRNO when using functions that use or return + * sockets, such as SockSend() or accept(). + * + * * Use HOST_ERRNO when using gethostbyname() or gethostbyaddr() + * functions. + * + * * As far as I can tell, getservbyname() and related functions + * never set any error variable. + * + * * Use SockStrError() & HostStrError() to convert SOCK_ERRNO + * and HOST_ERRNO to error strings. + * + * * In .MAK files, include $(TCPIP_MAK) & use $(TCPIPLIB) + * when linking applications using TCP/IP. + * + ****************************************************************/ + +#if !defined( IN_TCPIP_H ) +#define IN_TCPIP_H + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <netdb.h> +#include <errno.h> + +#if defined( TCPIP_IBM ) +# include <types.h> +# if !defined( TCPIP_IBM_NOHIDE ) +# define send IbmSockSend +# define recv IbmSockRecv +# endif +#endif + +#if defined( TCPIP_IBM ) +# define BSD_SELECT +# include <sys/select.h> +# include <sys/time.h> +# include <nerrno.h> +# include <utils.h> +# if defined( MICROSOFT ) +# define SOCK_ERRNO (tcperrno()) +# else +# define SOCK_ERRNO (sock_errno()) +# endif +# define HOST_ERRNO (h_errno) +# define SockClose(S) soclose(S) +# define SockInit() (!sock_init()) +# define SockSend IbmSockSend +# define SockRecv IbmSockRecv + +const char *HostStrError(int HostErrno); +const char *SockStrError(int SockErrno); + +int IbmSockSend (int Socket, const void *Buffer, int Len, int Flags); +int IbmSockRecv (int Socket, const void *Buffer, int Len, int Flags); + +#if !defined( h_errno ) +extern int h_errno; /* IBM forgot to declare this in current header files */ +#endif + +#elif defined( __unix ) +# if defined( sgi ) /* SGI incorrectly defines FD_ZERO in sys/select.h */ +# include <bstring.h> +# endif +# if defined( sunos ) +extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +# else +# include <sys/select.h> +# endif +# include <sys/time.h> +# include <errno.h> +# include <arpa/inet.h> +# define SOCK_ERRNO errno +# define HOST_ERRNO h_errno +# define SockClose(S) close(S) +# define SockInit() TRUE +# define SockSend send +# define SockRecv recv +# define SockStrError(E) strerror(E) + +const char *HostStrError( int HostErrno ); + +#else +# error Undefined version of TCP/IP specified + +#endif + +#endif diff --git a/gnu/usr.bin/cvs/os2/test-makefile b/gnu/usr.bin/cvs/os2/test-makefile new file mode 100644 index 00000000000..d6179ee386e --- /dev/null +++ b/gnu/usr.bin/cvs/os2/test-makefile @@ -0,0 +1,40 @@ +# I use this for single compilation while porting; once the port is +# done it can be removed. + +THIS_BASENAME = ../src/add + +CC = icc + +LIB = s:\ibmcpp\lib;s:\toolkt21\os2lib; +CINC = -Is:/ibmcpp/include -Is:/toolkt21/c/os2h +CFLAGS = -C+ +CFLAGS += -W3 -Wpro+rea+tru+use+ -Ti+ -Ss+ -Gd+ -Gm+ -G4 -Q+ -Sm ${CINC} +CFLAGS += -DIBM_CPP -DHAVE_CONFIG_H + +# translation of most important CFLAGS -- others are trivial +# ICC sez -C+ -W3 -Ti+ ${CINC} +# GCC sez -c -Wall -g ${CINC} + +# "-I../os2" below ought to be equivalent to "-I." +CFLAGS += -I../os2 -I../lib -I../src + +# Preprocesses to stdout. +# CFLAGS += -Pd+ + +# TCP/IP stuff +TCPIPLIB = s:\ibmtcpip\lib\tcp32dll.lib s:\ibmtcpip\lib\so32dll.lib porttcp.obj + +# We probably don't need these. +# RPCLIB = s:\ibmtcpip\lib\rpc32dll.lib +# FTPLIB = s:\ibmtcpip\lib\ftpapi.lib + +CFLAGS += -DTCPIP_IBM -Is:\ibmtcpip\include + +all: ${THIS_BASENAME}.obj +# all: ${THIS_BASENAME}.exe + +${THIS_BASENAME}.obj: ${THIS_BASENAME}.c + ${CC} ${CFLAGS} /Fo${THIS_BASENAME}.obj ${THIS_BASENAME}.c + +${THIS_BASENAME}.exe: ${THIS_BASENAME}.c + ${CC} ${CFLAGS} /Fe${THIS_BASENAME}.exe ${THIS_BASENAME}.c diff --git a/gnu/usr.bin/cvs/os2/waitpid.c b/gnu/usr.bin/cvs/os2/waitpid.c new file mode 100644 index 00000000000..2b64f5dcce2 --- /dev/null +++ b/gnu/usr.bin/cvs/os2/waitpid.c @@ -0,0 +1,36 @@ +/* waitpid.c --- waiting for process termination, under OS/2 + Karl Fogel <kfogel@cyclic.com> --- November 1995 */ + +#include <assert.h> +#include <stdio.h> +#include <process.h> +#include <errno.h> + +#include "config.h" + +/* Wait for the process PID to exit. Put the return status in *statusp. + OPTIONS is not supported yet under OS/2. We hope it's always zero. */ +pid_t waitpid (pid, statusp, options) + pid_t pid; + int *statusp; + int options; +{ + pid_t rc; + + /* We don't know how to deal with any options yet. */ + assert (options == 0); + + rc = _cwait (statusp, pid, WAIT_CHILD); + + if (rc == -1) + { + if (errno == ECHILD) + return pid; + else + return -1; + } + else if (rc == pid) + return pid; + else + return -1; +} |