Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
ChangeLog entry:

Thanks to Paul Eggert who suggested using better random numbers as
well as using the base62 format for compactness and provided the
sample divide_by and convert functions used here.

2005-09-29  Mark D. Baushke  <mdb@gnu.org>

	* man/rcsfile.5in: Document new commitid delta phrase.
	* man/rcsfile.5: Regenerated.

	* src/ci.c (RANDOM_BYTES, COMMITID_RAW_SIZE): New constants.
	(mainProg): Add commitid to delta records. Use
	random data and represent in base62 or fall back to using the
	same basic format construction as is used by CVS and CVSNT.
	(divide_by): New function used by convert.
	(convert): New fucntion to convert to base62.
	* rcsbase.h (commitidsize): Room for base62 encoded block or
	32bit pid plus a 32bit time rendered as hex plus one
	NUL byte round up to 64.
	(struct hshentry): Add new commitid field.
	* src/rcsgen.c (putdelta): Preserve old commitid entries.
	* src/rcssyn.c (Kcommitid): New global constant keyword.
	(getdelta): Add optional parsing for it.
	* src/rlog.c (putadelta): Print it out.

Index:man/rcsfile.5
--- man/rcsfile.5~	1995-06-16 06:58:26.000000000 +0000
+++ man/rcsfile.5	2005-09-27 20:53:01.023504000 +0000
@@ -1,4 +1,4 @@
-.lf 1 ./rcsfile.5in
+.lf 1 rcsfile.5in
 .\" Set p to 1 if your formatter can handle pic output.
 .if t .nr p 1
 .de Id
@@ -69,6 +69,7 @@ nonterminal symbols are in
 		\f3state\fP	{\f2id\fP}\f3;\fP
 		\f3branches\fP	{\f2num\fP}*\f3;\fP
 		\f3next\fP	{\f2num\fP}\f3;\fP
+		{ \f3commitid\fP \f2id\fP\f3;\fP }
 		{ \f2newphrase\fP }*
 .LP
 \f2desc\fP	::=	\f3desc\fP	\f2string\fP
@@ -128,6 +129,18 @@ and all the digits of years thereafter.
 Dates use the Gregorian calendar; times use UTC.
 .PP
 The
+.I commitid
+is followed by an
+.I id
+token. This token is intended to be unique across
+multiple files and is used to help group files as
+being a part of the same logical commit.
+This token must uniquely identify the commit
+operation that was applied to a set of RCS files.
+In particular, it must be unique among all the
+commitids in this file.
+.PP
+The
 .I newphrase
 productions in the grammar are reserved for future extensions
 to the format of \*r files.
@@ -230,7 +243,7 @@ The following diagram shows an example o
 .fi
 .\}
 .if \np \{\
-.lf 232
+.lf 245
 .PS 4.250i 3.812i
 .\" -2.0625 -4.25 1.75 0
 .\" 0.000i 4.250i 3.812i 0.000i
@@ -239,7 +252,7 @@ The following diagram shows an example o
 .nr 0x 1
 \h'3.812i'
 .sp -1
-.lf 242
+.lf 255
 \h'2.062i-(\w'Head'u/2u)'\v'0.125i-(0v/2u)+0v+0.22m'Head
 .sp -1
 \h'2.062i'\v'0.250i'\D'l0.000i 0.500i'
@@ -256,7 +269,7 @@ The following diagram shows an example o
 .sp -1
 \h'1.688i'\v'0.750i'\D'l0.000i 0.500i'
 .sp -1
-.lf 244
+.lf 257
 \h'2.062i-(\w'2.1'u/2u)'\v'1.000i-(0v/2u)+0v+0.22m'2.1
 .sp -1
 \h'2.062i'\v'1.250i'\D'l0.000i 0.500i'
@@ -265,7 +278,7 @@ The following diagram shows an example o
 .sp -1
 \h'2.062i'\v'1.750i'\D'l-0.025i -0.100i'
 .sp -1
-.lf 246
+.lf 259
 \h'2.062i-(\w'1.3'u/2u)'\v'2.000i-(1v/2u)+0v+0.22m'1.3
 .sp -1
 \h'2.062i'\v'2.250i'\D'l-0.375i -0.500i'
@@ -280,7 +293,7 @@ The following diagram shows an example o
 .sp -1
 \h'1.375i'\v'1.500i'\D'l0.025i 0.100i'
 .sp -1
-.lf 249
+.lf 262
 \h'1.375i-(\w'1.3.1.1'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.3.1.1
 .sp -1
 \h'1.375i'\v'1.000i'\D'l-0.375i 0.500i'
@@ -295,7 +308,7 @@ The following diagram shows an example o
 .sp -1
 \h'2.062i'\v'2.750i'\D'l-0.025i -0.100i'
 .sp -1
-.lf 252
+.lf 265
 \h'2.062i-(\w'1.2'u/2u)'\v'3.000i-(1v/2u)+0v+0.22m'1.2
 .sp -1
 \h'2.062i'\v'3.250i'\D'l-0.375i -0.500i'
@@ -310,7 +323,7 @@ The following diagram shows an example o
 .sp -1
 \h'0.375i'\v'2.500i'\D'l0.025i 0.100i'
 .sp -1
-.lf 255
+.lf 268
 \h'0.375i-(\w'1.2.1.1'u/2u)'\v'2.250i-(1v/2u)+1v+0.22m'1.2.1.1
 .sp -1
 \h'0.375i'\v'2.000i'\D'l-0.375i 0.500i'
@@ -325,7 +338,7 @@ The following diagram shows an example o
 .sp -1
 \h'0.375i'\v'1.500i'\D'l0.025i 0.100i'
 .sp -1
-.lf 257
+.lf 270
 \h'0.375i-(\w'1.2.1.3'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.2.1.3
 .sp -1
 \h'0.375i'\v'1.000i'\D'l-0.375i 0.500i'
@@ -340,7 +353,7 @@ The following diagram shows an example o
 .sp -1
 \h'2.750i'\v'2.500i'\D'l0.025i 0.100i'
 .sp -1
-.lf 261
+.lf 274
 \h'2.750i-(\w'1.2.2.1'u/2u)'\v'2.250i-(1v/2u)+1v+0.22m'1.2.2.1
 .sp -1
 \h'2.750i'\v'2.000i'\D'l-0.375i 0.500i'
@@ -355,7 +368,7 @@ The following diagram shows an example o
 .sp -1
 \h'3.438i'\v'1.250i'\D'l0.025i 0.100i'
 .sp -1
-.lf 264
+.lf 277
 \h'3.438i-(\w'\s-21.2.2.1.1.1\s0'u/2u)'\v'1.000i-(1v/2u)+1v+0.22m'\s-21.2.2.1.1.1\s0
 .sp -1
 \h'3.438i'\v'0.750i'\D'l-0.375i 0.500i'
@@ -370,7 +383,7 @@ The following diagram shows an example o
 .sp -1
 \h'2.750i'\v'1.500i'\D'l0.025i 0.100i'
 .sp -1
-.lf 267
+.lf 280
 \h'2.750i-(\w'1.2.2.2'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.2.2.2
 .sp -1
 \h'2.750i'\v'1.000i'\D'l-0.375i 0.500i'
@@ -385,7 +398,7 @@ The following diagram shows an example o
 .sp -1
 \h'2.062i'\v'3.750i'\D'l-0.025i -0.100i'
 .sp -1
-.lf 270
+.lf 283
 \h'2.062i-(\w'1.1'u/2u)'\v'4.000i-(1v/2u)+0v+0.22m'1.1
 .sp -1
 \h'2.062i'\v'4.250i'\D'l-0.375i -0.500i'
@@ -398,9 +411,9 @@ The following diagram shows an example o
 .if \n(00 .fi
 .br
 .nr 0x 0
-.lf 271
+.lf 284
 .PE
-.lf 272
+.lf 285
 .\}
 .PP
 .SH IDENTIFICATION
Index:man/rcsfile.5in
--- man/rcsfile.5in~	1995-06-05 08:28:35.000000000 +0000
+++ man/rcsfile.5in	2005-09-27 20:52:46.424504000 +0000
@@ -68,6 +68,7 @@ nonterminal symbols are in
 		\f3state\fP	{\f2id\fP}\f3;\fP
 		\f3branches\fP	{\f2num\fP}*\f3;\fP
 		\f3next\fP	{\f2num\fP}\f3;\fP
+		{ \f3commitid\fP \f2id\fP\f3;\fP }
 		{ \f2newphrase\fP }*
 .LP
 \f2desc\fP	::=	\f3desc\fP	\f2string\fP
@@ -127,6 +128,18 @@ and all the digits of years thereafter.
 Dates use the Gregorian calendar; times use UTC.
 .PP
 The
+.I commitid
+is followed by an
+.I id
+token. This token is intended to be unique across
+multiple files and is used to help group files as
+being a part of the same logical commit.
+This token must uniquely identify the commit
+operation that was applied to a set of RCS files.
+In particular, it must be unique among all the
+commitids in this file.
+.PP
+The
 .I newphrase
 productions in the grammar are reserved for future extensions
 to the format of \*r files.
Index:src/rcsbase.h
--- src/rcsbase.h~	1995-06-16 06:19:24.000000000 +0000
+++ src/rcsbase.h	2005-09-28 21:47:51.490505000 +0000
@@ -222,6 +222,11 @@ Report problems and direct all questions
                               /* 1 sets the default locking to strict;      */
                               /* used in production environments.           */
 
+/* base64_encode(128 random bits) needs 24 bytes + 1 for NUL */
+/* time_t may be 64bits on some machines needs 16 bytes + 1 as hex */
+#define commitidsize	   64 /* time+1+base64(128bits)+1 | pid+time+rand+1 */
+#define urandom_dev "/dev/urandom"
+
 #define yearlength	   16 /* (good through AD 9,999,999,999,999,999)    */
 #define datesize (yearlength+16)	/* size of output of time2date */
 #define RCSTMPPREFIX '_' /* prefix for temp files in working dir  */
@@ -358,6 +363,7 @@ struct hshentry {
 	char const	  * lockedby; /* who locks the revision		    */
 	char const	  * state;    /* state of revision (Exp by default) */
 	char const	  * name;     /* name (if any) by which retrieved   */
+	char const        * commitid; /* text string to associate commits   */
 	struct cbuf	    log;      /* log message requested at checkin   */
         struct branchhead * branches; /* list of first revisions on branches*/
 	struct cbuf	    ig;	      /* ignored phrases in admin part	    */
@@ -662,6 +668,7 @@ extern int               TotalDeltas;
 extern char const *const expand_names[];
 extern char const
 	Kaccess[], Kauthor[], Kbranch[], Kcomment[],
+	Kcommitid[],
 	Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
 	Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
 void unexpected_EOF P((void)) exiting;
Index:src/ci.c
--- src/ci.c~	1995-06-16 06:19:24.000000000 +0000
+++ src/ci.c	2005-09-29 21:57:57.814504000 +0000
@@ -262,6 +262,10 @@ static void cleanup P((void));
 static void incnum P((char const*,struct buf*));
 static void addassoclst P((int,char const*));
 
+enum {RANDOM_BYTES = 8};
+enum {COMMITID_RAW_SIZE = (sizeof(time_t) + RANDOM_BYTES)};
+static void convert P((char const input[COMMITID_RAW_SIZE], char *output));
+
 static FILE *exfile;
 static RILE *workptr;			/* working file pointer		*/
 static struct buf newdelnum;		/* new revision number		*/
@@ -285,6 +289,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.30 1
 	char olddate[datesize];
 	char newdatebuf[datesize + zonelenmax];
 	char targetdatebuf[datesize + zonelenmax];
+	char commitid[commitidsize];
 	char *a, **newargv, *textfile;
 	char const *author, *krev, *rev, *state;
 	char const *diffname, *expname;
@@ -309,6 +314,45 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.30 1
 	suffixes = X_DEFAULT;
 	nextassoc = &assoclst;
 
+	{
+		char buf[COMMITID_RAW_SIZE] = { 0, };
+		ssize_t len = 0;
+		time_t rightnow = time (NULL);
+		char *startrand = buf + sizeof (time_t);
+		unsigned char *p = (unsigned char *) startrand;
+		size_t randbytes = RANDOM_BYTES;
+		int flags = O_RDONLY;
+		int fd;
+#ifdef O_NOCTTY
+		flags |= O_NOCTTY;
+#endif
+		if (rightnow != (time_t)-1)
+			while (rightnow > 0) {
+				*--p = rightnow % (UCHAR_MAX + 1);
+				rightnow /= UCHAR_MAX + 1;
+			}
+		else {
+			/* try to use more random data */
+			randbytes = COMMITID_RAW_SIZE;
+			startrand = buf;
+		}
+		fd = open (urandom_dev, flags);
+		if (fd >= 0) {
+			len = read (fd, startrand, randbytes);
+			close (fd);
+		}
+		if (len <= 0) {
+			/* no random data was available so use pid */
+			long int pid = (long int)getpid ();
+			p = (unsigned char *) (startrand + sizeof (pid));
+			while (pid > 0) {
+			    *--p = pid % (UCHAR_MAX + 1);
+			    pid /= UCHAR_MAX + 1;
+			}
+		}
+		convert(buf, commitid);
+	}
+
 	argc = getRCSINIT(argc, argv, &newargv);
 	argv = newargv;
 	while (a = *++argv,  0<--argc && *a++=='-') {
@@ -532,6 +576,8 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.30 1
 	newdelta.name = 0;
 	clear_buf(&newdelta.ig);
 	clear_buf(&newdelta.igtext);
+	/* set commitid */
+	newdelta.commitid=commitid;
 	/* set author */
 	if (author)
 		newdelta.author=author;     /* set author given by -w         */
@@ -1317,3 +1363,38 @@ addassoclst(flag, sp)
 	*nextassoc = pt;
 	nextassoc = &pt->nextsym;
 }
+
+static char const alphabet[62] =
+  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+/* Divide BUF by D, returning the remainder.  Replace BUF by the
+   quotient.  BUF[0] is the most significant part of BUF.
+   D must not exceed UINT_MAX >> CHAR_BIT.  */
+static unsigned int
+divide_by (unsigned char buf[COMMITID_RAW_SIZE], unsigned int d)
+{
+  unsigned int carry = 0;
+  int i;
+  for (i = 0; i < COMMITID_RAW_SIZE; i++)
+    {
+      unsigned int byte = buf[i];
+      unsigned int dividend = (carry << CHAR_BIT) + byte;
+      buf[i] = dividend / d;
+      carry = dividend % d;
+    }
+  return carry;
+}
+
+static void
+convert (char const input[COMMITID_RAW_SIZE], char *output)
+{
+  static char const zero[COMMITID_RAW_SIZE] = { 0, };
+  unsigned char buf[COMMITID_RAW_SIZE];
+  size_t o = 0;
+  memcpy (buf, input, COMMITID_RAW_SIZE);
+  while (memcmp (buf, zero, COMMITID_RAW_SIZE) != 0)
+    output[o++] = alphabet[divide_by (buf, sizeof alphabet)];
+  if (! o)
+    output[o++] = '0';
+  output[o] = '\0';
+}
Index:src/rcsgen.c
--- src/rcsgen.c~	1995-06-16 06:19:24.000000000 +0000
+++ src/rcsgen.c	2005-09-27 22:08:47.421504000 +0000
@@ -547,6 +547,9 @@ putdelta(node, fout)
 
 	aprintf(fout, ";\n%s\t%s;\n", Knext, node->next?node->next->num:"");
 	awrite(node->ig.string, node->ig.size, fout);
+
+	if (node->commitid)
+		aprintf(fout, "%s\t%s;\n", Kcommitid, node->commitid);
 }
 
 
Index:src/rcssyn.c
--- src/rcssyn.c~	1995-06-16 06:19:24.000000000 +0000
+++ src/rcssyn.c	2005-09-27 22:08:47.429504000 +0000
@@ -171,6 +171,7 @@ char const
 	Kauthor[]   = "author",
 	Kbranch[]   = "branch",
 	Kcomment[]  = "comment",
+	Kcommitid[] = "commitid",
 	Kdate[]     = "date",
 	Kdesc[]     = "desc",
 	Kexpand[]   = "expand",
@@ -433,6 +434,13 @@ getdelta()
 	Delta->lockedby = 0;
 	Delta->log.string = 0;
 	Delta->selector = true;
+
+	if (getkeyopt(Kcommitid)) {
+		Delta->commitid = NextString;
+		nextlex();
+		getsemi(Kcommitid);
+        }
+
 	Delta->ig = getphrases(Kdesc);
         TotalDeltas++;
         return (true);
Index:src/rlog.c
--- src/rlog.c~	1995-06-16 06:19:24.000000000 +0000
+++ src/rlog.c	2005-09-26 17:23:55.257504000 +0000
@@ -591,6 +591,10 @@ putadelta(node,editscript,trunk)
 	      aprintf(out, insDelFormat,
                              editscript->insertlns, editscript->deletelns);
 
+	if ( node->commitid )
+	   aprintf(out, "%s commitid: %s", (editscript) ? ";" : "",
+		   node->commitid);
+
         newbranch = node->branches;
         if ( newbranch ) {
 	   bufautobegin(&branchnum);