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 "cvs.h"
21 #include <sys/param.h>
22
23 /*
24 * I don't know of a convenient way to test this at configure time, or else
25 * I'd certainly do it there.
26 */
27 #if defined(NeXT)
28 #define LOSING_TMPNAM_FUNCTION
29 #endif
30
31 static int deep_remove_dir PROTO((const char *path));
32
33 /*
34 * Copies "from" to "to".
35 */
36 void
copy_file(from,to)37 copy_file (from, to)
38 const char *from;
39 const char *to;
40 {
41 struct stat sb;
42 struct utimbuf t;
43 int fdin, fdout;
44
45 if (trace)
46 #ifdef SERVER_SUPPORT
47 (void) fprintf (stderr, "%c-> copy(%s,%s)\n",
48 (server_active) ? 'S' : ' ', from, to);
49 #else
50 (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to);
51 #endif
52 if (noexec)
53 return;
54
55 if ((fdin = open (from, O_RDONLY | O_BINARY)) < 0)
56 error (1, errno, "cannot open %s for copying", from);
57 if (fstat (fdin, &sb) < 0)
58 error (1, errno, "cannot fstat %s", from);
59 if ((fdout = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY,
60 (int) sb.st_mode & 07777)) < 0)
61 error (1, errno, "cannot create %s for copying", to);
62 if (sb.st_size > 0)
63 {
64 char buf[BUFSIZ];
65 int n;
66
67 for (;;)
68 {
69 n = read (fdin, buf, sizeof(buf));
70 if (n == -1)
71 {
72 #ifdef EINTR
73 if (errno == EINTR)
74 continue;
75 #endif
76 error (1, errno, "cannot read file %s for copying", from);
77 }
78 else if (n == 0)
79 break;
80
81 if (write(fdout, buf, n) != n) {
82 error (1, errno, "cannot write file %s for copying", to);
83 }
84 }
85
86 #ifdef HAVE_FSYNC
87 if (fsync (fdout))
88 error (1, errno, "cannot fsync file %s after copying", to);
89 #endif
90 }
91
92 if (close (fdin) < 0)
93 error (0, errno, "cannot close %s", from);
94 if (close (fdout) < 0)
95 error (1, errno, "cannot close %s", to);
96
97 /* now, set the times for the copied file to match those of the original */
98 memset ((char *) &t, 0, sizeof (t));
99 t.actime = sb.st_atime;
100 t.modtime = sb.st_mtime;
101 (void) utime (to, &t);
102 }
103
104 /* FIXME-krp: these functions would benefit from caching the char * &
105 stat buf. */
106
107 /*
108 * Returns non-zero if the argument file is a directory, or is a symbolic
109 * link which points to a directory.
110 */
111 int
isdir(file)112 isdir (file)
113 const char *file;
114 {
115 struct stat sb;
116
117 if (stat (file, &sb) < 0)
118 return (0);
119 return (S_ISDIR (sb.st_mode));
120 }
121
122 /*
123 * Returns non-zero if the argument file is a symbolic link.
124 */
125 int
islink(file)126 islink (file)
127 const char *file;
128 {
129 #ifdef S_ISLNK
130 struct stat sb;
131
132 if (lstat (file, &sb) < 0)
133 return (0);
134 return (S_ISLNK (sb.st_mode));
135 #else
136 return (0);
137 #endif
138 }
139
140 /*
141 * Returns non-zero if the argument file exists.
142 */
143 int
isfile(file)144 isfile (file)
145 const char *file;
146 {
147 return isaccessible(file, F_OK);
148 }
149
150 /*
151 * Returns non-zero if the argument file is readable.
152 */
153 int
isreadable(file)154 isreadable (file)
155 const char *file;
156 {
157 return isaccessible(file, R_OK);
158 }
159
160 /*
161 * Returns non-zero if the argument file is writable.
162 */
163 int
iswritable(file)164 iswritable (file)
165 const char *file;
166 {
167 return isaccessible(file, W_OK);
168 }
169
170 /*
171 * Returns non-zero if the argument file is accessable according to
172 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
173 * bits set.
174 */
175 int
isaccessible(file,mode)176 isaccessible (file, mode)
177 const char *file;
178 const int mode;
179 {
180 #ifdef SETXID_SUPPORT
181 struct stat sb;
182 int umask = 0;
183 int gmask = 0;
184 int omask = 0;
185 int uid;
186
187 if (stat(file, &sb) == -1)
188 return 0;
189 if (mode == F_OK)
190 return 1;
191
192 uid = geteuid();
193 if (uid == 0) /* superuser */
194 {
195 if (mode & X_OK)
196 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH);
197 else
198 return 1;
199 }
200
201 if (mode & R_OK)
202 {
203 umask |= S_IRUSR;
204 gmask |= S_IRGRP;
205 omask |= S_IROTH;
206 }
207 if (mode & W_OK)
208 {
209 umask |= S_IWUSR;
210 gmask |= S_IWGRP;
211 omask |= S_IWOTH;
212 }
213 if (mode & X_OK)
214 {
215 umask |= S_IXUSR;
216 gmask |= S_IXGRP;
217 omask |= S_IXOTH;
218 }
219
220 if (sb.st_uid == uid)
221 return (sb.st_mode & umask) == umask;
222 else if (sb.st_gid == getegid())
223 return (sb.st_mode & gmask) == gmask;
224 else
225 return (sb.st_mode & omask) == omask;
226 #else
227 return access(file, mode) == 0;
228 #endif
229 }
230
231 /*
232 * Open a file and die if it fails
233 */
234 FILE *
open_file(name,mode)235 open_file (name, mode)
236 const char *name;
237 const char *mode;
238 {
239 FILE *fp;
240
241 if ((fp = fopen (name, mode)) == NULL)
242 error (1, errno, "cannot open %s", name);
243 return (fp);
244 }
245
246 /*
247 * Make a directory and die if it fails
248 */
249 void
make_directory(name)250 make_directory (name)
251 const char *name;
252 {
253 struct stat sb;
254
255 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
256 error (0, 0, "%s already exists but is not a directory", name);
257 if (!noexec && mkdir (name, 0777) < 0)
258 error (1, errno, "cannot make directory %s", name);
259 }
260
261 /*
262 * Make a path to the argument directory, printing a message if something
263 * goes wrong.
264 */
265 void
make_directories(name)266 make_directories (name)
267 const char *name;
268 {
269 char *cp;
270
271 if (noexec)
272 return;
273
274 if (mkdir (name, 0777) == 0 || errno == EEXIST)
275 return;
276 if (! existence_error (errno))
277 {
278 error (0, errno, "cannot make path to %s", name);
279 return;
280 }
281 if ((cp = strrchr (name, '/')) == NULL)
282 return;
283 *cp = '\0';
284 make_directories (name);
285 *cp++ = '/';
286 if (*cp == '\0')
287 return;
288 (void) mkdir (name, 0777);
289 }
290
291 /* Create directory NAME if it does not already exist; fatal error for
292 other errors. Returns 0 if directory was created; 1 if it already
293 existed. */
294 int
mkdir_if_needed(name)295 mkdir_if_needed (name)
296 char *name;
297 {
298 if (mkdir (name, 0777) < 0)
299 {
300 if (errno != EEXIST)
301 error (1, errno, "cannot make directory %s", name);
302 return 1;
303 }
304 return 0;
305 }
306
307 /*
308 * Change the mode of a file, either adding write permissions, or removing
309 * all write permissions. Either change honors the current umask setting.
310 * The EMX doc (0.9c, emxlib.doc) says that chmod sets/clears the readonly
311 * bit. But it always seemed to be a noop when I tried it. Therefore,
312 * I've copied over the "attrib" code from os2/filesubr.c.
313 */
314 void
xchmod(fname,writable)315 xchmod (fname, writable)
316 char *fname;
317 int writable;
318 {
319 char *attrib_cmd;
320 char *attrib_option;
321 char *whole_cmd;
322 char *p;
323 char *q;
324
325 if (!isfile (fname))
326 {
327 error (0, 0, "cannot change mode of file %s; it does not exist",
328 fname);
329 return;
330 }
331
332 attrib_cmd = "attrib "; /* No, really? */
333
334 if (writable)
335 attrib_option = "-r "; /* make writeable */
336 else
337 attrib_option = "+r "; /* make read-only */
338
339 whole_cmd = xmalloc (strlen (attrib_cmd)
340 + strlen (attrib_option)
341 + strlen (fname)
342 + 1);
343
344 strcpy (whole_cmd, attrib_cmd);
345 strcat (whole_cmd, attrib_option);
346
347 /* Copy fname to the end of whole_cmd, translating / to \.
348 Attrib doesn't take / but many parts of CVS rely
349 on being able to use it. */
350 p = whole_cmd + strlen (whole_cmd);
351 q = fname;
352 while (*q)
353 {
354 if (*q == '/')
355 *p++ = '\\';
356 else
357 *p++ = *q;
358 ++q;
359 }
360 *p = '\0';
361
362 system (whole_cmd);
363 free (whole_cmd);
364 }
365
366 /*
367 * Rename a file and die if it fails
368 */
369 void
rename_file(from,to)370 rename_file (from, to)
371 const char *from;
372 const char *to;
373 {
374 if (trace)
375 #ifdef SERVER_SUPPORT
376 (void) fprintf (stderr, "%c-> rename(%s,%s)\n",
377 (server_active) ? 'S' : ' ', from, to);
378 #else
379 (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to);
380 #endif
381 if (noexec)
382 return;
383
384 unlink_file (to);
385 if (rename (from, to) != 0)
386 error (1, errno, "cannot rename file %s to %s", from, to);
387 }
388
389 /*
390 * unlink a file, if possible.
391 */
392 int
unlink_file(f)393 unlink_file (f)
394 const char *f;
395 {
396 if (trace)
397 #ifdef SERVER_SUPPORT
398 (void) fprintf (stderr, "%c-> unlink(%s)\n",
399 (server_active) ? 'S' : ' ', f);
400 #else
401 (void) fprintf (stderr, "-> unlink(%s)\n", f);
402 #endif
403 if (noexec)
404 return (0);
405
406 if (isfile (f))
407 xchmod ((char *)f, 1);
408 return (unlink (f));
409 }
410
411 /*
412 * Unlink a file or dir, if possible. If it is a directory do a deep
413 * removal of all of the files in the directory. Return -1 on error
414 * (in which case errno is set).
415 */
416 int
unlink_file_dir(f)417 unlink_file_dir (f)
418 const char *f;
419 {
420 if (trace)
421 #ifdef SERVER_SUPPORT
422 (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n",
423 (server_active) ? 'S' : ' ', f);
424 #else
425 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f);
426 #endif
427 if (noexec)
428 return (0);
429
430 /* For at least some unices, if root tries to unlink() a directory,
431 instead of doing something rational like returning EISDIR,
432 the system will gleefully go ahead and corrupt the filesystem.
433 So we first call isdir() to see if it is OK to call unlink(). This
434 doesn't quite work--if someone creates a directory between the
435 call to isdir() and the call to unlink(), we'll still corrupt
436 the filesystem. Where is the Unix Haters Handbook when you need
437 it? */
438 if (isdir(f))
439 return deep_remove_dir(f);
440 else
441 {
442 if (unlink (f) != 0)
443 return -1;
444 }
445 /* We were able to remove the file from the disk */
446 return 0;
447 }
448
449 /* Remove a directory and everything it contains. Returns 0 for
450 * success, -1 for failure (in which case errno is set).
451 */
452
453 static int
deep_remove_dir(path)454 deep_remove_dir (path)
455 const char *path;
456 {
457 DIR *dirp;
458 struct dirent *dp;
459 char buf[PATH_MAX];
460
461 if (rmdir (path) != 0)
462 {
463 if (errno == ENOTEMPTY
464 || errno == EEXIST
465 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
466 (it defines ENOTEMPTY and EEXIST to 17 but actually
467 returns 87). */
468 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
469 {
470 if ((dirp = opendir (path)) == NULL)
471 /* If unable to open the directory return
472 * an error
473 */
474 return -1;
475
476 while ((dp = readdir (dirp)) != NULL)
477 {
478 if (strcmp (dp->d_name, ".") == 0 ||
479 strcmp (dp->d_name, "..") == 0)
480 continue;
481
482 sprintf (buf, "%s/%s", path, dp->d_name);
483
484 /* See comment in unlink_file_dir explanation of why we use
485 isdir instead of just calling unlink and checking the
486 status. */
487 if (isdir(buf))
488 {
489 if (deep_remove_dir(buf))
490 {
491 closedir(dirp);
492 return -1;
493 }
494 }
495 else
496 {
497 if (unlink (buf) != 0)
498 {
499 closedir(dirp);
500 return -1;
501 }
502 }
503 }
504 closedir (dirp);
505 return rmdir (path);
506 }
507 else
508 return -1;
509 }
510
511 /* Was able to remove the directory return 0 */
512 return 0;
513 }
514
515 /* Read NCHARS bytes from descriptor FD into BUF.
516 Return the number of characters successfully read.
517 The number returned is always NCHARS unless end-of-file or error. */
518 static size_t
block_read(fd,buf,nchars)519 block_read (fd, buf, nchars)
520 int fd;
521 char *buf;
522 size_t nchars;
523 {
524 char *bp = buf;
525 size_t nread;
526
527 do
528 {
529 nread = read (fd, bp, nchars);
530 if (nread == (size_t)-1)
531 {
532 #ifdef EINTR
533 if (errno == EINTR)
534 continue;
535 #endif
536 return (size_t)-1;
537 }
538
539 if (nread == 0)
540 break;
541
542 bp += nread;
543 nchars -= nread;
544 } while (nchars != 0);
545
546 return bp - buf;
547 }
548
549
550 /*
551 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
552 */
553 int
xcmp(file1,file2)554 xcmp (file1, file2)
555 const char *file1;
556 const char *file2;
557 {
558 char *buf1, *buf2;
559 struct stat sb1, sb2;
560 int fd1, fd2;
561 int ret;
562
563 if ((fd1 = open (file1, O_RDONLY | O_BINARY)) < 0)
564 error (1, errno, "cannot open file %s for comparing", file1);
565 if ((fd2 = open (file2, O_RDONLY | O_BINARY)) < 0)
566 error (1, errno, "cannot open file %s for comparing", file2);
567 if (fstat (fd1, &sb1) < 0)
568 error (1, errno, "cannot fstat %s", file1);
569 if (fstat (fd2, &sb2) < 0)
570 error (1, errno, "cannot fstat %s", file2);
571
572 /* A generic file compare routine might compare st_dev & st_ino here
573 to see if the two files being compared are actually the same file.
574 But that won't happen in CVS, so we won't bother. */
575
576 if (sb1.st_size != sb2.st_size)
577 ret = 1;
578 else if (sb1.st_size == 0)
579 ret = 0;
580 else
581 {
582 /* FIXME: compute the optimal buffer size by computing the least
583 common multiple of the files st_blocks field */
584 size_t buf_size = 8 * 1024;
585 size_t read1;
586 size_t read2;
587
588 buf1 = xmalloc (buf_size);
589 buf2 = xmalloc (buf_size);
590
591 do
592 {
593 read1 = block_read (fd1, buf1, buf_size);
594 if (read1 == (size_t)-1)
595 error (1, errno, "cannot read file %s for comparing", file1);
596
597 read2 = block_read (fd2, buf2, buf_size);
598 if (read2 == (size_t)-1)
599 error (1, errno, "cannot read file %s for comparing", file2);
600
601 /* assert (read1 == read2); */
602
603 ret = memcmp(buf1, buf2, read1);
604 } while (ret == 0 && read1 == buf_size);
605
606 free (buf1);
607 free (buf2);
608 }
609
610 (void) close (fd1);
611 (void) close (fd2);
612 return (ret);
613 }
614
615
616 /* Just in case this implementation does not define this. */
617 #ifndef L_tmpnam
618 #define L_tmpnam 50
619 #endif
620
621
622 #ifdef LOSING_TMPNAM_FUNCTION
623 char *
cvs_temp_name()624 cvs_temp_name ()
625 {
626 char value[L_tmpnam + 1];
627
628 /* FIXME: Should be using TMPDIR. */
629 strcpy (value, "/tmp/cvsXXXXXX");
630 mktemp (value);
631 return xstrdup (value);
632 }
633 #else
634 /* Generate a unique temporary filename. Returns a pointer to a newly
635 malloc'd string containing the name. Returns successfully or not at
636 all. */
637 char *
cvs_temp_name()638 cvs_temp_name ()
639 {
640 char value[L_tmpnam + 1];
641 char *retval;
642
643 /* FIXME: should be using TMPDIR, perhaps by using tempnam on systems
644 which have it. */
645 retval = tmpnam (value);
646 if (retval == NULL)
647 error (1, errno, "cannot generate temporary filename");
648 return xstrdup (retval);
649 }
650 #endif
651
652
653 /* Return non-zero iff FILENAME is absolute.
654 Trivial under Unix, but more complicated under other systems.
655 Under EMX let _fnisabs do all this work. */
656 int
isabsolute(filename)657 isabsolute (filename)
658 const char *filename;
659 {
660 return _fnisabs(filename);
661 }
662
663
664 /* Return a pointer into PATH's last component. */
665 char *
last_component(path)666 last_component (path)
667 char *path;
668 {
669 char *last;
670
671 /* We can't be sure here if 'path' is already slashified. */
672 _fnslashify (path);
673
674 last = strrchr (path, '/');
675
676 if (last && (last != path))
677 return last + 1;
678 else
679 return path;
680 }
681
682 /* Return the home directory. Returns a pointer to storage
683 managed by this function or its callees (currently getenv).
684 This function will return the same thing every time it is
685 called. */
686 char *
get_homedir()687 get_homedir ()
688 {
689 static char *home = NULL;
690 char *env = getenv ("HOME");
691 struct passwd *pw;
692
693 if (home != NULL)
694 return home;
695
696 if (env)
697 home = env;
698 else if ((pw = (struct passwd *) getpwuid (getuid ()))
699 && pw->pw_dir)
700 home = xstrdup (pw->pw_dir);
701 else
702 return 0;
703
704 return home;
705 }
706
707 /* See cvs.h for description. On unix this does nothing, because the
708 shell expands the wildcards. Under EMX, use _fnexplode to get the
709 expanded filenames */
710 void
expand_wild(argc,argv,pargc,pargv)711 expand_wild (argc, argv, pargc, pargv)
712 int argc;
713 char **argv;
714 int *pargc;
715 char ***pargv;
716 {
717 int i;
718 *pargc = argc;
719 *pargv = (char **) xmalloc (argc * sizeof (char *));
720 for (i = 0; i < argc; ++i)
721 (*pargv)[i] = xstrdup (argv[i]);
722 }
723
724 unsigned char
725 OS2_filename_classes[] =
726 {
727 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
728 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
729 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
730 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
731 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
732 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
733 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37,
734 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f,
735 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
736 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
737 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
738 0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f,
739 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
740 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
741 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
742 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f,
743 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
744 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
745 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
746 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
747 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7,
748 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf,
749 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7,
750 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf,
751 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7,
752 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf,
753 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7,
754 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf,
755 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7,
756 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef,
757 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7,
758 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff,
759 };
760
761
762 /* Like strcmp, but with the appropriate tweaks for file names.
763 Under OS/2, filenames are case-insensitive but case-preserving, and
764 both \ and / are path element separators. */
765 int
fncmp(const char * n1,const char * n2)766 fncmp (const char *n1, const char *n2)
767 {
768 char fn1[MAXNAMLEN], fn2[MAXNAMLEN];
769
770 strcpy (fn1, n1); _fnslashify(fn1);
771 strcpy (fn2, n2); _fnslashify(fn2);
772
773 return _fncmp ((unsigned char *) fn1, (unsigned char *) fn2);
774 }
775
776
777 /* Fold characters in FILENAME to their canonical forms.
778 If FOLD_FN_CHAR is not #defined, the system provides a default
779 definition for this. */
780 void
fnfold(char * filename)781 fnfold (char *filename)
782 {
783 while (*filename)
784 {
785 *filename = FOLD_FN_CHAR (*filename);
786 filename++;
787 }
788 }
789