/* * 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. */ #include "cvs.h" #ifndef lint static char rcsid[] = "@(#)vers_ts.c 1.36 92/03/31"; #endif extern char *ctime (); /* XXX - should use gmtime/asctime */ /* * 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. xfiles is * all source code control files, preparsed for our pleasure */ Vers_TS * Version_TS (repository, options, tag, date, user, force_tag_match, set_time, entries, xfiles) char *repository; char *options; char *tag; char *date; char *user; int force_tag_match; int set_time; List *entries; List *xfiles; { 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)); bzero ((char *) vers_ts, 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 (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); 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 (sdtp && sdtp->aflag == 0) { if (!vers_ts->options) vers_ts->options = xstrdup (sdtp->options); } 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 (xfiles != (List *) NULL) { p = findnode (xfiles, user); if (p != NULL) { rcsdata = (RCSNode *) p->data; rcsdata->refcount++; } else rcsdata = NULL; } else rcsdata = RCS_parse (user, repository); if (rcsdata != NULL) { /* squirrel away the rcsdata pointer for others */ vers_ts->srcfile = rcsdata; /* get RCS version number into vn_rcs (if appropriate) */ if (((vers_ts->tag || vers_ts->date) && force_tag_match) || ((rcsdata->flags & VALID) && (rcsdata->flags & INATTIC) == 0)) { if (vers_ts->tag && strcmp (vers_ts->tag, TAG_BASE) == 0) vers_ts->vn_rcs = xstrdup (vers_ts->vn_user); else vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag, vers_ts->date, force_tag_match); } /* * 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; 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) vers_ts->ts_user = time_stamp (user); return (vers_ts); } /* * 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 { ts = xmalloc (51); /* 51 = 2 ctime strings + NULL */ cp = ctime (&sb.st_ctime); /* copy in the create time */ cp[24] = ' '; (void) strcpy (ts, cp); cp = ctime (&sb.st_mtime); /* copy in the modify time */ cp[24] = '\0'; (void) strcat (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)->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); free ((char *) *versp); *versp = (Vers_TS *) NULL; }