summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/vers_ts.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-08-20 23:46:10 +0000
committerpeter <peter@FreeBSD.org>1996-08-20 23:46:10 +0000
commit8982e501c77217c860f79bba431f46a62b607a21 (patch)
tree70187fdf5be4cbefd0baf46bddac7e5e32c13c24 /contrib/cvs/src/vers_ts.c
parent01ee40fd6a76f6ff7ef247fc1b2cf6e337f216c5 (diff)
downloadFreeBSD-src-8982e501c77217c860f79bba431f46a62b607a21.zip
FreeBSD-src-8982e501c77217c860f79bba431f46a62b607a21.tar.gz
Import of slightly trimmed cvs-1.8 distribution. Generated files
and non-unix code has been left out.
Diffstat (limited to 'contrib/cvs/src/vers_ts.c')
-rw-r--r--contrib/cvs/src/vers_ts.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
new file mode 100644
index 0000000..34983a1
--- /dev/null
+++ b/contrib/cvs/src/vers_ts.c
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+#include "cvs.h"
+
+#ifdef SERVER_SUPPORT
+static void time_stamp_server PROTO((char *, Vers_TS *));
+#endif
+
+/*
+ * Fill in and return a Vers_TS structure "user" is the name of the local
+ * file; entries is the entries file - preparsed for our pleasure. rcs is
+ * the current source control file - preparsed for our pleasure.
+ */
+Vers_TS *
+Version_TS (repository, options, tag, date, user, force_tag_match,
+ set_time, entries, rcs)
+ char *repository;
+ char *options;
+ char *tag;
+ char *date;
+ char *user;
+ int force_tag_match;
+ int set_time;
+ List *entries;
+ RCSNode *rcs;
+{
+ Node *p;
+ RCSNode *rcsdata;
+ Vers_TS *vers_ts;
+ struct stickydirtag *sdtp;
+
+ /* get a new Vers_TS struct */
+ vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS));
+ memset ((char *) vers_ts, 0, sizeof (*vers_ts));
+
+ /*
+ * look up the entries file entry and fill in the version and timestamp
+ * if entries is NULL, there is no entries file so don't bother trying to
+ * look it up (used by checkout -P)
+ */
+ if (entries == NULL)
+ {
+ sdtp = NULL;
+ p = NULL;
+ }
+ else
+ {
+ p = findnode_fn (entries, user);
+ sdtp = (struct stickydirtag *) entries->list->data; /* list-private */
+ }
+
+ if (p != NULL)
+ {
+ Entnode *entdata = (Entnode *) p->data;
+
+ vers_ts->vn_user = xstrdup (entdata->version);
+ vers_ts->ts_rcs = xstrdup (entdata->timestamp);
+ vers_ts->ts_conflict = xstrdup (entdata->conflict);
+ if (!tag)
+ {
+ if (!(sdtp && sdtp->aflag))
+ vers_ts->tag = xstrdup (entdata->tag);
+ }
+ if (!date)
+ {
+ if (!(sdtp && sdtp->aflag))
+ vers_ts->date = xstrdup (entdata->date);
+ }
+ if (!options || (options && *options == '\0'))
+ {
+ if (!(sdtp && sdtp->aflag))
+ vers_ts->options = xstrdup (entdata->options);
+ }
+ vers_ts->entdata = entdata;
+ }
+
+ /*
+ * -k options specified on the command line override (and overwrite)
+ * options stored in the entries file
+ */
+ if (options)
+ vers_ts->options = xstrdup (options);
+ else if (!vers_ts->options)
+ {
+ if (sdtp && sdtp->aflag == 0)
+ vers_ts->options = xstrdup (sdtp->options);
+ else if (rcs != NULL)
+ {
+ /* If no keyword expansion was specified on command line,
+ use whatever was in the rcs file (if there is one). This
+ is how we, if we are the server, tell the client whether
+ a file is binary. */
+ char *rcsexpand = RCS_getexpand (rcs);
+ if (rcsexpand != NULL)
+ {
+ vers_ts->options = xmalloc (strlen (rcsexpand) + 3);
+ strcpy (vers_ts->options, "-k");
+ strcat (vers_ts->options, rcsexpand);
+ }
+ }
+ }
+ if (!vers_ts->options)
+ vers_ts->options = xstrdup ("");
+
+ /*
+ * if tags were specified on the command line, they override what is in
+ * the Entries file
+ */
+ if (tag || date)
+ {
+ vers_ts->tag = xstrdup (tag);
+ vers_ts->date = xstrdup (date);
+ }
+ else if (!vers_ts->entdata && (sdtp && sdtp->aflag == 0))
+ {
+ if (!vers_ts->tag)
+ vers_ts->tag = xstrdup (sdtp->tag);
+ if (!vers_ts->date)
+ vers_ts->date = xstrdup (sdtp->date);
+ }
+
+ /* Now look up the info on the source controlled file */
+ if (rcs != NULL)
+ {
+ rcsdata = rcs;
+ rcsdata->refcount++;
+ }
+ else if (repository != NULL)
+ rcsdata = RCS_parse (user, repository);
+ else
+ rcsdata = NULL;
+
+ if (rcsdata != NULL)
+ {
+ /* squirrel away the rcsdata pointer for others */
+ vers_ts->srcfile = rcsdata;
+
+ if (vers_ts->tag && strcmp (vers_ts->tag, TAG_BASE) == 0)
+ {
+ vers_ts->vn_rcs = xstrdup (vers_ts->vn_user);
+ vers_ts->vn_tag = xstrdup (vers_ts->vn_user);
+ }
+ else
+ {
+ vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag,
+ vers_ts->date, force_tag_match, 1);
+ if (vers_ts->vn_rcs == NULL)
+ vers_ts->vn_tag = NULL;
+ else
+ {
+ char *colon = strchr (vers_ts->vn_rcs, ':');
+ if (colon)
+ {
+ vers_ts->vn_tag = xstrdup (colon+1);
+ *colon = '\0';
+ }
+ else
+ vers_ts->vn_tag = xstrdup (vers_ts->vn_rcs);
+ }
+ }
+
+ /*
+ * If the source control file exists and has the requested revision,
+ * get the Date the revision was checked in. If "user" exists, set
+ * its mtime.
+ */
+ if (set_time)
+ {
+ struct utimbuf t;
+
+ memset ((char *) &t, 0, sizeof (t));
+ if (vers_ts->vn_rcs &&
+ (t.actime = t.modtime = RCS_getrevtime (rcsdata,
+ vers_ts->vn_rcs, (char *) 0, 0)) != -1)
+ (void) utime (user, &t);
+ }
+ }
+
+ /* get user file time-stamp in ts_user */
+ if (entries != (List *) NULL)
+ {
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ time_stamp_server (user, vers_ts);
+ else
+#endif
+ vers_ts->ts_user = time_stamp (user);
+ }
+
+ return (vers_ts);
+}
+
+#ifdef SERVER_SUPPORT
+
+/* Set VERS_TS->TS_USER to time stamp for FILE. */
+
+/* Separate these out to keep the logic below clearer. */
+#define mark_lost(V) ((V)->ts_user = 0)
+#define mark_unchanged(V) ((V)->ts_user = xstrdup ((V)->ts_rcs))
+
+static void
+time_stamp_server (file, vers_ts)
+ char *file;
+ Vers_TS *vers_ts;
+{
+ struct stat sb;
+ char *cp;
+
+ if (stat (file, &sb) < 0)
+ {
+ if (! existence_error (errno))
+ error (1, errno, "cannot stat temp file");
+ if (use_unchanged)
+ {
+ /* Missing file means lost or unmodified; check entries
+ file to see which.
+
+ XXX FIXME - If there's no entries file line, we
+ wouldn't be getting the file at all, so consider it
+ lost. I don't know that that's right, but it's not
+ clear to me that either choice is. Besides, would we
+ have an RCS string in that case anyways? */
+ if (vers_ts->entdata == NULL)
+ mark_lost (vers_ts);
+ else if (vers_ts->entdata->timestamp
+ && vers_ts->entdata->timestamp[0] == '=')
+ mark_unchanged (vers_ts);
+ else
+ mark_lost (vers_ts);
+ }
+ else
+ {
+ /* Missing file in the temp directory means that the file
+ was not modified. */
+ mark_unchanged (vers_ts);
+ }
+ }
+ else if (sb.st_mtime == 0)
+ {
+ if (use_unchanged)
+ /* We shouldn't reach this case any more! */
+ abort ();
+
+ /* Special code used by server.c to indicate the file was lost. */
+ mark_lost (vers_ts);
+ }
+ else
+ {
+ struct tm *tm_p;
+ struct tm local_tm;
+
+ vers_ts->ts_user = xmalloc (25);
+ /* We want to use the same timestamp format as is stored in the
+ st_mtime. For unix (and NT I think) this *must* be universal
+ time (UT), so that files don't appear to be modified merely
+ because the timezone has changed. For VMS, or hopefully other
+ systems where gmtime returns NULL, the modification time is
+ stored in local time, and therefore it is not possible to cause
+ st_mtime to be out of sync by changing the timezone. */
+ tm_p = gmtime (&sb.st_mtime);
+ if (tm_p)
+ {
+ memcpy (&local_tm, tm_p, sizeof (local_tm));
+ cp = asctime (&local_tm); /* copy in the modify time */
+ }
+ else
+ cp = ctime (&sb.st_mtime);
+
+ cp[24] = 0;
+ (void) strcpy (vers_ts->ts_user, cp);
+ }
+}
+
+#endif /* SERVER_SUPPORT */
+/*
+ * Gets the time-stamp for the file "file" and returns it in space it
+ * allocates
+ */
+char *
+time_stamp (file)
+ char *file;
+{
+ struct stat sb;
+ char *cp;
+ char *ts;
+
+ if (stat (file, &sb) < 0)
+ {
+ ts = NULL;
+ }
+ else
+ {
+ struct tm *tm_p;
+ struct tm local_tm;
+ ts = xmalloc (25);
+ /* We want to use the same timestamp format as is stored in the
+ st_mtime. For unix (and NT I think) this *must* be universal
+ time (UT), so that files don't appear to be modified merely
+ because the timezone has changed. For VMS, or hopefully other
+ systems where gmtime returns NULL, the modification time is
+ stored in local time, and therefore it is not possible to cause
+ st_mtime to be out of sync by changing the timezone. */
+ tm_p = gmtime (&sb.st_mtime);
+ if (tm_p)
+ {
+ memcpy (&local_tm, tm_p, sizeof (local_tm));
+ cp = asctime (&local_tm); /* copy in the modify time */
+ }
+ else
+ cp = ctime(&sb.st_mtime);
+
+ cp[24] = 0;
+ (void) strcpy (ts, cp);
+ }
+
+ return (ts);
+}
+
+/*
+ * free up a Vers_TS struct
+ */
+void
+freevers_ts (versp)
+ Vers_TS **versp;
+{
+ if ((*versp)->srcfile)
+ freercsnode (&((*versp)->srcfile));
+ if ((*versp)->vn_user)
+ free ((*versp)->vn_user);
+ if ((*versp)->vn_rcs)
+ free ((*versp)->vn_rcs);
+ if ((*versp)->vn_tag)
+ free ((*versp)->vn_tag);
+ if ((*versp)->ts_user)
+ free ((*versp)->ts_user);
+ if ((*versp)->ts_rcs)
+ free ((*versp)->ts_rcs);
+ if ((*versp)->options)
+ free ((*versp)->options);
+ if ((*versp)->tag)
+ free ((*versp)->tag);
+ if ((*versp)->date)
+ free ((*versp)->date);
+ if ((*versp)->ts_conflict)
+ free ((*versp)->ts_conflict);
+ free ((char *) *versp);
+ *versp = (Vers_TS *) NULL;
+}
OpenPOWER on IntegriCloud