* 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.
* Entries file to Files file
* Creates the file Files containing the names that comprise the project, from
static char rcsid
[] = "@(#)entries.c 1.37 92/03/31";
static Node
*AddEntryNode (List
* list
, char *name
, char *version
,
char *timestamp
, char *options
, char *tag
,
static Node
*AddEntryNode ();
static char *entfilename
; /* for error messages */
* Write out the line associated with a node of an entries file
p
= (Entnode
*) node
->data
;
if (fprintf (entfile
, "/%s/%s/%s/%s/", node
->key
, p
->version
,
p
->timestamp
, p
->options
) == EOF
)
error (1, errno
, "cannot write %s", entfilename
);
if (fprintf (entfile
, "T%s\n", p
->tag
) == EOF
)
error (1, errno
, "cannot write %s", entfilename
);
if (fprintf (entfile
, "D%s\n", p
->date
) == EOF
)
error (1, errno
, "cannot write %s", entfilename
);
else if (fprintf (entfile
, "\n") == EOF
)
error (1, errno
, "cannot write %s", entfilename
);
* write out the current entries file given a list, making a backup copy
/* open the new one and walk the list writing entries */
entfilename
= CVSADM_ENTBAK
;
entfile
= open_file (entfilename
, "w+");
(void) walklist (list
, write_ent_proc
);
if (fclose (entfile
) == EOF
)
error (1, errno
, "error closing %s", entfilename
);
/* now, atomically (on systems that support it) rename it */
rename_file (entfilename
, CVSADM_ENT
);
* Removes the argument file from the Entries file if necessary.
Scratch_Entry (list
, fname
)
(void) fprintf (stderr
, "-> Scratch_Entry(%s)\n", fname
);
/* hashlookup to see if it is there */
if ((node
= findnode (list
, fname
)) != NULL
)
delnode (node
); /* delete the node */
write_entries (list
); /* re-write the file */
* Enters the given file name/version/time-stamp into the Entries file,
* removing the old entry first, if necessary.
Register (list
, fname
, vn
, ts
, options
, tag
, date
)
(void) fprintf (stderr
, "-> Register(%s, %s, %s, %s, %s %s)\n",
fname
, vn
, ts
, options
, tag
? tag
: "",
/* was it already there? */
if ((node
= findnode (list
, fname
)) != NULL
)
/* add the new one and re-write the file */
(void) AddEntryNode (list
, fname
, vn
, ts
, options
, tag
, date
);
node
= AddEntryNode (list
, fname
, vn
, ts
, options
, tag
, date
);
/* append it to the end */
entfilename
= CVSADM_ENT
;
entfile
= open_file (entfilename
, "a");
(void) write_ent_proc (node
);
if (fclose (entfile
) == EOF
)
error (1, errno
, "error closing %s", entfilename
);
* Node delete procedure for list-private sticky dir tag/date info
struct stickydirtag
*sdtp
;
sdtp
= (struct stickydirtag
*) p
->data
;
* Read the entries file into a list, hashing on the file name.
char *cp
, *user
, *vn
, *ts
, *options
;
char *tag_or_date
, *tag
, *date
;
/* get a fresh list... */
* Parse the CVS/Tag file, to get any default tag/date settings. Use
* list-private storage to tuck them away for Version_TS().
ParseTag (&dirtag
, &dirdate
);
if (aflag
|| dirtag
|| dirdate
)
struct stickydirtag
*sdtp
;
sdtp
= (struct stickydirtag
*) xmalloc (sizeof (*sdtp
));
bzero ((char *) sdtp
, sizeof (*sdtp
));
sdtp
->tag
= xstrdup (dirtag
);
sdtp
->date
= xstrdup (dirdate
);
/* feed it into the list-private area */
entries
->list
->data
= (char *) sdtp
;
entries
->list
->delproc
= freesdt
;
fpin
= fopen (CVSADM_ENT
, "r");
error (0, errno
, "cannot open %s for reading", CVSADM_ENT
);
while (fgets (line
, sizeof (line
), fpin
) != NULL
)
if ((cp
= index (user
, '/')) == NULL
)
if ((cp
= index (vn
, '/')) == NULL
)
if ((cp
= index (ts
, '/')) == NULL
)
if ((cp
= index (options
, '/')) == NULL
)
if ((cp
= index (tag_or_date
, '\n')) == NULL
)
else if (*tag_or_date
== 'D')
(void) AddEntryNode (entries
, user
, vn
, ts
, options
, tag
, date
);
/* try conversion only on first line */
check_entries ((char *) NULL
);
/* clean up and return */
* Look at the entries file to determine if it is in the old entries format.
* If so, convert it to the new format.
char entname
[MAXLINELEN
];
char *cp
, *user
, *rev
, *ts
, *opt
;
(void) sprintf (entname
, "%s/%s", dir
, CVSADM_ENT
);
(void) sprintf (entbak
, "%s/%s", dir
, CVSADM_ENTBAK
);
(void) strcpy (entname
, CVSADM_ENT
);
(void) strcpy (entbak
, CVSADM_ENTBAK
);
fpin
= open_file (entname
, "r");
if (fgets (line
, sizeof (line
), fpin
) == NULL
)
rename_file (entname
, entbak
);
fpin
= open_file (entbak
, "r");
fpout
= open_file (entname
, "w+");
while (fgets (line
, sizeof (line
), fpin
) != NULL
)
if (fputs (line
, fpout
) == EOF
)
error (1, errno
, "cannot write %s", CVSADM_ENT
);
if ((ts
= index (line
, '|')) == NULL
)
if ((user
= rindex (ts
, ' ')) == NULL
)
if ((cp
= index (user
, '|')) == NULL
)
if (fprintf (fpout
, "/%s/%s/%s/%s/\n", user
, rev
, ts
, opt
) == EOF
)
error (1, errno
, "cannot write %s", CVSADM_ENT
);
if (fclose (fpout
) == EOF
)
error (1, errno
, "cannot close %s", entname
);
/* clean up any old Files or Mod files */
(void) sprintf (tmp
, "%s/%s", dir
, CVSADM_FILE
);
(void) strcpy (tmp
, CVSADM_FILE
);
(void) sprintf (tmp
, "%s/%s", dir
, CVSADM_MOD
);
(void) strcpy (tmp
, CVSADM_MOD
);
* Free up the memory associated with the data section of an ENTRIES type
p
= (Entnode
*) node
->data
;
* Get an Entries file list node, initialize it, and add it to the specified
AddEntryNode (list
, name
, version
, timestamp
, options
, tag
, date
)
/* get a node and fill in the regular stuff */
p
->delproc
= Entries_delproc
;
/* this one gets a key of the name for hashing */
/* malloc the data parts and fill them in */
p
->data
= xmalloc (sizeof (Entnode
));
entdata
= (Entnode
*) p
->data
;
entdata
->version
= xstrdup (version
);
entdata
->timestamp
= xstrdup (timestamp
);
entdata
->options
= xstrdup (options
);
if (entdata
->options
== NULL
)
entdata
->options
= xstrdup ("");/* must be non-NULL */
entdata
->tag
= xstrdup (tag
);
entdata
->date
= xstrdup (date
);
/* put the node into the list */
if (addnode (list
, p
) != 0)
error (0, 0, "Duplicate filename in entries file (%s) -- ignored",
* Write out/Clear the CVS/Tag file.
WriteTag (dir
, tag
, date
)
(void) strcpy (tmp
, CVSADM_TAG
);
(void) sprintf (tmp
, "%s/%s", dir
, CVSADM_TAG
);
fout
= open_file (tmp
, "w+");
if (fprintf (fout
, "T%s\n", tag
) == EOF
)
error (1, errno
, "write to %s failed", tmp
);
if (fprintf (fout
, "D%s\n", date
) == EOF
)
error (1, errno
, "write to %s failed", tmp
);
if (fclose (fout
) == EOF
)
error (1, errno
, "cannot close %s", tmp
);
(void) unlink_file (tmp
);
* Parse the CVS/Tag file for the current directory.
fp
= fopen (CVSADM_TAG
, "r");
if (fgets (line
, sizeof (line
), fp
) != NULL
)
if ((cp
= rindex (line
, '\n')) != NULL
)
if (*line
== 'T' && tagp
)
*tagp
= xstrdup (line
+ 1);
else if (*line
== 'D' && datep
)
*datep
= xstrdup (line
+ 1);