Sun Mar 11 14:59:41 2018 UTC ()
deal with cvs meta-data directories not called CVS.


(christos)
diff -r1.6 -r1.7 src/usr.bin/cvslatest/cvslatest.c

cvs diff -r1.6 -r1.7 src/usr.bin/cvslatest/cvslatest.c (expand / switch to unified diff)

--- src/usr.bin/cvslatest/cvslatest.c 2017/09/24 09:43:27 1.6
+++ src/usr.bin/cvslatest/cvslatest.c 2018/03/11 14:59:41 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cvslatest.c,v 1.6 2017/09/24 09:43:27 joerg Exp $ */ 1/* $NetBSD: cvslatest.c,v 1.7 2018/03/11 14:59:41 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2016 The NetBSD Foundation, Inc. 4 * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -28,40 +28,41 @@ @@ -28,40 +28,41 @@
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#ifdef __linux__ 32#ifdef __linux__
33#define _GNU_SOURCE 33#define _GNU_SOURCE
34#endif 34#endif
35 35
36#ifdef HAVE_NBTOOL_CONFIG_H 36#ifdef HAVE_NBTOOL_CONFIG_H
37#include "nbtool_config.h" 37#include "nbtool_config.h"
38#endif 38#endif
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: cvslatest.c,v 1.6 2017/09/24 09:43:27 joerg Exp $"); 41__RCSID("$NetBSD: cvslatest.c,v 1.7 2018/03/11 14:59:41 christos Exp $");
42 42
43/* 43/*
44 * Find the latest timestamp in a set of CVS trees, by examining the 44 * Find the latest timestamp in a set of CVS trees, by examining the
45 * Entries files 45 * Entries files
46 */ 46 */
47 47
48#include <sys/param.h> 48#include <sys/param.h>
49#include <sys/types.h> 49#include <sys/types.h>
50 50
51#include <stdio.h> 51#include <stdio.h>
52#include <string.h> 52#include <string.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <unistd.h> 54#include <unistd.h>
 55#include <dirent.h>
55#include <err.h> 56#include <err.h>
56#include <fts.h> 57#include <fts.h>
57#include <time.h> 58#include <time.h>
58 59
59static int debug = 0; 60static int debug = 0;
60static int ignore = 0; 61static int ignore = 0;
61 62
62struct latest { 63struct latest {
63 time_t time; 64 time_t time;
64 char path[MAXPATHLEN]; 65 char path[MAXPATHLEN];
65}; 66};
66 67
67static void 68static void
@@ -164,47 +165,94 @@ cvsscan(char **pathv, const char *name,  @@ -164,47 +165,94 @@ cvsscan(char **pathv, const char *name,
164 } 165 }
165 166
166 (void)fts_close(dh); 167 (void)fts_close(dh);
167} 168}
168 169
169static __dead void 170static __dead void
170usage(void) 171usage(void)
171{ 172{
172 fprintf(stderr, "Usage: %s [-di] [-n <name>] <path> ...\n", 173 fprintf(stderr, "Usage: %s [-di] [-n <name>] <path> ...\n",
173 getprogname()); 174 getprogname());
174 exit(EXIT_FAILURE); 175 exit(EXIT_FAILURE);
175} 176}
176 177
 178static int
 179checkDir(char *path, size_t pathlen, const char *name)
 180{
 181 static const char *files[] = {
 182 "Entries", "Root", "Repository",
 183 };
 184 size_t i;
 185
 186 for (i = 0; i < __arraycount(files); i++) {
 187 snprintf(path, pathlen, "%s/%s", name, files[i]);
 188 if (access(path, F_OK) == -1)
 189 return 0;
 190 }
 191
 192 return 1;
 193}
 194
 195static const char *
 196findCVSDir(char *path, size_t pathlen, const char *name)
 197{
 198 DIR *dirp;
 199 struct dirent *dp;
 200 const char *n;
 201
 202 if ((dirp = opendir(name)) == NULL)
 203 err(EXIT_FAILURE, "Can't open `%s'", name);
 204
 205 while ((dp = readdir(dirp)) != NULL) {
 206 n = dp->d_name;
 207 if (n[0] == '.' && (n[1] == '\0' ||
 208 (n[1] == '.' && n[2] == '\0')))
 209 continue;
 210 if (checkDir(path, pathlen, n))
 211 goto out;
 212 }
 213 n = "CVS";
 214out:
 215 closedir(dirp);
 216 strlcpy(path, n, pathlen);
 217 return path;
 218}
 219
 220
177int 221int
178main(int argc, char *argv[]) 222main(int argc, char *argv[])
179{ 223{
180 struct latest lat; 224 struct latest lat;
181 const char *name = "CVS"; 225 const char *name = NULL;
 226 char path[MAXPATHLEN];
182 int c; 227 int c;
183 228
184 while ((c = getopt(argc, argv, "din:")) != -1) 229 while ((c = getopt(argc, argv, "din:")) != -1)
185 switch (c) { 230 switch (c) {
186 case 'i': 231 case 'i':
187 ignore++; 232 ignore++;
188 break; 233 break;
189 case 'd': 234 case 'd':
190 debug++; 235 debug++;
191 break; 236 break;
192 case 'n': 237 case 'n':
193 name = optarg; 238 name = optarg;
194 break; 239 break;
195 default: 240 default:
196 usage(); 241 usage();
197 } 242 }
198 243
199 if (argc == optind) 244 if (argc == optind)
200 usage(); 245 usage();
201 246
202 // So that mktime behaves consistently 247 // So that mktime behaves consistently
203 setenv("TZ", "UTC", 1); 248 setenv("TZ", "UTC", 1);
204 249
 250 if (name == NULL)
 251 name = findCVSDir(path, sizeof(path), argv[optind]);
 252
205 cvsscan(argv + optind, name, &lat); 253 cvsscan(argv + optind, name, &lat);
206 if (debug) 254 if (debug)
207 printlat(&lat); 255 printlat(&lat);
208 printf("%jd\n", (intmax_t)lat.time); 256 printf("%jd\n", (intmax_t)lat.time);
209 return 0; 257 return 0;
210} 258}