Пример #1
0
/*
 * Returns non-zero if the argument file is a symbolic link.
 */
int islink (const char *file)
{
#ifdef S_ISLNK
    struct stat sb;

    if (CVS_LSTAT (file, &sb) < 0)
        return (0);
    return (S_ISLNK (sb.st_mode));
#else
    return (0);
#endif
}
Пример #2
0
/*
 * Returns non-zero if the argument file is a block or
 * character special device.
 */
int isdevice (const char *file)
{
    struct stat sb;

    if (CVS_LSTAT (file, &sb) < 0)
        return (0);
#ifdef S_ISBLK
    if (S_ISBLK (sb.st_mode))
        return 1;
#endif
#ifdef S_ISCHR
    if (S_ISCHR (sb.st_mode))
        return 1;
#endif
    return 0;
}
Пример #3
0
/*
 * Process the current directory, looking for files not in ILIST and
 * not on the global ignore list for this directory.  If we find one,
 * call PROC passing it the name of the file and the update dir.
 * ENTRIES is the entries list, which is used to identify known
 * directories.  ENTRIES may be NULL, in which case we assume that any
 * directory with a CVS administration directory is known.
 */
void ignore_files (List *ilist, List *entries, char *update_dir, Ignore_proc proc)
{
    int subdirs;
    DIR *dirp;
    struct dirent *dp;
    struct stat sb;
    char *file;
    char *xdir;
    List *files;
    Node *p;

    /* Set SUBDIRS if we have subdirectory information in ENTRIES.  */
    if (entries == NULL)
		subdirs = 0;
    else
    {
		struct stickydirtag *sdtp;

		sdtp = (struct stickydirtag *) entries->list->data;
		subdirs = sdtp == NULL || sdtp->subdirs;
    }

    /* we get called with update_dir set to "." sometimes... strip it */
    if (strcmp (update_dir, ".") == 0)
		xdir = "";
    else
		xdir = update_dir;

    dirp = opendir (".");
    if (dirp == NULL)
    {
		error (0, errno, "cannot open current directory");
		return;
    }

    ign_add_file (CVSDOTIGNORE, 1);
    wrap_add_file (CVSDOTWRAPPER, true);

    /* Make a list for the files.  */
    files = getlist ();

    while (errno = 0, (dp = readdir (dirp)) != NULL)
    {
		file = dp->d_name;
		if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
			continue;
		if (findnode_fn (ilist, file) != NULL)
			continue;
		if (subdirs)
		{
			Node *node;

			node = findnode_fn (entries, file);
			if (node != NULL
			&& ((Entnode *) node->data)->type == ENT_SUBDIR)
			{
			char *p;
			int dir;

			/* For consistency with past behaviour, we only ignore
			this directory if there is a CVS subdirectory.
			This will normally be the case, but the user may
			have messed up the working directory somehow.  */
			p = (char*)xmalloc (strlen (file) + sizeof CVSADM + 10);
			sprintf (p, "%s/%s", file, CVSADM);
			dir = isdir (p);
			xfree (p);
			if (dir)
				continue;
			}
		}

		/* We could be ignoring FIFOs and other files which are neither
		regular files nor directories here.  */
		if (ign_name (file))
			continue;

		if (CVS_LSTAT(file, &sb) != -1)
		{
			if (S_ISDIR (sb.st_mode))
			{
				if (! subdirs)
				{
					char *temp;

					temp = (char*)xmalloc (strlen (file) + sizeof (CVSADM) + 10);
					sprintf (temp, "%s/%s", file, CVSADM);
					if (isdir (temp))
					{
						xfree (temp);
						continue;
					}
					xfree (temp);
				}
			}
#ifdef S_ISLNK
			else if (S_ISLNK (sb.st_mode))
			{
				continue;
			}
#endif
		}

		p = getnode ();
		p->type = FILES;
		p->key = xstrdup (file);
		addnode (files, p);
    }
    if (errno != 0)
		error (0, errno, "error reading current directory");
    closedir (dirp);

    sortlist (files, fsortcmp);
    for (p = files->list->next; p != files->list; p = p->next)
	(*proc) (p->key, xdir);
    dellist (&files);
}
Пример #4
0
/*
 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
 * If FILE1 and FILE2 are special files, compare their salient characteristics
 * (i.e. major/minor device numbers, links, etc.
 */
int xcmp (const char *file1, const char *file2)
{
    char *buf1, *buf2;
    struct stat sb1, sb2;
    int fd1, fd2;
    int ret;

    if (CVS_LSTAT (file1, &sb1) < 0)
        error (1, errno, "cannot lstat %s", fn_root(file1));
    if (CVS_LSTAT (file2, &sb2) < 0)
        error (1, errno, "cannot lstat %s", fn_root(file2));

    /* If FILE1 and FILE2 are not the same file type, they are unequal. */
    if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
        return 1;

    /* If FILE1 and FILE2 are symlinks, they are equal if they point to
       the same thing. */
    if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
    {
        int result;
        buf1 = xreadlink (file1);
        buf2 = xreadlink (file2);
        result = (strcmp (buf1, buf2) == 0);
        xfree (buf1);
        xfree (buf2);
        return result;
    }

    /* If FILE1 and FILE2 are devices, they are equal if their device
       numbers match. */
    if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
    {
#ifdef HAVE_STRUCT_STAT_ST_RDEV
        if (sb1.st_rdev == sb2.st_rdev)
            return 0;
        else
            return 1;
#else
        error (1, 0, "cannot compare device files on this system (%s and %s)",
               file1, file2);
#endif
    }

    if ((fd1 = CVS_OPEN (file1, O_RDONLY)) < 0)
        error (1, errno, "cannot open file %s for comparing", fn_root(file1));
    if ((fd2 = CVS_OPEN (file2, O_RDONLY)) < 0)
        error (1, errno, "cannot open file %s for comparing", fn_root(file2));

    /* A generic file compare routine might compare st_dev & st_ino here
       to see if the two files being compared are actually the same file.
       But that won't happen in CVS, so we won't bother. */

    if (sb1.st_size != sb2.st_size)
        ret = 1;
    else if (sb1.st_size == 0)
        ret = 0;
    else
    {
        /* FIXME: compute the optimal buffer size by computing the least
           common multiple of the files st_blocks field */
        size_t buf_size = 8 * 1024;
        size_t read1;
        size_t read2;

        buf1 = (char*)xmalloc (buf_size);
        buf2 = (char*)xmalloc (buf_size);

        do
        {
            read1 = block_read (fd1, buf1, buf_size);
            if (read1 == (size_t)-1)
                error (1, errno, "cannot read file %s for comparing", fn_root(file1));

            read2 = block_read (fd2, buf2, buf_size);
            if (read2 == (size_t)-1)
                error (1, errno, "cannot read file %s for comparing", fn_root(file2));

            /* assert (read1 == read2); */

            ret = memcmp(buf1, buf2, read1);
        } while (ret == 0 && read1 == buf_size);

        xfree (buf1);
        xfree (buf2);
    }

    (void) close (fd1);
    (void) close (fd2);
    return (ret);
}