1 /* filesubr.c --- subroutines for dealing with files
2 Jim Blandy <jimb@cyclic.com>
3
4 This file is part of GNU CVS.
5
6 GNU CVS is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. */
15
16 /* These functions were moved out of subr.c because they need different
17 definitions under operating systems (like, say, Windows NT) with different
18 file system semantics. */
19
20 #include <assert.h>
21 #include "cvs.h"
22
23 static int deep_remove_dir PROTO((const char *path));
24
25 /*
26 * Copies "from" to "to".
27 */
28 void
copy_file(from,to)29 copy_file (from, to)
30 const char *from;
31 const char *to;
32 {
33 struct stat sb;
34 struct utimbuf t;
35 int fdin, fdout;
36
37 if (trace)
38 (void) fprintf (stderr, "%s-> copy(%s,%s)\n",
39 CLIENT_SERVER_STR, from, to);
40 if (noexec)
41 return;
42
43 /* If the file to be copied is a link or a device, then just create
44 the new link or device appropriately. */
45 if (islink (from))
46 {
47 char *source = xreadlink (from);
48 symlink (source, to);
49 free (source);
50 return;
51 }
52
53 if (isdevice (from))
54 {
55 #if defined(HAVE_MKNOD) && defined(HAVE_ST_RDEV)
56 if (stat (from, &sb) < 0)
57 error (1, errno, "cannot stat %s", from);
58 mknod (to, sb.st_mode, sb.st_rdev);
59 #else
60 error (1, 0, "cannot copy device files on this system (%s)", from);
61 #endif
62 }
63 else
64 {
65 /* Not a link or a device... probably a regular file. */
66 if ((fdin = open (from, O_RDONLY)) < 0)
67 error (1, errno, "cannot open %s for copying", from);
68 if (fstat (fdin, &sb) < 0)
69 error (1, errno, "cannot fstat %s", from);
70 if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
71 error (1, errno, "cannot create %s for copying", to);
72 if (sb.st_size > 0)
73 {
74 char buf[BUFSIZ];
75 int n;
76
77 for (;;)
78 {
79 n = read (fdin, buf, sizeof(buf));
80 if (n == -1)
81 {
82 #ifdef EINTR
83 if (errno == EINTR)
84 continue;
85 #endif
86 error (1, errno, "cannot read file %s for copying", from);
87 }
88 else if (n == 0)
89 break;
90
91 if (write(fdout, buf, n) != n) {
92 error (1, errno, "cannot write file %s for copying", to);
93 }
94 }
95
96 #ifdef HAVE_FSYNC
97 if (fsync (fdout))
98 error (1, errno, "cannot fsync file %s after copying", to);
99 #endif
100 }
101
102 if (close (fdin) < 0)
103 error (0, errno, "cannot close %s", from);
104 if (close (fdout) < 0)
105 error (1, errno, "cannot close %s", to);
106 }
107
108 /* now, set the times for the copied file to match those of the original */
109 memset ((char *) &t, 0, sizeof (t));
110 t.actime = sb.st_atime;
111 t.modtime = sb.st_mtime;
112 (void) utime (to, &t);
113 }
114
115 /* FIXME-krp: these functions would benefit from caching the char * &
116 stat buf. */
117
118 /*
119 * Returns non-zero if the argument file is a directory, or is a symbolic
120 * link which points to a directory.
121 */
122 int
isdir(file)123 isdir (file)
124 const char *file;
125 {
126 struct stat sb;
127
128 if (stat (file, &sb) < 0)
129 return (0);
130 return (S_ISDIR (sb.st_mode));
131 }
132
133 /*
134 * Returns non-zero if the argument file is a symbolic link.
135 */
136 int
islink(file)137 islink (file)
138 const char *file;
139 {
140 #ifdef S_ISLNK
141 struct stat sb;
142
143 if (CVS_LSTAT (file, &sb) < 0)
144 return (0);
145 return (S_ISLNK (sb.st_mode));
146 #else
147 return (0);
148 #endif
149 }
150
151 /*
152 * Returns non-zero if the argument file is a block or
153 * character special device.
154 */
155 int
isdevice(file)156 isdevice (file)
157 const char *file;
158 {
159 struct stat sb;
160
161 if (CVS_LSTAT (file, &sb) < 0)
162 return (0);
163 #ifdef S_ISBLK
164 if (S_ISBLK (sb.st_mode))
165 return 1;
166 #endif
167 #ifdef S_ISCHR
168 if (S_ISCHR (sb.st_mode))
169 return 1;
170 #endif
171 return 0;
172 }
173
174 /*
175 * Returns non-zero if the argument file exists.
176 */
177 int
isfile(file)178 isfile (file)
179 const char *file;
180 {
181 return isaccessible(file, F_OK);
182 }
183
184 /*
185 * Returns non-zero if the argument file is readable.
186 */
187 int
isreadable(file)188 isreadable (file)
189 const char *file;
190 {
191 return isaccessible(file, R_OK);
192 }
193
194 /*
195 * Returns non-zero if the argument file is writable.
196 */
197 int
iswritable(file)198 iswritable (file)
199 const char *file;
200 {
201 return isaccessible(file, W_OK);
202 }
203
204 /*
205 * Returns non-zero if the argument file is accessable according to
206 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
207 * bits set.
208 */
209 int
isaccessible(file,mode)210 isaccessible (file, mode)
211 const char *file;
212 const int mode;
213 {
214 #ifdef SETXID_SUPPORT
215 struct stat sb;
216 int umask = 0;
217 int gmask = 0;
218 int omask = 0;
219 int uid;
220
221 if (stat(file, &sb) == -1)
222 return 0;
223 if (mode == F_OK)
224 return 1;
225
226 uid = geteuid();
227 if (uid == 0) /* superuser */
228 {
229 if (mode & X_OK)
230 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH);
231 else
232 return 1;
233 }
234
235 if (mode & R_OK)
236 {
237 umask |= S_IRUSR;
238 gmask |= S_IRGRP;
239 omask |= S_IROTH;
240 }
241 if (mode & W_OK)
242 {
243 umask |= S_IWUSR;
244 gmask |= S_IWGRP;
245 omask |= S_IWOTH;
246 }
247 if (mode & X_OK)
248 {
249 umask |= S_IXUSR;
250 gmask |= S_IXGRP;
251 omask |= S_IXOTH;
252 }
253
254 if (sb.st_uid == uid)
255 return (sb.st_mode & umask) == umask;
256 else if (sb.st_gid == getegid())
257 return (sb.st_mode & gmask) == gmask;
258 else
259 return (sb.st_mode & omask) == omask;
260 #else
261 return access(file, mode) == 0;
262 #endif
263 }
264
265 /*
266 * Open a file and die if it fails
267 */
268 FILE *
open_file(name,mode)269 open_file (name, mode)
270 const char *name;
271 const char *mode;
272 {
273 FILE *fp;
274
275 if ((fp = fopen (name, mode)) == NULL)
276 error (1, errno, "cannot open %s", name);
277 return (fp);
278 }
279
280 /*
281 * Make a directory and die if it fails
282 */
283 void
make_directory(name)284 make_directory (name)
285 const char *name;
286 {
287 struct stat sb;
288
289 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
290 error (0, 0, "%s already exists but is not a directory", name);
291 if (!noexec && mkdir (name, 0777) < 0)
292 error (1, errno, "cannot make directory %s", name);
293 }
294
295 /*
296 * Make a path to the argument directory, printing a message if something
297 * goes wrong.
298 */
299 void
make_directories(name)300 make_directories (name)
301 const char *name;
302 {
303 char *cp;
304
305 if (noexec)
306 return;
307
308 if (mkdir (name, 0777) == 0 || errno == EEXIST)
309 return;
310 if (! existence_error (errno))
311 {
312 error (0, errno, "cannot make path to %s", name);
313 return;
314 }
315 if ((cp = strrchr (name, '/')) == NULL)
316 return;
317 *cp = '\0';
318 make_directories (name);
319 *cp++ = '/';
320 if (*cp == '\0')
321 return;
322 (void) mkdir (name, 0777);
323 }
324
325 /* Create directory NAME if it does not already exist; fatal error for
326 other errors. Returns 0 if directory was created; 1 if it already
327 existed. */
328 int
mkdir_if_needed(name)329 mkdir_if_needed (name)
330 char *name;
331 {
332 if (mkdir (name, 0777) < 0)
333 {
334 if (!(errno == EEXIST
335 || (errno == EACCES && isdir (name))))
336 error (1, errno, "cannot make directory %s", name);
337 return 1;
338 }
339 return 0;
340 }
341
342 /*
343 * Change the mode of a file, either adding write permissions, or removing
344 * all write permissions. Either change honors the current umask setting.
345 *
346 * Don't do anything if PreservePermissions is set to `yes'. This may
347 * have unexpected consequences for some uses of xchmod.
348 */
349 void
xchmod(fname,writable)350 xchmod (fname, writable)
351 char *fname;
352 int writable;
353 {
354 struct stat sb;
355 mode_t mode, oumask;
356
357 if (preserve_perms)
358 return;
359
360 if (stat (fname, &sb) < 0)
361 {
362 if (!noexec)
363 error (0, errno, "cannot stat %s", fname);
364 return;
365 }
366 oumask = umask (0);
367 (void) umask (oumask);
368 if (writable)
369 {
370 mode = sb.st_mode | (~oumask
371 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
372 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
373 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
374 }
375 else
376 {
377 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
378 }
379
380 if (trace)
381 (void) fprintf (stderr, "%s-> chmod(%s,%o)\n",
382 CLIENT_SERVER_STR, fname,
383 (unsigned int) mode);
384 if (noexec)
385 return;
386
387 if (chmod (fname, mode) < 0)
388 error (0, errno, "cannot change mode of file %s", fname);
389 }
390
391 /*
392 * Rename a file and die if it fails
393 */
394 void
rename_file(from,to)395 rename_file (from, to)
396 const char *from;
397 const char *to;
398 {
399 if (trace)
400 (void) fprintf (stderr, "%s-> rename(%s,%s)\n",
401 CLIENT_SERVER_STR, from, to);
402 if (noexec)
403 return;
404
405 if (rename (from, to) < 0)
406 error (1, errno, "cannot rename file %s to %s", from, to);
407 }
408
409 /*
410 * unlink a file, if possible.
411 */
412 int
unlink_file(f)413 unlink_file (f)
414 const char *f;
415 {
416 if (trace)
417 (void) fprintf (stderr, "%s-> unlink_file(%s)\n",
418 CLIENT_SERVER_STR, f);
419 if (noexec)
420 return (0);
421
422 return (CVS_UNLINK (f));
423 }
424
425 /*
426 * Unlink a file or dir, if possible. If it is a directory do a deep
427 * removal of all of the files in the directory. Return -1 on error
428 * (in which case errno is set).
429 */
430 int
unlink_file_dir(f)431 unlink_file_dir (f)
432 const char *f;
433 {
434 struct stat sb;
435
436 if (trace
437 #ifdef SERVER_SUPPORT
438 /* This is called by the server parent process in contexts where
439 it is not OK to send output (e.g. after we sent "ok" to the
440 client). */
441 && !server_active
442 #endif
443 )
444 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f);
445
446 if (noexec)
447 return (0);
448
449 /* For at least some unices, if root tries to unlink() a directory,
450 instead of doing something rational like returning EISDIR,
451 the system will gleefully go ahead and corrupt the filesystem.
452 So we first call stat() to see if it is OK to call unlink(). This
453 doesn't quite work--if someone creates a directory between the
454 call to stat() and the call to unlink(), we'll still corrupt
455 the filesystem. Where is the Unix Haters Handbook when you need
456 it? */
457 if (stat (f, &sb) < 0)
458 {
459 if (existence_error (errno))
460 {
461 /* The file or directory doesn't exist anyhow. */
462 return -1;
463 }
464 }
465 else if (S_ISDIR (sb.st_mode))
466 return deep_remove_dir (f);
467
468 return CVS_UNLINK (f);
469 }
470
471 /* Remove a directory and everything it contains. Returns 0 for
472 * success, -1 for failure (in which case errno is set).
473 */
474
475 static int
deep_remove_dir(path)476 deep_remove_dir (path)
477 const char *path;
478 {
479 DIR *dirp;
480 struct dirent *dp;
481
482 if (rmdir (path) != 0)
483 {
484 if (errno == ENOTEMPTY
485 || errno == EEXIST
486 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
487 (it defines ENOTEMPTY and EEXIST to 17 but actually
488 returns 87). */
489 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
490 {
491 if ((dirp = CVS_OPENDIR (path)) == NULL)
492 /* If unable to open the directory return
493 * an error
494 */
495 return -1;
496
497 errno = 0;
498 while ((dp = CVS_READDIR (dirp)) != NULL)
499 {
500 char *buf;
501
502 if (strcmp (dp->d_name, ".") == 0 ||
503 strcmp (dp->d_name, "..") == 0)
504 continue;
505
506 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
507 sprintf (buf, "%s/%s", path, dp->d_name);
508
509 /* See comment in unlink_file_dir explanation of why we use
510 isdir instead of just calling unlink and checking the
511 status. */
512 if (isdir(buf))
513 {
514 if (deep_remove_dir(buf))
515 {
516 CVS_CLOSEDIR(dirp);
517 free (buf);
518 return -1;
519 }
520 }
521 else
522 {
523 if (CVS_UNLINK (buf) != 0)
524 {
525 CVS_CLOSEDIR(dirp);
526 free (buf);
527 return -1;
528 }
529 }
530 free (buf);
531
532 errno = 0;
533 }
534 if (errno != 0)
535 {
536 int save_errno = errno;
537 CVS_CLOSEDIR (dirp);
538 errno = save_errno;
539 return -1;
540 }
541 CVS_CLOSEDIR (dirp);
542 return rmdir (path);
543 }
544 else
545 return -1;
546 }
547
548 /* Was able to remove the directory return 0 */
549 return 0;
550 }
551
552 /* Read NCHARS bytes from descriptor FD into BUF.
553 Return the number of characters successfully read.
554 The number returned is always NCHARS unless end-of-file or error. */
555 static size_t
block_read(fd,buf,nchars)556 block_read (fd, buf, nchars)
557 int fd;
558 char *buf;
559 size_t nchars;
560 {
561 char *bp = buf;
562 size_t nread;
563
564 do
565 {
566 nread = read (fd, bp, nchars);
567 if (nread == (size_t)-1)
568 {
569 #ifdef EINTR
570 if (errno == EINTR)
571 continue;
572 #endif
573 return (size_t)-1;
574 }
575
576 if (nread == 0)
577 break;
578
579 bp += nread;
580 nchars -= nread;
581 } while (nchars != 0);
582
583 return bp - buf;
584 }
585
586
587 /*
588 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
589 * If FILE1 and FILE2 are special files, compare their salient characteristics
590 * (i.e. major/minor device numbers, links, etc.
591 */
592 int
xcmp(file1,file2)593 xcmp (file1, file2)
594 const char *file1;
595 const char *file2;
596 {
597 char *buf1, *buf2;
598 struct stat sb1, sb2;
599 int fd1, fd2;
600 int ret;
601
602 if (CVS_LSTAT (file1, &sb1) < 0)
603 error (1, errno, "cannot lstat %s", file1);
604 if (CVS_LSTAT (file2, &sb2) < 0)
605 error (1, errno, "cannot lstat %s", file2);
606
607 /* If FILE1 and FILE2 are not the same file type, they are unequal. */
608 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
609 return 1;
610
611 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
612 the same thing. */
613 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
614 {
615 int result;
616 buf1 = xreadlink (file1);
617 buf2 = xreadlink (file2);
618 result = (strcmp (buf1, buf2) == 0);
619 free (buf1);
620 free (buf2);
621 return result;
622 }
623
624 /* If FILE1 and FILE2 are devices, they are equal if their device
625 numbers match. */
626 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
627 {
628 #ifdef HAVE_ST_RDEV
629 if (sb1.st_rdev == sb2.st_rdev)
630 return 0;
631 else
632 return 1;
633 #else
634 error (1, 0, "cannot compare device files on this system (%s and %s)",
635 file1, file2);
636 #endif
637 }
638
639 if ((fd1 = open (file1, O_RDONLY)) < 0)
640 error (1, errno, "cannot open file %s for comparing", file1);
641 if ((fd2 = open (file2, O_RDONLY)) < 0)
642 error (1, errno, "cannot open file %s for comparing", file2);
643
644 /* A generic file compare routine might compare st_dev & st_ino here
645 to see if the two files being compared are actually the same file.
646 But that won't happen in CVS, so we won't bother. */
647
648 if (sb1.st_size != sb2.st_size)
649 ret = 1;
650 else if (sb1.st_size == 0)
651 ret = 0;
652 else
653 {
654 /* FIXME: compute the optimal buffer size by computing the least
655 common multiple of the files st_blocks field */
656 size_t buf_size = 8 * 1024;
657 size_t read1;
658 size_t read2;
659
660 buf1 = xmalloc (buf_size);
661 buf2 = xmalloc (buf_size);
662
663 do
664 {
665 read1 = block_read (fd1, buf1, buf_size);
666 if (read1 == (size_t)-1)
667 error (1, errno, "cannot read file %s for comparing", file1);
668
669 read2 = block_read (fd2, buf2, buf_size);
670 if (read2 == (size_t)-1)
671 error (1, errno, "cannot read file %s for comparing", file2);
672
673 /* assert (read1 == read2); */
674
675 ret = memcmp(buf1, buf2, read1);
676 } while (ret == 0 && read1 == buf_size);
677
678 free (buf1);
679 free (buf2);
680 }
681
682 (void) close (fd1);
683 (void) close (fd2);
684 return (ret);
685 }
686
687 /* Generate a unique temporary filename. Returns a pointer to a newly
688 * malloc'd string containing the name. Returns successfully or not at
689 * all.
690 *
691 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!!
692 *
693 * and yes, I know about the way the rcs commands use temp files. I think
694 * they should be converted too but I don't have time to look into it right
695 * now.
696 */
697 char *
cvs_temp_name()698 cvs_temp_name ()
699 {
700 char *fn;
701 FILE *fp;
702
703 fp = cvs_temp_file (&fn);
704 if (fp == NULL)
705 error (1, errno, "Failed to create temporary file");
706 if (fclose (fp) == EOF)
707 error (0, errno, "Failed to close temporary file %s", fn);
708 return fn;
709 }
710
711 /* Generate a unique temporary filename and return an open file stream
712 * to the truncated file by that name
713 *
714 * INPUTS
715 * filename where to place the pointer to the newly allocated file
716 * name string
717 *
718 * OUTPUTS
719 * filename dereferenced, will point to the newly allocated file
720 * name string. This value is undefined if the function
721 * returns an error.
722 *
723 * RETURNS
724 * An open file pointer to a read/write mode empty temporary file with the
725 * unique file name or NULL on failure.
726 *
727 * ERRORS
728 * on error, errno will be set to some value either by CVS_FOPEN or
729 * whatever system function is called to generate the temporary file name
730 */
731 /* There are at least four functions for generating temporary
732 * filenames. We use mkstemp (BSD 4.3) if possible, else tempnam (SVID 3),
733 * else mktemp (BSD 4.3), and as last resort tmpnam (POSIX). Reason is that
734 * mkstemp, tempnam, and mktemp both allow to specify the directory in which
735 * the temporary file will be created.
736 *
737 * And the _correct_ way to use the deprecated functions probably involves
738 * opening file descriptors using O_EXCL & O_CREAT and even doing the annoying
739 * NFS locking thing, but until I hear of more problems, I'm not going to
740 * bother.
741 */
cvs_temp_file(filename)742 FILE *cvs_temp_file (filename)
743 char **filename;
744 {
745 char *fn;
746 FILE *fp;
747
748 /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
749 * some of the rcs & diff functions which rely on a temp file run in
750 * noexec mode too.
751 */
752
753 assert (filename != NULL);
754
755 #ifdef HAVE_MKSTEMP
756
757 {
758 int fd;
759
760 fn = xmalloc (strlen (Tmpdir) + 11);
761 sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
762 fd = mkstemp (fn);
763
764 /* a NULL return will be interpreted by callers as an error and
765 * errno should still be set
766 */
767 if (fd == -1) fp = NULL;
768 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
769 {
770 /* attempt to close and unlink the file since mkstemp returned successfully and
771 * we believe it's been created and opened
772 */
773 int save_errno = errno;
774 if (close (fd))
775 error (0, errno, "Failed to close temporary file %s", fn);
776 if (CVS_UNLINK (fn))
777 error (0, errno, "Failed to unlink temporary file %s", fn);
778 errno = save_errno;
779 }
780
781 if (fp == NULL) free (fn);
782 /* mkstemp is defined to open mode 0600 using glibc 2.0.7+ */
783 /* FIXME - configure can probably tell us which version of glibc we are
784 * linking to and not chmod for 2.0.7+
785 */
786 else chmod (fn, 0600);
787
788 }
789
790 #elif HAVE_TEMPNAM
791
792 /* tempnam has been deprecated due to under-specification */
793
794 fn = tempnam (Tmpdir, "cvs");
795 if (fn == NULL) fp = NULL;
796 else if ((fp = CVS_FOPEN (fn, "w+")) == NULL) free (fn);
797 else chmod (fn, 0600);
798
799 /* tempnam returns a pointer to a newly malloc'd string, so there's
800 * no need for a xstrdup
801 */
802
803 #elif HAVE_MKTEMP
804
805 /* mktemp has been deprecated due to the BSD 4.3 specification specifying
806 * that XXXXXX will be replaced by a PID and a letter, creating only 26
807 * possibilities, a security risk, and a race condition.
808 */
809
810 {
811 char *ifn;
812
813 ifn = xmalloc (strlen (Tmpdir) + 11);
814 sprintf (ifn, "%s/%s", Tmpdir, "cvsXXXXXX" );
815 fn = mktemp (ifn);
816
817 if (fn == NULL) fp = NULL;
818 else fp = CVS_FOPEN (fn, "w+");
819
820 if (fp == NULL) free (ifn);
821 else chmod (fn, 0600);
822
823 }
824
825 #else /* use tmpnam if all else fails */
826
827 /* tmpnam is deprecated */
828
829 {
830 char ifn[L_tmpnam + 1];
831
832 fn = tmpnam (ifn);
833
834 if (fn == NULL) fp = NULL;
835 else if ((fp = CVS_FOPEN (ifn, "w+")) != NULL)
836 {
837 fn = xstrdup (ifn);
838 chmod (fn, 0600);
839 }
840
841 }
842
843 #endif
844
845 *filename = fn;
846 return fp;
847 }
848
849 /* Return non-zero iff FILENAME is absolute.
850 Trivial under Unix, but more complicated under other systems. */
851 int
isabsolute(filename)852 isabsolute (filename)
853 const char *filename;
854 {
855 return filename[0] == '/';
856 }
857
858 /*
859 * Return a string (dynamically allocated) with the name of the file to which
860 * LINK is symlinked.
861 */
862 char *
xreadlink(link)863 xreadlink (link)
864 const char *link;
865 {
866 char *file = NULL;
867 char *tfile;
868 int buflen = 128;
869 int link_name_len;
870
871 if (!islink (link))
872 return NULL;
873
874 /* Get the name of the file to which `from' is linked.
875 FIXME: what portability issues arise here? Are readlink &
876 ENAMETOOLONG defined on all systems? -twp */
877 do
878 {
879 file = xrealloc (file, buflen);
880 link_name_len = readlink (link, file, buflen - 1);
881 buflen *= 2;
882 }
883 while (link_name_len < 0 && errno == ENAMETOOLONG);
884
885 if (link_name_len < 0)
886 error (1, errno, "cannot readlink %s", link);
887
888 file[link_name_len] = '\0';
889
890 tfile = xstrdup (file);
891 free (file);
892
893 return tfile;
894 }
895
896
897 /* Return a pointer into PATH's last component. */
898 char *
last_component(path)899 last_component (path)
900 char *path;
901 {
902 char *last = strrchr (path, '/');
903
904 if (last && (last != path))
905 return last + 1;
906 else
907 return path;
908 }
909
910 /* Return the home directory. Returns a pointer to storage
911 managed by this function or its callees (currently getenv).
912 This function will return the same thing every time it is
913 called. Returns NULL if there is no home directory.
914
915 Note that for a pserver server, this may return root's home
916 directory. What typically happens is that upon being started from
917 inetd, before switching users, the code in cvsrc.c calls
918 get_homedir which remembers root's home directory in the static
919 variable. Then the switch happens and get_homedir might return a
920 directory that we don't even have read or execute permissions for
921 (which is bad, when various parts of CVS try to read there). One
922 fix would be to make the value returned by get_homedir only good
923 until the next call (which would free the old value). Another fix
924 would be to just always malloc our answer, and let the caller free
925 it (that is best, because some day we may need to be reentrant).
926
927 The workaround is to put -f in inetd.conf which means that
928 get_homedir won't get called until after the switch in user ID.
929
930 The whole concept of a "home directory" on the server is pretty
931 iffy, although I suppose some people probably are relying on it for
932 .cvsrc and such, in the cases where it works. */
933 char *
get_homedir()934 get_homedir ()
935 {
936 static char *home = NULL;
937 char *env;
938 struct passwd *pw;
939
940 if (home != NULL)
941 return home;
942
943 if (
944 #ifdef SERVER_SUPPORT
945 !server_active &&
946 #endif
947 (env = getenv ("HOME")) != NULL)
948 home = env;
949 else if ((pw = (struct passwd *) getpwuid (getuid ()))
950 && pw->pw_dir)
951 home = xstrdup (pw->pw_dir);
952 else
953 return 0;
954
955 return home;
956 }
957
958 /* See cvs.h for description. On unix this does nothing, because the
959 shell expands the wildcards. */
960 void
expand_wild(argc,argv,pargc,pargv)961 expand_wild (argc, argv, pargc, pargv)
962 int argc;
963 char **argv;
964 int *pargc;
965 char ***pargv;
966 {
967 int i;
968 if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
969 *pargc = 0;
970 *pargv = NULL;
971 error (0, 0, "expand_wild: too many arguments");
972 return;
973 }
974 *pargc = argc;
975 *pargv = xmalloc (xtimes (argc, sizeof (char *)));
976 for (i = 0; i < argc; ++i)
977 (*pargv)[i] = xstrdup (argv[i]);
978 }
979
980 #ifdef SERVER_SUPPORT
981 /* Case-insensitive string compare. I know that some systems
982 have such a routine, but I'm not sure I see any reasons for
983 dealing with the hair of figuring out whether they do (I haven't
984 looked into whether this is a performance bottleneck; I would guess
985 not). */
986 int
cvs_casecmp(str1,str2)987 cvs_casecmp (str1, str2)
988 char *str1;
989 char *str2;
990 {
991 char *p;
992 char *q;
993 int pqdiff;
994
995 p = str1;
996 q = str2;
997 while ((pqdiff = tolower (*p) - tolower (*q)) == 0)
998 {
999 if (*p == '\0')
1000 return 0;
1001 ++p;
1002 ++q;
1003 }
1004 return pqdiff;
1005 }
1006
1007 /* Case-insensitive file open. As you can see, this is an expensive
1008 call. We don't regard it as our main strategy for dealing with
1009 case-insensitivity. Returns errno code or 0 for success. Puts the
1010 new file in *FP. NAME and MODE are as for fopen. If PATHP is not
1011 NULL, then put a malloc'd string containing the pathname as found
1012 into *PATHP. *PATHP is only set if the return value is 0.
1013
1014 Might be cleaner to separate the file finding (which just gives
1015 *PATHP) from the file opening (which the caller can do). For one
1016 thing, might make it easier to know whether to put NAME or *PATHP
1017 into error messages. */
1018 int
fopen_case(name,mode,fp,pathp)1019 fopen_case (name, mode, fp, pathp)
1020 char *name;
1021 char *mode;
1022 FILE **fp;
1023 char **pathp;
1024 {
1025 struct dirent *dp;
1026 DIR *dirp;
1027 char *dir;
1028 char *fname;
1029 char *found_name;
1030 int retval;
1031
1032 /* Separate NAME into directory DIR and filename within the directory
1033 FNAME. */
1034 dir = xstrdup (name);
1035 fname = strrchr (dir, '/');
1036 if (fname == NULL)
1037 error (1, 0, "internal error: relative pathname in fopen_case");
1038 *fname++ = '\0';
1039
1040 found_name = NULL;
1041 dirp = CVS_OPENDIR (dir);
1042 if (dirp == NULL)
1043 {
1044 if (existence_error (errno))
1045 {
1046 /* This can happen if we are looking in the Attic and the Attic
1047 directory does not exist. Return the error to the caller;
1048 they know what to do with it. */
1049 retval = errno;
1050 goto out;
1051 }
1052 else
1053 {
1054 /* Give a fatal error; that way the error message can be
1055 more specific than if we returned the error to the caller. */
1056 error (1, errno, "cannot read directory %s", dir);
1057 }
1058 }
1059 errno = 0;
1060 while ((dp = CVS_READDIR (dirp)) != NULL)
1061 {
1062 if (cvs_casecmp (dp->d_name, fname) == 0)
1063 {
1064 if (found_name != NULL)
1065 error (1, 0, "%s is ambiguous; could mean %s or %s",
1066 fname, dp->d_name, found_name);
1067 found_name = xstrdup (dp->d_name);
1068 }
1069 }
1070 if (errno != 0)
1071 error (1, errno, "cannot read directory %s", dir);
1072 CVS_CLOSEDIR (dirp);
1073
1074 if (found_name == NULL)
1075 {
1076 *fp = NULL;
1077 retval = ENOENT;
1078 }
1079 else
1080 {
1081 char *p;
1082
1083 /* Copy the found name back into DIR. We are assuming that
1084 found_name is the same length as fname, which is true as
1085 long as the above code is just ignoring case and not other
1086 aspects of filename syntax. */
1087 p = dir + strlen (dir);
1088 *p++ = '/';
1089 strcpy (p, found_name);
1090 *fp = fopen (dir, mode);
1091 if (*fp == NULL)
1092 retval = errno;
1093 else
1094 retval = 0;
1095 }
1096
1097 if (pathp == NULL)
1098 free (dir);
1099 else if (retval != 0)
1100 free (dir);
1101 else
1102 *pathp = dir;
1103 free (found_name);
1104 out:
1105 return retval;
1106 }
1107 #endif /* SERVER_SUPPORT */
1108