Example #1
0
/****************************************************************************
Create a directory given an absolute path, perms based upon another directory
path
****************************************************************************/
static int make_bak_dir(char *fname,char *bak_path)
{
        STRUCT_STAT st;
        STRUCT_STAT *st2;
        char fullpath[MAXPATHLEN];
        extern int orig_umask;
        char *p;
        char *q;

        while(strncmp(bak_path,"./",2)==0) bak_path += 2;

        if(bak_path[strlen(bak_path)-1]!='/') {
                snprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
        } else {
                snprintf(fullpath,sizeof(fullpath),"%s",bak_path);
        }
        p=fullpath;
        q=&fullpath[strlen(fullpath)];  /* End of bak_path string */
        strcat(fullpath,fname);

        /* Make the directories */
        while ((p=strchr(p,'/'))) {
                *p = 0;
                if(do_lstat(fullpath,&st)!=0) {
                        do_mkdir(fullpath,0777 & ~orig_umask);
                        if(p>q) {
                                if(do_lstat(q,&st)!=0) {
                                        rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno));
                                } else {
                                        st2=&st;
                                        set_modtime(fullpath,st2->st_mtime);
                                        if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) {
                                                rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno));
                                        };
                                        if(do_chmod(fullpath,st2->st_mode)!=0) {
                                                rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno));
                                        };
                                };
                        }
                };
                *p = '/';
                p++;
        }
        return 0;
}
Example #2
0
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
	      int report)
{
	int updated = 0;
	STRUCT_STAT st2;
	int change_uid, change_gid;
	extern int am_daemon;

	if (dry_run) return 0;

	if (!st) {
		if (link_stat(fname,&st2) != 0) {
			rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
			return 0;
		}
		st = &st2;
	}

	if (preserve_times && !S_ISLNK(st->st_mode) &&
	    st->st_mtime != file->modtime) {
		/* don't complain about not setting times on directories
		   because some filesystems can't do it */
		if (set_modtime(fname,file->modtime) != 0 &&
		    !S_ISDIR(st->st_mode)) {
			rprintf(FERROR,"failed to set times on %s : %s\n",
				fname,strerror(errno));
			return 0;
		} else {
			updated = 1;
		}
	}

	change_uid = am_root && preserve_uid && st->st_uid != file->uid;
	change_gid = !am_daemon && preserve_gid && file->gid != (gid_t) -1 && \
				st->st_gid != file->gid;
	if (change_gid && !am_root) {
		/* enforce bsd-style group semantics: non-root can only
		    change to groups that the user is a member of */
		change_gid = is_in_group(file->gid);
	}
	if (change_uid || change_gid) {
		if (do_lchown(fname,
			      change_uid?file->uid:st->st_uid,
			      change_gid?file->gid:st->st_gid) != 0) {
			/* shouldn't have attempted to change uid or gid
			     unless have the privilege */
			rprintf(FERROR,"chown %s : %s\n", fname,strerror(errno));
			return 0;
		}
		updated = 1;
	}

#ifdef HAVE_CHMOD
	if (!S_ISLNK(st->st_mode)) {
		int file_mode;
		if (preserve_perms)
			file_mode = file->mode;
		else
			file_mode = file->mode & ACCESSPERMS;
		if (st->st_mode != file->mode) {
			updated = 1;
			if (do_chmod(fname,file_mode) != 0) {
				rprintf(FERROR,"failed to set permissions on %s : %s\n",
					fname,strerror(errno));
				return 0;
			}
		}
	}
#endif
    
	if (verbose > 1 && report) {
		if (updated)
			rprintf(FINFO,"%s\n",fname);
		else
			rprintf(FINFO,"%s is uptodate\n",fname);
	}
	return updated;
}
Example #3
0
/****************************************************************************
Create a directory given an absolute path, perms based upon another directory
path
****************************************************************************/
static int make_bak_dir(char *fullpath)
{
	STRUCT_STAT st;
	char *rel = fullpath + backup_dir_len;
	char *end = rel + strlen(rel);
	char *p = end;

	while (strncmp(fullpath, "./", 2) == 0)
		fullpath += 2;

	/* Try to find an existing dir, starting from the deepest dir. */
	while (1) {
		if (--p == fullpath) {
			p += strlen(p);
			goto failure;
		}
		if (*p == '/') {
			*p = '\0';
			if (mkdir_defmode(fullpath) == 0)
				break;
			if (errno != ENOENT) {
				rsyserr(FERROR, errno,
					"make_bak_dir mkdir %s failed",
					full_fname(fullpath));
				goto failure;
			}
		}
	}

	/* Make all the dirs that we didn't find on the way here. */
	while (1) {
		if (p >= rel) {
			/* Try to transfer the directory settings of the
			 * actual dir that the files are coming from. */
			if (do_stat(rel, &st) < 0) {
				rsyserr(FERROR, errno,
					"make_bak_dir stat %s failed",
					full_fname(rel));
			} else {
				do_lchown(fullpath, st.st_uid, st.st_gid);
#ifdef HAVE_CHMOD
				do_chmod(fullpath, st.st_mode);
#endif
			}
		}
		*p = '/';
		p += strlen(p);
		if (p == end)
			break;
		if (mkdir_defmode(fullpath) < 0) {
			rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
				full_fname(fullpath));
			goto failure;
		}
	}
	return 0;

  failure:
	while (p != end) {
		*p = '/';
		p += strlen(p);
	}
	return -1;
}