summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cvs/lib/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cvs/lib/subr.c')
-rw-r--r--gnu/usr.bin/cvs/lib/subr.c912
1 files changed, 912 insertions, 0 deletions
diff --git a/gnu/usr.bin/cvs/lib/subr.c b/gnu/usr.bin/cvs/lib/subr.c
new file mode 100644
index 0000000..2b728c2
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/subr.c
@@ -0,0 +1,912 @@
+/*
+ * 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.3 kit.
+ *
+ * Various useful functions for the CVS support code.
+ */
+
+#include "cvs.h"
+
+#ifdef _MINIX
+#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
+#endif
+
+#ifndef VPRINTF_MISSING
+#if __STDC__
+#include <stdarg.h>
+#define VA_START(args, lastarg) va_start(args, lastarg)
+#else
+#include <varargs.h>
+#define VA_START(args, lastarg) va_start(args)
+#endif
+#else
+#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif
+
+#ifndef lint
+static char rcsid[] = "@(#)subr.c 1.52 92/03/31";
+#endif
+
+#if __STDC__
+static void run_add_arg (char *s);
+static void run_init_prog (void);
+#else
+static void run_add_arg ();
+static void run_init_prog ();
+#endif /* __STDC__ */
+
+extern char *getlogin ();
+extern char *strtok ();
+
+/*
+ * Copies "from" to "to". mallocs a buffer large enough to hold the entire
+ * file and does one read/one write to do the copy. This is reasonable,
+ * since source files are typically not too large.
+ */
+void
+copy_file (from, to)
+ char *from;
+ char *to;
+{
+ struct stat sb;
+ struct utimbuf t;
+ int fdin, fdout;
+ char *buf;
+
+ if (trace)
+ (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to);
+ if (noexec)
+ return;
+
+ if ((fdin = open (from, O_RDONLY)) < 0)
+ error (1, errno, "cannot open %s for copying", from);
+ if (fstat (fdin, &sb) < 0)
+ error (1, errno, "cannot fstat %s", from);
+ if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
+ error (1, errno, "cannot create %s for copying", to);
+ if (sb.st_size > 0)
+ {
+ buf = xmalloc ((int) sb.st_size);
+ if (read (fdin, buf, (int) sb.st_size) != (int) sb.st_size)
+ error (1, errno, "cannot read file %s for copying", from);
+ if (write (fdout, buf, (int) sb.st_size) != (int) sb.st_size
+#ifndef FSYNC_MISSING
+ || fsync (fdout) == -1
+#endif
+ )
+ {
+ error (1, errno, "cannot write file %s for copying", to);
+ }
+ free (buf);
+ }
+ (void) close (fdin);
+ 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 */
+ t.actime = sb.st_atime;
+ t.modtime = sb.st_mtime;
+ (void) utime (to, &t);
+}
+
+/*
+ * Returns non-zero if the argument file is a directory, or is a symbolic
+ * link which points to a directory.
+ */
+int
+isdir (file)
+ 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)
+ 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)
+ 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)
+ 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)
+ char *file;
+{
+ return (access (file, W_OK) != -1);
+}
+
+/*
+ * Open a file and die if it fails
+ */
+FILE *
+open_file (name, mode)
+ char *name;
+ char *mode;
+{
+ FILE *fp;
+
+ if ((fp = fopen (name, mode)) == NULL)
+ error (1, errno, "cannot open %s", name);
+ return (fp);
+}
+
+/*
+ * Open a file if allowed and return.
+ */
+FILE *
+Fopen (name, mode)
+ char *name;
+ char *mode;
+{
+ if (trace)
+ (void) fprintf (stderr, "-> fopen(%s,%s)\n", name, mode);
+ if (noexec)
+ return (NULL);
+
+ return (fopen (name, mode));
+}
+
+/*
+ * Make a directory and die if it fails
+ */
+void
+make_directory (name)
+ char *name;
+{
+ struct stat buf;
+
+ if (stat (name, &buf) == 0)
+ {
+ if (S_ISDIR (buf.st_mode))
+ {
+ if (access (name, (R_OK | W_OK | X_OK)) == 0)
+ {
+ error (0, 0, "Directory %s already exists", name);
+ return;
+ }
+ else
+ {
+ error (0, 0,
+ "Directory %s already exists but is protected from you",
+ name);
+ }
+ }
+ else
+ error (0, 0, "%s already exists but is not a directory", name);
+ }
+ if (!noexec && mkdir (name, 0777) < 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)
+ char *name;
+{
+ char *cp;
+
+ if (noexec)
+ return;
+
+ if (mkdir (name, 0777) == 0 || errno == EEXIST)
+ return;
+ if (errno != ENOENT)
+ {
+ error (0, errno, "cannot make path to %s", name);
+ return;
+ }
+ if ((cp = rindex (name, '/')) == NULL)
+ return;
+ *cp = '\0';
+ make_directories (name);
+ *cp++ = '/';
+ if (*cp == '\0')
+ return;
+ (void) mkdir (name, 0777);
+}
+
+/*
+ * malloc some data and die if it fails
+ */
+char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *cp;
+
+ if (bytes <= 0)
+ error (1, 0, "bad malloc size %d", bytes);
+ if ((cp = malloc ((unsigned) bytes)) == NULL)
+ error (1, 0, "malloc failed");
+ return (cp);
+}
+
+/*
+ * realloc data and die if it fails [I've always wanted to have "realloc" do
+ * a "malloc" if the argument is NULL, but you can't depend on it. Here, I
+ * can *force* it.
+ */
+char *
+xrealloc (ptr, bytes)
+ char *ptr;
+ int bytes;
+{
+ char *cp;
+
+ if (!ptr)
+ return (xmalloc (bytes));
+
+ if (bytes <= 0)
+ error (1, 0, "bad realloc size %d", bytes);
+ if ((cp = realloc (ptr, (unsigned) bytes)) == NULL)
+ error (1, 0, "realloc failed");
+ return (cp);
+}
+
+/*
+ * Duplicate a string, calling xmalloc to allocate some dynamic space
+ */
+char *
+xstrdup (str)
+ char *str;
+{
+ char *s;
+
+ if (str == NULL)
+ return ((char *) NULL);
+ s = xmalloc (strlen (str) + 1);
+ (void) strcpy (s, str);
+ return (s);
+}
+
+/*
+ * 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;
+{
+ struct stat sb;
+ int mode, oumask;
+
+ if (stat (fname, &sb) < 0)
+ {
+ if (!noexec)
+ error (0, errno, "cannot stat %s", fname);
+ return;
+ }
+ if (writable)
+ {
+ oumask = umask (0);
+ (void) umask (oumask);
+ mode = sb.st_mode | ((S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask);
+ }
+ else
+ {
+ mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH);
+ }
+
+ if (trace)
+ (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, mode);
+ if (noexec)
+ return;
+
+ if (chmod (fname, mode) < 0)
+ error (0, errno, "cannot change mode of file %s", fname);
+}
+
+/*
+ * Rename a file and die if it fails
+ */
+void
+rename_file (from, to)
+ char *from;
+ char *to;
+{
+ if (trace)
+ (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to);
+ if (noexec)
+ return;
+
+ if (rename (from, to) < 0)
+ error (1, errno, "cannot rename file %s to %s", from, to);
+}
+
+/*
+ * link a file, if possible.
+ */
+int
+link_file (from, to)
+ char *from, *to;
+{
+ if (trace)
+ (void) fprintf (stderr, "-> link(%s,%s)\n", from, to);
+ if (noexec)
+ return (0);
+
+ return (link (from, to));
+}
+
+/*
+ * unlink a file, if possible.
+ */
+int
+unlink_file (f)
+ char *f;
+{
+ if (trace)
+ (void) fprintf (stderr, "-> unlink(%s)\n", f);
+ if (noexec)
+ return (0);
+
+ return (unlink (f));
+}
+
+/*
+ * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
+ *
+ * mallocs a buffer large enough to hold the entire file and does two reads to
+ * load the buffer and calls bcmp to do the cmp. This is reasonable, since
+ * source files are typically not too large.
+ */
+int
+xcmp (file1, file2)
+ char *file1;
+ char *file2;
+{
+ register char *buf1, *buf2;
+ struct stat sb;
+ off_t size;
+ int ret, fd1, fd2;
+
+ if ((fd1 = open (file1, O_RDONLY)) < 0)
+ error (1, errno, "cannot open file %s for comparing", file1);
+ if ((fd2 = open (file2, O_RDONLY)) < 0)
+ error (1, errno, "cannot open file %s for comparing", file2);
+ if (fstat (fd1, &sb) < 0)
+ error (1, errno, "cannot fstat %s", file1);
+ size = sb.st_size;
+ if (fstat (fd2, &sb) < 0)
+ error (1, errno, "cannot fstat %s", file2);
+ if (size == sb.st_size)
+ {
+ if (size == 0)
+ ret = 0;
+ else
+ {
+ buf1 = xmalloc ((int) size);
+ buf2 = xmalloc ((int) size);
+ if (read (fd1, buf1, (int) size) != (int) size)
+ error (1, errno, "cannot read file %s cor comparing", file1);
+ if (read (fd2, buf2, (int) size) != (int) size)
+ error (1, errno, "cannot read file %s for comparing", file2);
+ ret = bcmp (buf1, buf2, (int) size);
+ free (buf1);
+ free (buf2);
+ }
+ }
+ else
+ ret = 1;
+ (void) close (fd1);
+ (void) close (fd2);
+ return (ret);
+}
+
+/*
+ * Recover the space allocated by Find_Names() and line2argv()
+ */
+void
+free_names (pargc, argv)
+ int *pargc;
+ char *argv[];
+{
+ register int i;
+
+ for (i = 0; i < *pargc; i++)
+ { /* only do through *pargc */
+ free (argv[i]);
+ }
+ *pargc = 0; /* and set it to zero when done */
+}
+
+/*
+ * Convert a line into argc/argv components and return the result in the
+ * arguments as passed. Use free_names() to return the memory allocated here
+ * back to the free pool.
+ */
+void
+line2argv (pargc, argv, line)
+ int *pargc;
+ char *argv[];
+ char *line;
+{
+ char *cp;
+
+ *pargc = 0;
+ for (cp = strtok (line, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
+ {
+ argv[*pargc] = xstrdup (cp);
+ (*pargc)++;
+ }
+}
+
+/*
+ * Returns the number of dots ('.') found in an RCS revision number
+ */
+int
+numdots (s)
+ char *s;
+{
+ char *cp;
+ int dots = 0;
+
+ for (cp = s; *cp; cp++)
+ {
+ if (*cp == '.')
+ dots++;
+ }
+ return (dots);
+}
+
+/*
+ * Get the caller's login from his uid. If the real uid is "root" try LOGNAME
+ * USER or getlogin(). If getlogin() and getpwuid() both fail, return
+ * the uid as a string.
+ */
+char *
+getcaller ()
+{
+ static char uidname[20];
+ struct passwd *pw;
+ char *name;
+ int uid;
+
+ uid = getuid ();
+ if (uid == 0)
+ {
+ /* super-user; try getlogin() to distinguish */
+ if (((name = getenv("LOGNAME")) || (name = getenv("USER")) ||
+ (name = getlogin ())) && *name)
+ return (name);
+ }
+ if ((pw = (struct passwd *) getpwuid (uid)) == NULL)
+ {
+ (void) sprintf (uidname, "uid%d", uid);
+ return (uidname);
+ }
+ return (pw->pw_name);
+}
+
+/*
+ * 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;
+
+/* VARARGS */
+#if !defined (VPRINTF_MISSING) && __STDC__
+void
+run_setup (char *fmt,...)
+#else
+void
+run_setup (fmt, va_alist)
+ char *fmt;
+ va_dcl
+
+#endif
+{
+#ifndef VPRINTF_MISSING
+ va_list args;
+
+#endif
+ 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 */
+#ifndef VPRINTF_MISSING
+ VA_START (args, fmt);
+ (void) vsprintf (run_prog, fmt, args);
+ va_end (args);
+#else
+ (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif
+
+ /* 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)
+ char *s;
+{
+ run_add_arg (s);
+}
+
+/* VARARGS */
+#if !defined (VPRINTF_MISSING) && __STDC__
+void
+run_args (char *fmt,...)
+#else
+void
+run_args (fmt, va_alist)
+ char *fmt;
+ va_dcl
+
+#endif
+{
+#ifndef VPRINTF_MISSING
+ va_list args;
+
+#endif
+
+ run_init_prog ();
+
+ /* process the varargs into run_prog */
+#ifndef VPRINTF_MISSING
+ VA_START (args, fmt);
+ (void) vsprintf (run_prog, fmt, args);
+ va_end (args);
+#else
+ (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif
+
+ /* and add the (single) argument to the run_argv list */
+ run_add_arg (run_prog);
+}
+
+static void
+run_add_arg (s)
+ 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++] = xstrdup (s);
+ else
+ run_argv[run_argc] = (char *) 0;/* not post-incremented on purpose! */
+}
+
+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 mode_out, mode_err;
+ int status = -1;
+ int rerrno = 0;
+ int pid, w;
+
+#ifdef POSIX
+ sigset_t sigset_mask, sigset_omask;
+ struct sigaction act, iact, qact;
+
+#else
+#ifdef BSD_SIGNALS
+ int mask;
+ struct sigvec vec, ivec, qvec;
+
+#else
+ SIGTYPE (*istat) (), (*qstat) ();
+#endif
+#endif
+
+ if (trace)
+ {
+ (void) fprintf (stderr, "-> system(");
+ run_print (stderr);
+ (void) fprintf (stderr, ")\n");
+ }
+ if (noexec && (flags & RUN_REALLY) == 0)
+ return (0);
+
+ /* 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);
+
+ 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;
+ }
+ }
+
+ /* The output files, if any, are now created. Do the fork and dups */
+#ifdef VFORK_MISSING
+ pid = fork ();
+#else
+ pid = vfork ();
+#endif
+ if (pid == 0)
+ {
+ 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);
+ }
+
+ /* dup'ing is done. try to run it now */
+ (void) execvp (run_argv[0], run_argv);
+ _exit (127);
+ }
+ else if (pid == -1)
+ {
+ rerrno = errno;
+ goto out;
+ }
+
+ /* the parent. Ignore some signals for now */
+#ifdef POSIX
+ if (flags & RUN_SIGIGNORE)
+ {
+ act.sa_handler = SIG_IGN;
+ (void) sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ (void) sigaction (SIGINT, &act, &iact);
+ (void) sigaction (SIGQUIT, &act, &qact);
+ }
+ else
+ {
+ (void) sigemptyset (&sigset_mask);
+ (void) sigaddset (&sigset_mask, SIGINT);
+ (void) sigaddset (&sigset_mask, SIGQUIT);
+ (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask);
+ }
+#else
+#ifdef BSD_SIGNALS
+ if (flags & RUN_SIGIGNORE)
+ {
+ bzero ((char *) &vec, sizeof (vec));
+ vec.sv_handler = SIG_IGN;
+ (void) sigvec (SIGINT, &vec, &ivec);
+ (void) sigvec (SIGQUIT, &vec, &qvec);
+ }
+ else
+ mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
+#else
+ istat = signal (SIGINT, SIG_IGN);
+ qstat = signal (SIGQUIT, SIG_IGN);
+#endif
+#endif
+
+ /* wait for our process to die and munge return status */
+#ifdef POSIX
+ while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+#else
+ while ((w = wait (&status)) != pid)
+ {
+ if (w == -1 && errno != EINTR)
+ break;
+ }
+#endif
+ if (w == -1)
+ {
+ status = -1;
+ rerrno = errno;
+ }
+ else if (WIFEXITED (status))
+ status = WEXITSTATUS (status);
+ else if (WIFSIGNALED (status))
+ {
+ if (WTERMSIG (status) == SIGPIPE)
+ error (1, 0, "broken pipe");
+ status = 2;
+ }
+ else
+ status = 1;
+
+ /* restore the signals */
+#ifdef POSIX
+ if (flags & RUN_SIGIGNORE)
+ {
+ (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL);
+ (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL);
+ }
+ else
+ (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL);
+#else
+#ifdef BSD_SIGNALS
+ if (flags & RUN_SIGIGNORE)
+ {
+ (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL);
+ (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL);
+ }
+ else
+ (void) sigsetmask (mask);
+#else
+ (void) signal (SIGINT, istat);
+ (void) signal (SIGQUIT, qstat);
+#endif
+#endif
+
+ /* cleanup the open file descriptors */
+ out:
+ if (sterr)
+ (void) close (sherr);
+ 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, " ");
+ }
+}
+
+FILE *
+Popen (cmd, mode)
+ char *cmd, *mode;
+{
+ if (trace)
+ (void) fprintf (stderr, "-> Popen(%s,%s)\n", cmd, mode);
+ if (noexec)
+ return (NULL);
+ return (popen (cmd, mode));
+}
+
+#ifdef lint
+#ifndef __GNUC__
+/* ARGSUSED */
+time_t
+get_date (date, now)
+ char *date;
+ struct timeb *now;
+{
+ time_t foo = 0;
+
+ return (foo);
+}
+#endif
+#endif
OpenPOWER on IntegriCloud