#include "cvs.h"
#include "savecwd.h"
static struct hrec
{
char *type;
char *user;
char *dir;
char *repos;
char *rev;
char *file;
char *end;
char *mod;
time_t date;
int idx;
} *hrec_head;
static char *fill_hrec PROTO((char *line, struct hrec * hr));
static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
static int select_hrec PROTO((struct hrec * hr));
static int sort_order PROTO((const PTR l, const PTR r));
static int within PROTO((char *find, char *string));
static void expand_modules PROTO((void));
static void read_hrecs PROTO((char *fname));
static void report_hrecs PROTO((void));
static void save_file PROTO((char *dir, char *name, char *module));
static void save_module PROTO((char *module));
static void save_user PROTO((char *name));
#define ALL_REC_TYPES "TOEFWUCGMAR"
#define USER_INCREMENT 2
#define FILE_INCREMENT 128
#define MODULE_INCREMENT 5
#define HREC_INCREMENT 128
static short report_count;
static short extract;
static short v_checkout;
static short modified;
static short tag_report;
static short module_report;
static short working;
static short last_entry;
static short all_users;
static short user_sort;
static short repos_sort;
static short file_sort;
static short module_sort;
static short tz_local;
static time_t tz_seconds_east_of_GMT;
static char *tz_name = "+0000";
static char *since_rev;
static char *since_tag;
static char *backto;
static char * since_date;
static struct hrec *last_since_tag;
static struct hrec *last_backto;
static char *rec_types;
static int hrec_count;
static int hrec_max;
static char **user_list;
static int user_max;
static int user_count;
static struct file_list_str
{
char *l_file;
char *l_module;
} *file_list;
static int file_max;
static int file_count;
static char **mod_list;
static int mod_max;
static int mod_count;
static char *histfile;
static const char *const history_usg[] =
{
"Usage: %s %s [-report] [-flags] [-options args] [files...]\n\n",
" Reports:\n",
" -T Produce report on all TAGs\n",
" -c Committed (Modified) files\n",
" -o Checked out modules\n",
" -m <module> Look for specified module (repeatable)\n",
" -x [TOEFWUCGMAR] Extract by record type\n",
" Flags:\n",
" -a All users (Default is self)\n",
" -e Everything (same as -x, but all record types)\n",
" -l Last modified (committed or modified report)\n",
" -w Working directory must match\n",
" Options:\n",
" -D <date> Since date (Many formats)\n",
" -b <str> Back to record with str in module/file/repos field\n",
" -f <file> Specified file (same as command line) (repeatable)\n",
" -n <modulename> In module (repeatable)\n",
" -p <repos> In repository (repeatable)\n",
" -r <rev/tag> Since rev or tag (looks inside RCS files!)\n",
" -t <tag> Since tag record placed in history file (by anyone).\n",
" -u <user> For user name (repeatable)\n",
" -z <tz> Output for time zone <tz> (e.g. -z -0700)\n",
NULL};
static int
sort_order (l, r)
const PTR l;
const PTR r;
{
int i;
const struct hrec *left = (const struct hrec *) l;
const struct hrec *right = (const struct hrec *) r;
if (user_sort)
{
if ((i = strcmp (left->user, right->user)) != 0)
return (i);
}
if (module_sort)
{
if (left->mod && right->mod)
if ((i = strcmp (left->mod, right->mod)) != 0)
return (i);
}
if (repos_sort)
{
if ((i = strcmp (left->repos, right->repos)) != 0)
return (i);
}
if (file_sort)
{
if ((i = strcmp (left->file, right->file)) != 0)
return (i);
if (working)
{
if ((i = strcmp (left->dir, right->dir)) != 0)
return (i);
if ((i = strcmp (left->end, right->end)) != 0)
return (i);
}
}
if ((i = ((long) (left->date) - (long) (right->date))) != 0)
return (i);
return (left->idx - right->idx);
}
int
history (argc, argv)
int argc;
char **argv;
{
int i, c;
char *fname;
if (argc == -1)
usage (history_usg);
since_rev = xstrdup ("");
since_tag = xstrdup ("");
backto = xstrdup ("");
rec_types = xstrdup ("");
optind = 0;
while ((c = getopt (argc, argv, "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != -1)
{
switch (c)
{
case 'T':
report_count++;
tag_report++;
break;
case 'a':
all_users++;
break;
case 'c':
report_count++;
modified = 1;
break;
case 'e':
report_count++;
extract++;
free (rec_types);
rec_types = xstrdup (ALL_REC_TYPES);
break;
case 'l':
last_entry = 1;
break;
case 'o':
report_count++;
v_checkout = 1;
break;
case 'w':
working = 1;
break;
case 'X':
histfile = optarg;
break;
case 'D':
if (*since_rev || *since_tag || *backto)
{
error (0, 0, "date overriding rev/tag/backto");
*since_rev = *since_tag = *backto = '\0';
}
since_date = Make_Date (optarg);
break;
case 'b':
if (since_date || *since_rev || *since_tag)
{
error (0, 0, "backto overriding date/rev/tag");
*since_rev = *since_tag = '\0';
if (since_date != NULL)
free (since_date);
since_date = NULL;
}
free (backto);
backto = xstrdup (optarg);
break;
case 'f':
save_file ("", optarg, (char *) NULL);
break;
case 'm':
report_count++;
module_report++;
case 'n':
save_module (optarg);
break;
case 'p':
save_file (optarg, "", (char *) NULL);
break;
case 'r':
if (since_date || *since_tag || *backto)
{
error (0, 0, "rev overriding date/tag/backto");
*since_tag = *backto = '\0';
if (since_date != NULL)
free (since_date);
since_date = NULL;
}
free (since_rev);
since_rev = xstrdup (optarg);
break;
case 't':
if (since_date || *since_rev || *backto)
{
error (0, 0, "tag overriding date/marker/file/repos");
*since_rev = *backto = '\0';
if (since_date != NULL)
free (since_date);
since_date = NULL;
}
free (since_tag);
since_tag = xstrdup (optarg);
break;
case 'u':
save_user (optarg);
break;
case 'x':
report_count++;
extract++;
{
char *cp;
for (cp = optarg; *cp; cp++)
if (!strchr (ALL_REC_TYPES, *cp))
error (1, 0, "%c is not a valid report type", *cp);
}
free (rec_types);
rec_types = xstrdup (optarg);
break;
case 'z':
tz_local =
(optarg[0] == 'l' || optarg[0] == 'L')
&& (optarg[1] == 't' || optarg[1] == 'T')
&& !optarg[2];
if (tz_local)
tz_name = optarg;
else
{
static char f[] = "1/1/1970 23:00 %s";
char *buf = xmalloc (sizeof (f) - 2 + strlen (optarg));
time_t t;
sprintf (buf, f, optarg);
t = get_date (buf, (struct timeb *) NULL);
free (buf);
if (t == (time_t) -1)
error (0, 0, "%s is not a known time zone", optarg);
else
{
tz_seconds_east_of_GMT = (time_t)23 * 60 * 60 - t;
tz_name = optarg;
}
}
break;
case '?':
default:
usage (history_usg);
break;
}
}
c = optind;
if (!report_count)
v_checkout++;
else if (report_count > 1)
error (1, 0, "Only one report type allowed from: \"-Tcomx\".");
#ifdef CLIENT_SUPPORT
if (client_active)
{
struct file_list_str *f1;
char **mod;
start_server ();
ign_setup ();
if (tag_report)
send_arg("-T");
if (all_users)
send_arg("-a");
if (modified)
send_arg("-c");
if (last_entry)
send_arg("-l");
if (v_checkout)
send_arg("-o");
if (working)
send_arg("-w");
if (histfile)
send_arg("-X");
if (since_date)
client_senddate (since_date);
if (backto[0] != '\0')
option_with_arg ("-b", backto);
for (f1 = file_list; f1 < &file_list[file_count]; ++f1)
{
if (f1->l_file[0] == '*')
option_with_arg ("-p", f1->l_file + 1);
else
option_with_arg ("-f", f1->l_file);
}
if (module_report)
send_arg("-m");
for (mod = mod_list; mod < &mod_list[mod_count]; ++mod)
option_with_arg ("-n", *mod);
if (*since_rev)
option_with_arg ("-r", since_rev);
if (*since_tag)
option_with_arg ("-t", since_tag);
for (mod = user_list; mod < &user_list[user_count]; ++mod)
option_with_arg ("-u", *mod);
if (extract)
option_with_arg ("-x", rec_types);
option_with_arg ("-z", tz_name);
send_to_server ("history\012", 0);
return get_responses_and_close ();
}
#endif
if (all_users)
save_user ("");
if (mod_list)
expand_modules ();
if (tag_report)
{
if (!strchr (rec_types, 'T'))
{
rec_types = xrealloc (rec_types, strlen (rec_types) + 5);
(void) strcat (rec_types, "T");
}
}
else if (extract)
{
if (user_list)
user_sort++;
}
else if (modified)
{
free (rec_types);
rec_types = xstrdup ("MAR");
if (!since_date && !*since_rev && !*since_tag && !*backto)
{
repos_sort++;
file_sort++;
if (!last_entry && user_list)
user_sort++;
}
}
else if (module_report)
{
free (rec_types);
rec_types = xstrdup (last_entry ? "OMAR" : ALL_REC_TYPES);
module_sort++;
repos_sort++;
file_sort++;
working = 0;
}
else
{
free (rec_types);
rec_types = xstrdup ("OF");
if (!last_entry && user_list)
user_sort++;
if (!since_date && !*since_rev && !*since_tag && !*backto)
file_sort++;
}
if (!user_list)
save_user (getcaller ());
if (*since_tag && !strchr (rec_types, 'T'))
{
rec_types = xrealloc (rec_types, strlen (rec_types) + 5);
(void) strcat (rec_types, "T");
}
argc -= c;
argv += c;
for (i = 0; i < argc; i++)
save_file ("", argv[i], (char *) NULL);
if (histfile)
fname = xstrdup (histfile);
else
{
fname = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_HISTORY) + 10);
(void) sprintf (fname, "%s/%s/%s", CVSroot_directory,
CVSROOTADM, CVSROOTADM_HISTORY);
}
read_hrecs (fname);
qsort ((PTR) hrec_head, hrec_count, sizeof (struct hrec), sort_order);
report_hrecs ();
free (fname);
if (since_date != NULL)
free (since_date);
free (since_rev);
free (since_tag);
free (backto);
free (rec_types);
return (0);
}
void
history_write (type, update_dir, revs, name, repository)
int type;
char *update_dir;
char *revs;
char *name;
char *repository;
{
char *fname;
char *workdir;
char *username = getcaller ();
int fd;
char *line;
char *slash = "", *cp, *cp2, *repos;
int i;
static char *tilde = "";
static char *PrCurDir = NULL;
if (logoff)
return;
fname = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_HISTORY) + 10);
(void) sprintf (fname, "%s/%s/%s", CVSroot_directory,
CVSROOTADM, CVSROOTADM_HISTORY);
if (!isfile (fname))
{
logoff = 1;
goto out;
}
if (trace)
#ifdef SERVER_SUPPORT
fprintf (stderr, "%c-> fopen(%s,a)\n",
(server_active) ? 'S' : ' ', fname);
#else
fprintf (stderr, "-> fopen(%s,a)\n", fname);
#endif
if (noexec)
goto out;
fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
if (fd < 0)
error (1, errno, "cannot open history file: %s", fname);
repos = Short_Repository (repository);
if (!PrCurDir)
{
char *pwdir;
pwdir = get_homedir ();
PrCurDir = CurDir;
if (pwdir != NULL)
{
i = strlen (pwdir);
if (!strncmp (CurDir, pwdir, i))
{
PrCurDir += i;
tilde = "~";
}
else
{
struct saved_cwd cwd;
char *homedir;
if (save_cwd (&cwd))
error_exit ();
if ( CVS_CHDIR (pwdir) < 0)
error (1, errno, "can't chdir(%s)", pwdir);
homedir = xgetwd ();
if (homedir == NULL)
error (1, errno, "can't getwd in %s", pwdir);
if (restore_cwd (&cwd, NULL))
error_exit ();
free_cwd (&cwd);
i = strlen (homedir);
if (!strncmp (CurDir, homedir, i))
{
PrCurDir += i;
tilde = "~";
}
free (homedir);
}
}
}
if (type == 'T')
{
repos = update_dir;
update_dir = "";
}
else if (update_dir && *update_dir)
slash = "/";
else
update_dir = "";
workdir = xmalloc (strlen (tilde) + strlen (PrCurDir) + strlen (slash)
+ strlen (update_dir) + 10);
(void) sprintf (workdir, "%s%s%s%s", tilde, PrCurDir, slash, update_dir);
if (!repos)
repos = "";
cp = workdir + strlen (workdir) - 1;
cp2 = repos + strlen (repos) - 1;
for (i = 0; cp2 >= repos && cp > workdir && *cp == *cp2--; cp--)
i++;
if (i > 2)
{
i = strlen (repos) - i;
(void) sprintf ((cp + 1), "*%x", i);
}
if (!revs)
revs = "";
line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos)
+ strlen (revs) + strlen (name) + 100);
sprintf (line, "%c%08lx|%s|%s|%s|%s|%s\n",
type, (long) time ((time_t *) NULL),
username, workdir, repos, revs, name);
if (lseek (fd, (off_t) 0, SEEK_END) == -1)
error (1, errno, "cannot seek to end of history file: %s", fname);
if (write (fd, line, strlen (line)) < 0)
error (1, errno, "cannot write to history file: %s", fname);
free (line);
if (close (fd) != 0)
error (1, errno, "cannot close history file: %s", fname);
free (workdir);
out:
free (fname);
}
static void
save_user (name)
char *name;
{
if (user_count == user_max)
{
user_max += USER_INCREMENT;
user_list = (char **) xrealloc ((char *) user_list,
(int) user_max * sizeof (char *));
}
user_list[user_count++] = xstrdup (name);
}
static void
save_file (dir, name, module)
char *dir;
char *name;
char *module;
{
char *cp;
struct file_list_str *fl;
if (file_count == file_max)
{
file_max += FILE_INCREMENT;
file_list = (struct file_list_str *) xrealloc ((char *) file_list,
file_max * sizeof (*fl));
}
fl = &file_list[file_count++];
fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2);
fl->l_module = module;
if (dir && *dir)
{
if (name && *name)
{
(void) strcpy (cp, dir);
(void) strcat (cp, "/");
(void) strcat (cp, name);
}
else
{
*cp++ = '*';
(void) strcpy (cp, dir);
}
}
else
{
if (name && *name)
{
(void) strcpy (cp, name);
}
else
{
error (0, 0, "save_file: null dir and file name");
}
}
}
static void
save_module (module)
char *module;
{
if (mod_count == mod_max)
{
mod_max += MODULE_INCREMENT;
mod_list = (char **) xrealloc ((char *) mod_list,
mod_max * sizeof (char *));
}
mod_list[mod_count++] = xstrdup (module);
}
static void
expand_modules ()
{
}
#define NEXT_BAR(here) do { while (isspace(*line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
static char *
fill_hrec (line, hr)
char *line;
struct hrec *hr;
{
char *cp, *rtn;
int c;
int off;
static int idx = 0;
unsigned long date;
memset ((char *) hr, 0, sizeof (*hr));
while (isspace (*line))
line++;
if (!(rtn = strchr (line, '\n')))
return ("");
*rtn++ = '\0';
hr->type = line++;
(void) sscanf (line, "%lx", &date);
hr->date = date;
while (*line && strchr ("0123456789abcdefABCDEF", *line))
line++;
if (*line == '\0')
return (rtn);
line++;
NEXT_BAR (user);
NEXT_BAR (dir);
if ((cp = strrchr (hr->dir, '*')) != NULL)
{
*cp++ = '\0';
(void) sscanf (cp, "%x", &off);
hr->end = line + off;
}
else
hr->end = line - 1;
NEXT_BAR (repos);
NEXT_BAR (rev);
hr->idx = idx++;
if (strchr ("FOET", *(hr->type)))
hr->mod = line;
NEXT_BAR (file);
return (rtn);
}
static void
read_hrecs (fname)
char *fname;
{
char *cp, *cp2;
int i, fd;
struct hrec *hr;
struct stat st_buf;
if ((fd = CVS_OPEN (fname, O_RDONLY | OPEN_BINARY)) < 0)
error (1, errno, "cannot open history file: %s", fname);
if (fstat (fd, &st_buf) < 0)
error (1, errno, "can't stat history file");
if (!(i = st_buf.st_size))
error (1, 0, "history file is empty");
cp = xmalloc (i + 2);
if (read (fd, cp, i) != i)
error (1, errno, "cannot read log file");
(void) close (fd);
if (*(cp + i - 1) != '\n')
{
*(cp + i) = '\n';
i++;
}
*(cp + i) = '\0';
for (cp2 = cp; cp2 - cp < i; cp2++)
{
if (*cp2 != '\n' && !isprint (*cp2))
*cp2 = ' ';
}
hrec_max = HREC_INCREMENT;
hrec_head = (struct hrec *) xmalloc (hrec_max * sizeof (struct hrec));
while (*cp)
{
if (hrec_count == hrec_max)
{
struct hrec *old_head = hrec_head;
hrec_max += HREC_INCREMENT;
hrec_head = (struct hrec *) xrealloc ((char *) hrec_head,
hrec_max * sizeof (struct hrec));
if (hrec_head != old_head)
{
if (last_since_tag)
last_since_tag = hrec_head + (last_since_tag - old_head);
if (last_backto)
last_backto = hrec_head + (last_backto - old_head);
}
}
hr = hrec_head + hrec_count;
cp = fill_hrec (cp, hr);
if (select_hrec (hr))
hrec_count++;
}
if (last_since_tag)
{
hrec_count -= (last_since_tag - hrec_head);
hrec_head = last_since_tag;
}
if (last_backto)
{
hrec_count -= (last_backto - hrec_head);
hrec_head = last_backto;
}
}
static int
within (find, string)
char *find, *string;
{
int c, len;
if (!find || !string)
return (0);
c = *find++;
len = strlen (find);
while (*string)
{
if (!(string = strchr (string, c)))
return (0);
string++;
if (!strncmp (find, string, len))
return (1);
}
return (0);
}
static int
select_hrec (hr)
struct hrec *hr;
{
char **cpp, *cp, *cp2;
struct file_list_str *fl;
int count;
if (since_date)
{
char *ourdate = date_from_time_t (hr->date);
if (RCS_datecmp (ourdate, since_date) < 0)
return (0);
free (ourdate);
}
else if (*since_rev)
{
Vers_TS *vers;
time_t t;
struct file_info finfo;
memset (&finfo, 0, sizeof finfo);
finfo.file = hr->file;
finfo.update_dir = NULL;
finfo.fullname = finfo.file;
finfo.repository = hr->repos;
finfo.entries = NULL;
finfo.rcs = NULL;
vers = Version_TS (&finfo, (char *) NULL, since_rev, (char *) NULL,
1, 0);
if (vers->vn_rcs)
{
if ((t = RCS_getrevtime (vers->srcfile, vers->vn_rcs, (char *) 0, 0))
!= (time_t) 0)
{
if (hr->date < t)
{
freevers_ts (&vers);
return (0);
}
}
}
freevers_ts (&vers);
}
else if (*since_tag)
{
if (*(hr->type) == 'T')
{
if (within (since_tag, hr->rev))
{
last_since_tag = hr;
return (1);
}
else
return (0);
}
if (!last_since_tag)
return (0);
}
else if (*backto)
{
if (within (backto, hr->file) || within (backto, hr->mod) ||
within (backto, hr->repos))
last_backto = hr;
else
return (0);
}
if (user_list && hr->user)
{
for (cpp = user_list, count = user_count; count; cpp++, count--)
{
if (!**cpp)
break;
if (!strcmp (hr->user, *cpp))
break;
}
if (!count)
return (0);
}
if (!strchr (rec_types, *(hr->type)))
return (0);
if (!strchr ("TFOE", *(hr->type)))
{
if (file_list)
{
for (fl = file_list, count = file_count; count; fl++, count--)
{
char *cmpfile = NULL;
if (*(cp = fl->l_file) == '*')
{
cp++;
if (!strncmp (cp, hr->repos, strlen (cp)))
{
hr->mod = fl->l_module;
break;
}
}
else
{
if (strchr (cp, '/'))
{
cmpfile = xmalloc (strlen (hr->repos)
+ strlen (hr->file)
+ 10);
(void) sprintf (cmpfile, "%s/%s",
hr->repos, hr->file);
cp2 = cmpfile;
}
else
{
cp2 = hr->file;
}
if (within (cp, cp2))
{
hr->mod = fl->l_module;
break;
}
if (cmpfile != NULL)
free (cmpfile);
}
}
if (!count)
return (0);
}
}
if (mod_list)
{
for (cpp = mod_list, count = mod_count; count; cpp++, count--)
{
if (hr->mod && !strcmp (hr->mod, *cpp))
break;
}
if (!count)
return (0);
}
return (1);
}
static void
report_hrecs ()
{
struct hrec *hr, *lr;
struct tm *tm;
int i, count, ty;
char *cp;
int user_len, file_len, rev_len, mod_len, repos_len;
if (*since_tag && !last_since_tag)
{
(void) printf ("No tag found: %s\n", since_tag);
return;
}
else if (*backto && !last_backto)
{
(void) printf ("No module, file or repository with: %s\n", backto);
return;
}
else if (hrec_count < 1)
{
(void) printf ("No records selected.\n");
return;
}
user_len = file_len = rev_len = mod_len = repos_len = 0;
hr = lr = hrec_head;
hr++;
for (count = hrec_count; count--; lr = hr, hr++)
{
char *repos;
if (!count)
hr = NULL;
if (!accept_hrec (lr, hr))
continue;
ty = *(lr->type);
repos = xstrdup (lr->repos);
if ((cp = strrchr (repos, '/')) != NULL)
{
if (lr->mod && !strcmp (++cp, lr->mod))
{
(void) strcpy (cp, "*");
}
}
if ((i = strlen (lr->user)) > user_len)
user_len = i;
if ((i = strlen (lr->file)) > file_len)
file_len = i;
if (ty != 'T' && (i = strlen (repos)) > repos_len)
repos_len = i;
if (ty != 'T' && (i = strlen (lr->rev)) > rev_len)
rev_len = i;
if (lr->mod && (i = strlen (lr->mod)) > mod_len)
mod_len = i;
free (repos);
}
for (lr = hrec_head, hr = (lr + 1); hrec_count--; lr = hr, hr++)
{
char *workdir;
char *repos;
if (!hrec_count)
hr = NULL;
if (!accept_hrec (lr, hr))
continue;
ty = *(lr->type);
if (!tz_local)
{
time_t t = lr->date + tz_seconds_east_of_GMT;
tm = gmtime (&t);
}
else
tm = localtime (&(lr->date));
(void) printf ("%c %02d/%02d %02d:%02d %s %-*s", ty, tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min, tz_name,
user_len, lr->user);
workdir = xmalloc (strlen (lr->dir) + strlen (lr->end) + 10);
(void) sprintf (workdir, "%s%s", lr->dir, lr->end);
if ((cp = strrchr (workdir, '/')) != NULL)
{
if (lr->mod && !strcmp (++cp, lr->mod))
{
(void) strcpy (cp, "*");
}
}
repos = xmalloc (strlen (lr->repos) + 10);
(void) strcpy (repos, lr->repos);
if ((cp = strrchr (repos, '/')) != NULL)
{
if (lr->mod && !strcmp (++cp, lr->mod))
{
(void) strcpy (cp, "*");
}
}
switch (ty)
{
case 'T':
(void) printf (" %-*s [%s:%s]", mod_len, lr->mod, lr->rev,
repos);
if (working)
(void) printf (" {%s}", workdir);
break;
case 'F':
case 'E':
case 'O':
if (lr->rev && *(lr->rev))
(void) printf (" [%s]", lr->rev);
(void) printf (" %-*s =%s%-*s %s", repos_len, repos, lr->mod,
mod_len + 1 - (int) strlen (lr->mod),
"=", workdir);
break;
case 'W':
case 'U':
case 'C':
case 'G':
case 'M':
case 'A':
case 'R':
(void) printf (" %-*s %-*s %-*s =%s= %s", rev_len, lr->rev,
file_len, lr->file, repos_len, repos,
lr->mod ? lr->mod : "", workdir);
break;
default:
(void) printf ("Hey! What is this junk? RecType[0x%2.2x]", ty);
break;
}
(void) putchar ('\n');
free (workdir);
free (repos);
}
}
static int
accept_hrec (lr, hr)
struct hrec *hr, *lr;
{
int ty;
ty = *(lr->type);
if (last_since_tag && ty == 'T')
return (1);
if (v_checkout)
{
if (ty != 'O')
return (0);
if (!hr ||
strcmp (hr->user, lr->user) ||
strcmp (hr->mod, lr->mod) ||
(working &&
(strcmp (hr->dir, lr->dir) ||
strcmp (hr->end, lr->end))))
return (1);
}
else if (modified)
{
if (!last_entry ||
!hr ||
strcmp (hr->repos, lr->repos) ||
strcmp (hr->file, lr->file))
return (1);
if (working)
{
if (strcmp (hr->dir, lr->dir) ||
strcmp (hr->end, lr->end))
return (1);
}
}
else if (module_report)
{
if (!last_entry ||
!hr ||
strcmp (hr->mod, lr->mod) ||
strcmp (hr->repos, lr->repos) ||
strcmp (hr->file, lr->file))
return (1);
}
else
{
return (1);
}
return (0);
}