1 /* filesubr.c --- subroutines for dealing with files
2 Jim Blandy <jimb@cyclic.com>
4 This file is part of GNU CVS.
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
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. */
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. */
21 #include <sys/param.h>
24 * I don't know of a convenient way to test this at configure time, or else
25 * I'd certainly do it there.
28 #define LOSING_TMPNAM_FUNCTION
31 static int deep_remove_dir( const char *path );
34 * Copies "from" to "to".
47 (void) fprintf (stderr, "%c-> copy(%s,%s)\n",
48 (server_active) ? 'S' : ' ', from, to);
50 (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to);
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);
69 n = read (fdin, buf, sizeof(buf));
76 error (1, errno, "cannot read file %s for copying", from);
81 if (write(fdout, buf, n) != n) {
82 error (1, errno, "cannot write file %s for copying", to);
88 error (1, errno, "cannot fsync file %s after copying", to);
93 error (0, errno, "cannot close %s", from);
94 if (close (fdout) < 0)
95 error (1, errno, "cannot close %s", to);
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);
104 /* FIXME-krp: these functions would benefit from caching the char * &
108 * Returns non-zero if the argument file is a directory, or is a symbolic
109 * link which points to a directory.
117 if (stat (file, &sb) < 0)
119 return (S_ISDIR (sb.st_mode));
123 * Returns non-zero if the argument file is a symbolic link.
132 if (lstat (file, &sb) < 0)
134 return (S_ISLNK (sb.st_mode));
141 * Returns non-zero if the argument file exists.
147 return isaccessible(file, F_OK);
151 * Returns non-zero if the argument file is readable.
157 return isaccessible(file, R_OK);
161 * Returns non-zero if the argument file is writable.
167 return isaccessible(file, W_OK);
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
176 isaccessible (file, mode)
180 #ifdef SETXID_SUPPORT
187 if (stat(file, &sb) == -1)
193 if (uid == 0) /* superuser */
196 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH);
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;
225 return (sb.st_mode & omask) == omask;
227 return access(file, mode) == 0;
234 * Make a directory and die if it fails
237 make_directory (name)
242 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
243 error (0, 0, "%s already exists but is not a directory", name);
244 if (!noexec && mkdir (name, 0777) < 0)
245 error (1, errno, "cannot make directory %s", name);
249 * Make a path to the argument directory, printing a message if something
253 make_directories (name)
261 if (mkdir (name, 0777) == 0 || errno == EEXIST)
263 if (! existence_error (errno))
265 error (0, errno, "cannot make path to %s", name);
268 if ((cp = strrchr (name, '/')) == NULL)
271 make_directories (name);
275 (void) mkdir (name, 0777);
278 /* Create directory NAME if it does not already exist; fatal error for
279 other errors. Returns 0 if directory was created; 1 if it already
282 mkdir_if_needed (name)
285 if (mkdir (name, 0777) < 0)
288 error (1, errno, "cannot make directory %s", name);
295 * Change the mode of a file, either adding write permissions, or removing
296 * all write permissions. Either change honors the current umask setting.
297 * The EMX doc (0.9c, emxlib.doc) says that chmod sets/clears the readonly
298 * bit. But it always seemed to be a noop when I tried it. Therefore,
299 * I've copied over the "attrib" code from os2/filesubr.c.
302 xchmod (fname, writable)
314 error (0, 0, "cannot change mode of file %s; it does not exist",
319 attrib_cmd = "attrib "; /* No, really? */
322 attrib_option = "-r "; /* make writeable */
324 attrib_option = "+r "; /* make read-only */
326 whole_cmd = xmalloc (strlen (attrib_cmd)
327 + strlen (attrib_option)
331 strcpy (whole_cmd, attrib_cmd);
332 strcat (whole_cmd, attrib_option);
334 /* Copy fname to the end of whole_cmd, translating / to \.
335 Attrib doesn't take / but many parts of CVS rely
336 on being able to use it. */
337 p = whole_cmd + strlen (whole_cmd);
354 * Rename a file and die if it fails
357 rename_file (from, to)
362 #ifdef SERVER_SUPPORT
363 (void) fprintf (stderr, "%c-> rename(%s,%s)\n",
364 (server_active) ? 'S' : ' ', from, to);
366 (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to);
372 if (rename (from, to) != 0)
373 error (1, errno, "cannot rename file %s to %s", from, to);
377 * unlink a file, if possible.
384 #ifdef SERVER_SUPPORT
385 (void) fprintf (stderr, "%c-> unlink(%s)\n",
386 (server_active) ? 'S' : ' ', f);
388 (void) fprintf (stderr, "-> unlink(%s)\n", f);
394 xchmod ((char *)f, 1);
399 * Unlink a file or dir, if possible. If it is a directory do a deep
400 * removal of all of the files in the directory. Return -1 on error
401 * (in which case errno is set).
408 #ifdef SERVER_SUPPORT
409 (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n",
410 (server_active) ? 'S' : ' ', f);
412 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f);
417 /* For at least some unices, if root tries to unlink() a directory,
418 instead of doing something rational like returning EISDIR,
419 the system will gleefully go ahead and corrupt the filesystem.
420 So we first call isdir() to see if it is OK to call unlink(). This
421 doesn't quite work--if someone creates a directory between the
422 call to isdir() and the call to unlink(), we'll still corrupt
423 the filesystem. Where is the Unix Haters Handbook when you need
426 return deep_remove_dir(f);
432 /* We were able to remove the file from the disk */
436 /* Remove a directory and everything it contains. Returns 0 for
437 * success, -1 for failure (in which case errno is set).
441 deep_remove_dir (path)
448 if (rmdir (path) != 0)
450 if (errno == ENOTEMPTY
452 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
453 (it defines ENOTEMPTY and EEXIST to 17 but actually
455 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
457 if ((dirp = opendir (path)) == NULL)
458 /* If unable to open the directory return
463 while ((dp = readdir (dirp)) != NULL)
465 if (strcmp (dp->d_name, ".") == 0 ||
466 strcmp (dp->d_name, "..") == 0)
469 sprintf (buf, "%s/%s", path, dp->d_name);
471 /* See comment in unlink_file_dir explanation of why we use
472 isdir instead of just calling unlink and checking the
476 if (deep_remove_dir(buf))
484 if (unlink (buf) != 0)
498 /* Was able to remove the directory return 0 */
502 /* Read NCHARS bytes from descriptor FD into BUF.
503 Return the number of characters successfully read.
504 The number returned is always NCHARS unless end-of-file or error. */
506 block_read (fd, buf, nchars)
516 nread = read (fd, bp, nchars);
517 if (nread == (size_t)-1)
531 } while (nchars != 0);
538 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
546 struct stat sb1, sb2;
550 if ((fd1 = open (file1, O_RDONLY | O_BINARY)) < 0)
551 error (1, errno, "cannot open file %s for comparing", file1);
552 if ((fd2 = open (file2, O_RDONLY | O_BINARY)) < 0)
553 error (1, errno, "cannot open file %s for comparing", file2);
554 if (fstat (fd1, &sb1) < 0)
555 error (1, errno, "cannot fstat %s", file1);
556 if (fstat (fd2, &sb2) < 0)
557 error (1, errno, "cannot fstat %s", file2);
559 /* A generic file compare routine might compare st_dev & st_ino here
560 to see if the two files being compared are actually the same file.
561 But that won't happen in CVS, so we won't bother. */
563 if (sb1.st_size != sb2.st_size)
565 else if (sb1.st_size == 0)
569 /* FIXME: compute the optimal buffer size by computing the least
570 common multiple of the files st_blocks field */
571 size_t buf_size = 8 * 1024;
575 buf1 = xmalloc (buf_size);
576 buf2 = xmalloc (buf_size);
580 read1 = block_read (fd1, buf1, buf_size);
581 if (read1 == (size_t)-1)
582 error (1, errno, "cannot read file %s for comparing", file1);
584 read2 = block_read (fd2, buf2, buf_size);
585 if (read2 == (size_t)-1)
586 error (1, errno, "cannot read file %s for comparing", file2);
588 /* assert (read1 == read2); */
590 ret = memcmp(buf1, buf2, read1);
591 } while (ret == 0 && read1 == buf_size);
603 /* Just in case this implementation does not define this. */
609 #ifdef LOSING_TMPNAM_FUNCTION
613 char value[L_tmpnam + 1];
615 /* FIXME: Should be using TMPDIR. */
616 strcpy (value, "/tmp/cvsXXXXXX");
618 return xstrdup (value);
621 /* Generate a unique temporary filename. Returns a pointer to a newly
622 malloc'd string containing the name. Returns successfully or not at
627 char value[L_tmpnam + 1];
630 /* FIXME: should be using TMPDIR, perhaps by using tempnam on systems
632 retval = tmpnam (value);
634 error (1, errno, "cannot generate temporary filename");
635 return xstrdup (retval);
642 * xresolvepath ( const char *path )
644 * Like xreadlink(), but resolve all links in a path.
647 * path The original path.
650 * The path with any symbolic links expanded.
653 * This function exits with a fatal error if it fails to read the link for
657 xresolvepath ( path )
663 /* assert ( isdir ( path ) ); */
665 /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
666 * bit by bit calling xreadlink().
670 if ( CVS_CHDIR ( path ) < 0)
671 error ( 1, errno, "cannot chdir to %s", path );
672 if ( ( hardpath = xgetwd() ) == NULL )
673 error (1, errno, "cannot readlink %s", hardpath);
674 if ( CVS_CHDIR ( owd ) < 0)
675 error ( 1, errno, "cannot chdir to %s", owd );
680 /* Return a pointer into PATH's last component. */
682 last_component (path)
687 /* We can't be sure here if 'path' is already slashified. */
690 last = strrchr (path, '/');
692 if (last && (last != path))
698 /* Return the home directory. Returns a pointer to storage
699 managed by this function or its callees (currently getenv).
700 This function will return the same thing every time it is
705 static char *home = NULL;
706 char *env = getenv ("HOME");
714 else if ((pw = (struct passwd *) getpwuid (getuid ()))
716 home = xstrdup (pw->pw_dir);
723 /* See cvs.h for description. On unix this does nothing, because the
724 shell expands the wildcards. Under EMX, use _fnexplode to get the
725 expanded filenames */
727 expand_wild (argc, argv, pargc, pargv)
735 *pargv = (char **) xmalloc (argc * sizeof (char *));
736 for (i = 0; i < argc; ++i)
737 (*pargv)[i] = xstrdup (argv[i]);
741 OS2_filename_classes[] =
743 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
744 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
745 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
746 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
747 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
748 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
749 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37,
750 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f,
751 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
752 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
753 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
754 0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f,
755 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
756 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
757 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
758 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f,
759 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
760 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
761 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
762 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
763 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7,
764 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf,
765 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7,
766 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf,
767 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7,
768 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf,
769 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7,
770 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf,
771 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7,
772 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef,
773 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7,
774 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff,
778 /* Like strcmp, but with the appropriate tweaks for file names.
779 Under OS/2, filenames are case-insensitive but case-preserving, and
780 both \ and / are path element separators. */
782 fncmp (const char *n1, const char *n2)
784 char fn1[MAXNAMLEN], fn2[MAXNAMLEN];
786 strcpy (fn1, n1); _fnslashify(fn1);
787 strcpy (fn2, n2); _fnslashify(fn2);
789 return _fncmp ((unsigned char *) fn1, (unsigned char *) fn2);
793 /* Fold characters in FILENAME to their canonical forms.
794 If FOLD_FN_CHAR is not #defined, the system provides a default
795 definition for this. */
797 fnfold (char *filename)
801 *filename = FOLD_FN_CHAR (*filename);