1 /* 2 * Copyright (c) 1992, Brian Berliner and Jeff Polk 3 * Copyright (c) 1989-1992, Brian Berliner 4 * 5 * You may distribute under the terms of the GNU General Public License as 6 * specified in the README file that comes with the CVS source distribution. 7 * 8 * Various useful functions for the CVS support code. 9 */ 10 11 #include "cvs.h" 12 #include "getline.h" 13 14 extern char *getlogin (); 15 16 /* 17 * malloc some data and die if it fails 18 */ 19 char * 20 xmalloc (bytes) 21 size_t bytes; 22 { 23 char *cp; 24 25 /* Parts of CVS try to xmalloc zero bytes and then free it. Some 26 systems have a malloc which returns NULL for zero byte 27 allocations but a free which can't handle NULL, so compensate. */ 28 if (bytes == 0) 29 bytes = 1; 30 31 cp = malloc (bytes); 32 if (cp == NULL) 33 error (1, 0, "out of memory; can not allocate %lu bytes", 34 (unsigned long) bytes); 35 return (cp); 36 } 37 38 /* 39 * realloc data and die if it fails [I've always wanted to have "realloc" do 40 * a "malloc" if the argument is NULL, but you can't depend on it. Here, I 41 * can *force* it. 42 */ 43 void * 44 xrealloc (ptr, bytes) 45 void *ptr; 46 size_t bytes; 47 { 48 char *cp; 49 50 if (!ptr) 51 cp = malloc (bytes); 52 else 53 cp = realloc (ptr, bytes); 54 55 if (cp == NULL) 56 error (1, 0, "can not reallocate %lu bytes", (unsigned long) bytes); 57 return (cp); 58 } 59 60 /* Two constants which tune expand_string. Having MIN_INCR as large 61 as 1024 might waste a bit of memory, but it shouldn't be too bad 62 (CVS used to allocate arrays of, say, 3000, PATH_MAX (8192, often), 63 or other such sizes). Probably anything which is going to allocate 64 memory which is likely to get as big as MAX_INCR shouldn't be doing 65 it in one block which must be contiguous, but since getrcskey does 66 so, we might as well limit the wasted memory to MAX_INCR or so 67 bytes. */ 68 69 #define MIN_INCR 1024 70 #define MAX_INCR (2*1024*1024) 71 72 /* *STRPTR is a pointer returned from malloc (or NULL), pointing to *N 73 characters of space. Reallocate it so that points to at least 74 NEWSIZE bytes of space. Gives a fatal error if out of memory; 75 if it returns it was successful. */ 76 void 77 expand_string (strptr, n, newsize) 78 char **strptr; 79 size_t *n; 80 size_t newsize; 81 { 82 if (*n < newsize) 83 { 84 while (*n < newsize) 85 { 86 if (*n < MIN_INCR) 87 *n += MIN_INCR; 88 else if (*n > MAX_INCR) 89 *n += MAX_INCR; 90 else 91 *n *= 2; 92 } 93 *strptr = xrealloc (*strptr, *n); 94 } 95 } 96 97 /* 98 * Duplicate a string, calling xmalloc to allocate some dynamic space 99 */ 100 char * 101 xstrdup (str) 102 const char *str; 103 { 104 char *s; 105 106 if (str == NULL) 107 return ((char *) NULL); 108 s = xmalloc (strlen (str) + 1); 109 (void) strcpy (s, str); 110 return (s); 111 } 112 113 /* Remove trailing newlines from STRING, destructively. */ 114 void 115 strip_trailing_newlines (str) 116 char *str; 117 { 118 int len; 119 len = strlen (str) - 1; 120 121 while (str[len] == '\n') 122 str[len--] = '\0'; 123 } 124 125 /* Return the number of levels that path ascends above where it starts. 126 For example: 127 "../../foo" -> 2 128 "foo/../../bar" -> 1 129 */ 130 /* FIXME: Should be using ISDIRSEP, last_component, or some other 131 mechanism which is more general than just looking at slashes, 132 particularly for the client.c caller. The server.c caller might 133 want something different, so be careful. */ 134 int 135 pathname_levels (path) 136 char *path; 137 { 138 char *p; 139 char *q; 140 int level; 141 int max_level; 142 143 max_level = 0; 144 p = path; 145 level = 0; 146 do 147 { 148 q = strchr (p, '/'); 149 if (q != NULL) 150 ++q; 151 if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || p[2] == '/')) 152 { 153 --level; 154 if (-level > max_level) 155 max_level = -level; 156 } 157 else if (p[0] == '.' && (p[1] == '\0' || p[1] == '/')) 158 ; 159 else 160 ++level; 161 p = q; 162 } while (p != NULL); 163 return max_level; 164 } 165 166 167 /* Free a vector, where (*ARGV)[0], (*ARGV)[1], ... (*ARGV)[*PARGC - 1] 168 are malloc'd and so is *ARGV itself. Such a vector is allocated by 169 line2argv or expand_wild, for example. */ 170 void 171 free_names (pargc, argv) 172 int *pargc; 173 char **argv; 174 { 175 register int i; 176 177 for (i = 0; i < *pargc; i++) 178 { /* only do through *pargc */ 179 free (argv[i]); 180 } 181 free (argv); 182 *pargc = 0; /* and set it to zero when done */ 183 } 184 185 /* Convert LINE into arguments separated by SEPCHARS. Set *ARGC 186 to the number of arguments found, and (*ARGV)[0] to the first argument, 187 (*ARGV)[1] to the second, etc. *ARGV is malloc'd and so are each of 188 (*ARGV)[0], (*ARGV)[1], ... Use free_names() to return the memory 189 allocated here back to the free pool. */ 190 void 191 line2argv (pargc, argv, line, sepchars) 192 int *pargc; 193 char ***argv; 194 char *line; 195 char *sepchars; 196 { 197 char *cp; 198 /* Could make a case for size_t or some other unsigned type, but 199 we'll stick with int to avoid signed/unsigned warnings when 200 comparing with *pargc. */ 201 int argv_allocated; 202 203 /* Small for testing. */ 204 /* argv_allocated must be at least 3 because at some places 205 (e.g. checkout_proc) cvs alters argv[2]. */ 206 argv_allocated = 4; 207 *argv = (char **) xmalloc (argv_allocated * sizeof (**argv)); 208 209 *pargc = 0; 210 for (cp = strtok (line, sepchars); cp; cp = strtok ((char *) NULL, sepchars)) 211 { 212 if (*pargc == argv_allocated) 213 { 214 argv_allocated *= 2; 215 *argv = xrealloc (*argv, argv_allocated * sizeof (**argv)); 216 } 217 (*argv)[*pargc] = xstrdup (cp); 218 (*pargc)++; 219 } 220 } 221 222 /* 223 * Returns the number of dots ('.') found in an RCS revision number 224 */ 225 int 226 numdots (s) 227 const char *s; 228 { 229 int dots = 0; 230 231 for (; *s; s++) 232 { 233 if (*s == '.') 234 dots++; 235 } 236 return (dots); 237 } 238 239 /* Compare revision numbers REV1 and REV2 by consecutive fields. 240 Return negative, zero, or positive in the manner of strcmp. The 241 two revision numbers must have the same number of fields, or else 242 compare_revnums will return an inaccurate result. */ 243 int 244 compare_revnums (rev1, rev2) 245 const char *rev1; 246 const char *rev2; 247 { 248 const char *s, *sp; 249 const char *t, *tp; 250 char *snext, *tnext; 251 int result = 0; 252 253 sp = s = rev1; 254 tp = t = rev2; 255 while (result == 0) 256 { 257 result = strtoul (sp, &snext, 10) - strtoul (tp, &tnext, 10); 258 if (*snext == '\0' || *tnext == '\0') 259 break; 260 sp = snext + 1; 261 tp = tnext + 1; 262 } 263 264 return result; 265 } 266 267 char * 268 increment_revnum (rev) 269 const char *rev; 270 { 271 char *newrev, *p; 272 int lastfield; 273 size_t len = strlen (rev); 274 275 newrev = (char *) xmalloc (len + 2); 276 memcpy (newrev, rev, len + 1); 277 p = strrchr (newrev, '.'); 278 if (p == NULL) 279 { 280 free (newrev); 281 return NULL; 282 } 283 lastfield = atoi (++p); 284 sprintf (p, "%d", lastfield + 1); 285 286 return newrev; 287 } 288 289 /* Return the username by which the caller should be identified in 290 CVS, in contexts such as the author field of RCS files, various 291 logs, etc. */ 292 char * 293 getcaller () 294 { 295 #ifndef SYSTEM_GETCALLER 296 static char *cache; 297 struct passwd *pw; 298 uid_t uid; 299 #endif 300 301 /* If there is a CVS username, return it. */ 302 #ifdef AUTH_SERVER_SUPPORT 303 if (CVS_Username != NULL) 304 return CVS_Username; 305 #endif 306 307 #ifdef SYSTEM_GETCALLER 308 return SYSTEM_GETCALLER (); 309 #else 310 /* Get the caller's login from his uid. If the real uid is "root" 311 try LOGNAME USER or getlogin(). If getlogin() and getpwuid() 312 both fail, return the uid as a string. */ 313 314 if (cache != NULL) 315 return cache; 316 317 uid = getuid (); 318 if (uid == (uid_t) 0) 319 { 320 char *name; 321 322 /* super-user; try getlogin() to distinguish */ 323 if (((name = getlogin ()) || (name = getenv("LOGNAME")) || 324 (name = getenv("USER"))) && *name) 325 { 326 cache = xstrdup (name); 327 return cache; 328 } 329 } 330 if ((pw = (struct passwd *) getpwuid (uid)) == NULL) 331 { 332 char uidname[20]; 333 334 (void) sprintf (uidname, "uid%lu", (unsigned long) uid); 335 cache = xstrdup (uidname); 336 return cache; 337 } 338 cache = xstrdup (pw->pw_name); 339 return cache; 340 #endif 341 } 342 343 #ifdef lint 344 #ifndef __GNUC__ 345 /* ARGSUSED */ 346 time_t 347 get_date (date, now) 348 char *date; 349 struct timeb *now; 350 { 351 time_t foo = 0; 352 353 return (foo); 354 } 355 #endif 356 #endif 357 358 /* Given two revisions, find their greatest common ancestor. If the 359 two input revisions exist, then rcs guarantees that the gca will 360 exist. */ 361 362 char * 363 gca (rev1, rev2) 364 const char *rev1; 365 const char *rev2; 366 { 367 int dots; 368 char *gca; 369 const char *p[2]; 370 int j[2]; 371 char *retval; 372 373 if (rev1 == NULL || rev2 == NULL) 374 { 375 error (0, 0, "sanity failure in gca"); 376 abort(); 377 } 378 379 /* The greatest common ancestor will have no more dots, and numbers 380 of digits for each component no greater than the arguments. Therefore 381 this string will be big enough. */ 382 gca = xmalloc (strlen (rev1) + strlen (rev2) + 100); 383 384 /* walk the strings, reading the common parts. */ 385 gca[0] = '\0'; 386 p[0] = rev1; 387 p[1] = rev2; 388 do 389 { 390 int i; 391 char c[2]; 392 char *s[2]; 393 394 for (i = 0; i < 2; ++i) 395 { 396 /* swap out the dot */ 397 s[i] = strchr (p[i], '.'); 398 if (s[i] != NULL) { 399 c[i] = *s[i]; 400 } 401 402 /* read an int */ 403 j[i] = atoi (p[i]); 404 405 /* swap back the dot... */ 406 if (s[i] != NULL) { 407 *s[i] = c[i]; 408 p[i] = s[i] + 1; 409 } 410 else 411 { 412 /* or mark us at the end */ 413 p[i] = NULL; 414 } 415 416 } 417 418 /* use the lowest. */ 419 (void) sprintf (gca + strlen (gca), "%d.", 420 j[0] < j[1] ? j[0] : j[1]); 421 422 } while (j[0] == j[1] 423 && p[0] != NULL 424 && p[1] != NULL); 425 426 /* back up over that last dot. */ 427 gca[strlen(gca) - 1] = '\0'; 428 429 /* numbers differ, or we ran out of strings. we're done with the 430 common parts. */ 431 432 dots = numdots (gca); 433 if (dots == 0) 434 { 435 /* revisions differ in trunk major number. */ 436 437 char *q; 438 const char *s; 439 440 s = (j[0] < j[1]) ? p[0] : p[1]; 441 442 if (s == NULL) 443 { 444 /* we only got one number. this is strange. */ 445 error (0, 0, "bad revisions %s or %s", rev1, rev2); 446 abort(); 447 } 448 else 449 { 450 /* we have a minor number. use it. */ 451 q = gca + strlen (gca); 452 453 *q++ = '.'; 454 for ( ; *s != '.' && *s != '\0'; ) 455 *q++ = *s++; 456 457 *q = '\0'; 458 } 459 } 460 else if ((dots & 1) == 0) 461 { 462 /* if we have an even number of dots, then we have a branch. 463 remove the last number in order to make it a revision. */ 464 465 char *s; 466 467 s = strrchr(gca, '.'); 468 *s = '\0'; 469 } 470 471 retval = xstrdup (gca); 472 free (gca); 473 return retval; 474 } 475 476 /* Give fatal error if REV is numeric and ARGC,ARGV imply we are 477 planning to operate on more than one file. The current directory 478 should be the working directory. Note that callers assume that we 479 will only be checking the first character of REV; it need not have 480 '\0' at the end of the tag name and other niceties. Right now this 481 is only called from admin.c, but if people like the concept it probably 482 should also be called from diff -r, update -r, get -r, and log -r. */ 483 484 void 485 check_numeric (rev, argc, argv) 486 const char *rev; 487 int argc; 488 char **argv; 489 { 490 if (rev == NULL || !isdigit (*rev)) 491 return; 492 493 /* Note that the check for whether we are processing more than one 494 file is (basically) syntactic; that is, we don't behave differently 495 depending on whether a directory happens to contain only a single 496 file or whether it contains more than one. I strongly suspect this 497 is the least confusing behavior. */ 498 if (argc != 1 499 || (!wrap_name_has (argv[0], WRAP_TOCVS) && isdir (argv[0]))) 500 { 501 error (0, 0, "while processing more than one file:"); 502 error (1, 0, "attempt to specify a numeric revision"); 503 } 504 } 505 506 /* 507 * Sanity checks and any required fix-up on message passed to RCS via '-m'. 508 * RCS 5.7 requires that a non-total-whitespace, non-null message be provided 509 * with '-m'. Returns a newly allocated, non-empty buffer with whitespace 510 * stripped from end of lines and end of buffer. 511 * 512 * TODO: We no longer use RCS to manage repository files, so maybe this 513 * nonsense about non-empty log fields can be dropped. 514 */ 515 char * 516 make_message_rcslegal (message) 517 char *message; 518 { 519 char *dst, *dp, *mp; 520 521 if (message == NULL) message = ""; 522 523 /* Strip whitespace from end of lines and end of string. */ 524 dp = dst = (char *) xmalloc (strlen (message) + 1); 525 for (mp = message; *mp != '\0'; ++mp) 526 { 527 if (*mp == '\n') 528 { 529 /* At end-of-line; backtrack to last non-space. */ 530 while (dp > dst && (dp[-1] == ' ' || dp[-1] == '\t')) 531 --dp; 532 } 533 *dp++ = *mp; 534 } 535 536 /* Backtrack to last non-space at end of string, and truncate. */ 537 while (dp > dst && isspace (dp[-1])) 538 --dp; 539 *dp = '\0'; 540 541 /* After all that, if there was no non-space in the string, 542 substitute a non-empty message. */ 543 if (*dst == '\0') 544 { 545 free (dst); 546 dst = xstrdup ("*** empty log message ***"); 547 } 548 549 return dst; 550 } 551 552 /* Does the file FINFO contain conflict markers? The whole concept 553 of looking at the contents of the file to figure out whether there are 554 unresolved conflicts is kind of bogus (people do want to manage files 555 which contain those patterns not as conflict markers), but for now it 556 is what we do. */ 557 int 558 file_has_markers (finfo) 559 const struct file_info *finfo; 560 { 561 FILE *fp; 562 char *line = NULL; 563 size_t line_allocated = 0; 564 int result; 565 566 result = 0; 567 fp = CVS_FOPEN (finfo->file, "r"); 568 if (fp == NULL) 569 error (1, errno, "cannot open %s", finfo->fullname); 570 while (getline (&line, &line_allocated, fp) > 0) 571 { 572 if (strncmp (line, RCS_MERGE_PAT, sizeof RCS_MERGE_PAT - 1) == 0) 573 { 574 result = 1; 575 goto out; 576 } 577 } 578 if (ferror (fp)) 579 error (0, errno, "cannot read %s", finfo->fullname); 580 out: 581 if (fclose (fp) < 0) 582 error (0, errno, "cannot close %s", finfo->fullname); 583 if (line != NULL) 584 free (line); 585 return result; 586 } 587 588 /* Read the entire contents of the file NAME into *BUF. 589 If NAME is NULL, read from stdin. *BUF 590 is a pointer returned from malloc (or NULL), pointing to *BUFSIZE 591 bytes of space. The actual size is returned in *LEN. On error, 592 give a fatal error. The name of the file to use in error messages 593 (typically will include a directory if we have changed directory) 594 is FULLNAME. MODE is "r" for text or "rb" for binary. */ 595 596 void 597 get_file (name, fullname, mode, buf, bufsize, len) 598 const char *name; 599 const char *fullname; 600 const char *mode; 601 char **buf; 602 size_t *bufsize; 603 size_t *len; 604 { 605 struct stat s; 606 size_t nread; 607 char *tobuf; 608 FILE *e; 609 size_t filesize; 610 611 if (name == NULL) 612 { 613 e = stdin; 614 filesize = 100; /* force allocation of minimum buffer */ 615 } 616 else 617 { 618 if (CVS_LSTAT (name, &s) < 0) 619 error (1, errno, "can't stat %s", fullname); 620 621 /* Don't attempt to read special files or symlinks. */ 622 if (!S_ISREG (s.st_mode)) 623 { 624 *len = 0; 625 return; 626 } 627 628 /* Convert from signed to unsigned. */ 629 filesize = s.st_size; 630 631 e = open_file (name, mode); 632 } 633 634 if (*bufsize < filesize) 635 { 636 *bufsize = filesize; 637 *buf = xrealloc (*buf, *bufsize); 638 } 639 640 tobuf = *buf; 641 nread = 0; 642 while (1) 643 { 644 size_t got; 645 646 got = fread (tobuf, 1, *bufsize - (tobuf - *buf), e); 647 if (ferror (e)) 648 error (1, errno, "can't read %s", fullname); 649 nread += got; 650 tobuf += got; 651 652 if (feof (e)) 653 break; 654 655 /* It's probably paranoid to think S.ST_SIZE might be 656 too small to hold the entire file contents, but we 657 handle it just in case. */ 658 if (tobuf == *buf + *bufsize) 659 { 660 int c; 661 long off; 662 663 c = getc (e); 664 if (c == EOF) 665 break; 666 off = tobuf - *buf; 667 expand_string (buf, bufsize, *bufsize + 100); 668 tobuf = *buf + off; 669 *tobuf++ = c; 670 ++nread; 671 } 672 } 673 674 if (e != stdin && fclose (e) < 0) 675 error (0, errno, "cannot close %s", fullname); 676 677 *len = nread; 678 679 /* Force *BUF to be large enough to hold a null terminator. */ 680 if (*buf != NULL) 681 { 682 if (nread == *bufsize) 683 expand_string (buf, bufsize, *bufsize + 1); 684 (*buf)[nread] = '\0'; 685 } 686 } 687