예제 #1
0
파일: host_ms_task.c 프로젝트: tslabs/avr
//! @brief This function manages the HOST mass storage application
//!
void host_ms_task(void)
{
   if( Is_host_ready() )   
   {
      // Here, Enumeration successfull, device is operationnal
      if(Is_new_device_connection_event())
      {
         // Update MS driver in case of
         if( host_mem_install() )
         {
#if (HOST_UPGRADE_MODE==ENABLE)
            b_new_msc_connected = TRUE;
#endif
            Led1_on();
         }
      }

#if (HOST_SYNC_MODE==ENABLE)  // Sync operating mode(if available)
      if( 0 != host_mem_get_lun() )
      {
         if(Is_joy_right())   // Sync device to host stream
         {
            Led0_on();
            sync_on_going=1;
            copy_dir( (U8 code *)dir_usb_out_name, (U8 code *)dir_local_in_name, 1 );
            sync_on_going=0;
            Led3_off();
            Led0_off();
         }
         if(Is_joy_left())    // Sync host to device stream
         {
            Led0_on();
            sync_on_going=1;
            copy_dir( (U8 code *)dir_local_out_name, (U8 code *)dir_usb_in_name, 1 );
            sync_on_going=0;
            Led0_off();
            Led3_off();
         }
      }
#endif

#if (HOST_UPGRADE_MODE==ENABLE)
      if( b_new_msc_connected )
      {
         // A new MSC is connected then start upgrade routine
         b_new_msc_connected = FALSE;
         firm_upgrade_run();
      }
#endif
   }

   // Device disconnection...
   if( Is_device_disconnection_event() )
   {
      // Update MS driver in case of
      host_mem_uninstall();
      Led1_off();
   }
}
예제 #2
0
파일: copy.c 프로젝트: azuwis/xreader
extern dword copy_dir(const char *src, const char *dest, t_copy_cb cb,
					  t_copy_overwritecb ocb, void *data)
{
	int dl = xrIoDopen(src);
	dword result = 0;
	SceIoDirent sid;

	if (dl < 0) {
		if (cb != NULL)
			cb(src, dest, false, data);
		return 0;
	}

	xrIoMkdir(dest, 0777);
	memset(&sid, 0, sizeof(SceIoDirent));

	while (xrIoDread(dl, &sid)) {
		char copysrc[260], copydest[260];

		if (sid.d_name[0] == '.')
			continue;

		SPRINTF_S(copysrc, "%s/%s", src, sid.d_name);
		SPRINTF_S(copydest, "%s/%s", dest, sid.d_name);
		if (FIO_S_ISDIR(sid.d_stat.st_mode)) {
			result += copy_dir(copysrc, copydest, cb, ocb, data);
			continue;
		}
		if (copy_file(copysrc, copydest, cb, ocb, data))
			++result;
		memset(&sid, 0, sizeof(SceIoDirent));
	}
	xrIoDclose(dl);
	return result;
}
예제 #3
0
파일: file.cpp 프로젝트: Bodyfarm/vidalia
/** Recursively copy the contents of one directory to another. The
 * destination must already exist. Returns true on success, and false
 * otherwise. */
bool
copy_dir(const QString &source, const QString &dest)
{
  /* Source and destination as QDir's */
  QDir src(source);
  QDir dst(dest);

  /* Get contents of the directory */
  QFileInfoList contents = src.entryInfoList(QDir::Files | QDir::Dirs
                                               | QDir::NoDotAndDotDot);

  /* Copy each entry in src to dst */
  foreach (QFileInfo fileInfo, contents) {
    /* Get absolute path of source and destination */
    QString fileName = fileInfo.fileName();
    QString srcFilePath = src.absoluteFilePath(fileName);
    QString dstFilePath = dst.absoluteFilePath(fileName);

    if (fileInfo.isDir()) {
      /* This is a directory, make it and recurse */
      if (!dst.mkdir(fileName))
        return false;
      if (!copy_dir(srcFilePath, dstFilePath))
        return false;
    } else if (fileInfo.isFile()) {
      /* This is a file, copy it */
      if (!QFile::copy(srcFilePath, dstFilePath))
        return false;
    }
    /* Ignore special files (e.g. symlinks, devices) */

  }
예제 #4
0
static bool copy_entry(const char *source,
                       const char *destination,
                       uid_t uid,
                       gid_t gid) {
  struct stat sb;
  if (lstat(source, &sb) != 0)
    return false;

  struct timeval tv[2];
  tv[0].tv_sec = sb.st_atime;
  tv[0].tv_usec = 0;
  tv[1].tv_sec = sb.st_mtime;
  tv[1].tv_usec = 0;

  if (S_ISDIR(sb.st_mode)) {
    if (!copy_dir(source, destination, uid, gid, &sb))
      return false;
  } else if (S_ISLNK(sb.st_mode)) {
    if (!copy_symlink(source, destination, uid, gid, &sb))
      return false;
  } else if (S_ISREG(sb.st_mode)) {
    if (!copy_file(source, destination, uid, gid, &sb))
      return false;
  } else {
    if (!copy_special(source, destination, uid, gid, &sb))
      return false;
  }

  if (lutimes(destination, tv) != 0)
    return false;

  return true;
}
예제 #5
0
extern u32 move_dir(const char *src, const char *dest, t_copy_cb cb, t_copy_overwritecb ocb, void *data)
{
	u32 result = copy_dir(src, dest, cb, ocb, data);

	if (result > 0)
		utils_del_dir(src);
	return result;
}
예제 #6
0
파일: adcp.c 프로젝트: gongfuPanada/xyj2006
int copy_dir(string src, string dst, int dir_existed)
{
        mixed *file;
        int count;
        int i;
/*
        if (! is_root(previous_object()))
                return 0;
*/
        count = 0;
        if (src[strlen(src) - 1] != '/') src += "/";
        if (dst[strlen(dst) - 1] != '/') dst += "/";

        // assure dst existed
        if (! dir_existed) assure_file(dst);

        file = get_dir(src, -1);
        if (! sizeof(file))
                return count;

        write (HIC "复制目录(" + src + ") -- > (" + dst + ")。\n" NOR);
        i = sizeof(file);
        while (i--) {
                reset_eval_cost();
                if (file[i][1] != -2) {
                       if ( file_size(dst) == -1 ) {
                               mkdir(dst);
                               write("创建目录" + dst + "成功。\n");
                               }
                       if (cp(src + file[i][0], dst + file[i][0])) {
                                write(src + file[i][0] + "  -->  ");
                                write(dst + file[i][0] + "\n");
                                count++; 
                                }
                       }
               }

        i = sizeof(file);
        while (i--)
        {
                reset_eval_cost();
                if (file[i][1] == -2)
                {
                        mkdir(dst + file[i][0]);
                        count += copy_dir(src + file[i][0],
                                          dst + file[i][0],
                                          DIR_EXISTED);
                }
        }
        return count;
}
예제 #7
0
void copy_dir (const char * source , const char * dest ) {
	
	DIR * dirp ;
	struct dirent * dir_struct ;
	char 	path_dest_temp[PATH_MAX_LEN] = {0} ;
	char 	* temp_path ;
	int 	dest_length = strlen(dest) ;
	int 	is_dir_ret = 0 ;

	create_dir (source , dest) ;
	strcpy (path_dest_temp , dest) ;
	if (NULL ==  (dirp = opendir (source) ) ){
		perror ("opendir error ") ;
		exit (1) ;
	}
	chdir (source) ; 

	temp_path = get_current_dir_name () ;
	printf ("current path is %s\n",temp_path ) ;
	while( NULL != (dir_struct = readdir (dirp ) ) ) {
		//  文件名还是自己造吧
		is_dir_ret = is_directory (dir_struct->d_name )  ;
		// 目录文件
		if ( ISDIR == is_dir_ret ) {
			if ( !strcmp (dir_struct->d_name,".") ){
				continue ;
			} else if (!strcmp (dir_struct->d_name , "..") ) {
				continue ;
			}
			printf ("copy a directory \n") ;
			strcpy ( path_dest_temp + dest_length , dir_struct->d_name) ;
			strcat (path_dest_temp , "/") ;
			copy_dir (dir_struct->d_name , path_dest_temp ) ;
			chdir ("..") ;
		} else if ( EXIST == is_dir_ret ) {
		// 普通文件
			printf ("target is a normal file , and it exist ! we will creat a dir have the same name !\n") ;
			strcpy ( path_dest_temp + dest_length , dir_struct->d_name) ;
			copy (dir_struct->d_name , path_dest_temp ) ; 
		} else {
		// 特殊文件
			printf ("target is special file  ! we will create it .\n") ;
			strcpy ( path_dest_temp + dest_length , dir_struct->d_name) ;
			copy (dir_struct->d_name , path_dest_temp ) ; 
		}
	}

	free (temp_path) ;
}
예제 #8
0
/// 这里应该做 错误检查 , 检查相对应模式下的错误情况 比如在copy 文件时  , source 不能是目录 , copy 目录时 , source 不能是文件等 必须做特殊处理
int copy_file (struct mode *oper_mode , int argc , char* argv[]) {

	// 保存 argv 中的 dest
	char 	path_buf[PATH_MAX_LEN] ;
	char 	source_path[PATH_MAX_LEN] ;
// 这里 对于递归 , 接口写好! , directory , directory 参数 , 这样的话, 就可以调, target的话,
	bzero (path_buf , PATH_MAX_LEN) ;
	strcpy(source_path , argv[argc-2]) ;
	if( 1 == oper_mode->directory ) {
		printf ("copy directory!\n ") ;  	// source是目录
		get_full_path (argv[argc-1] , path_buf) ;	
		// 判断用户输入的是否符合自己规定
		if ( '/' != path_buf[strlen(path_buf)-1] ){
			strcat (path_buf , "/") ;
		}
		if ( '/' != source_path[strlen(source_path)-1] ) {
			strcat (source_path , "/" ) ;
		}
		cat_source_to_dest (source_path , path_buf) ;
		copy_dir (source_path,path_buf) ;
		return TRUE ;	
	} else {
		// 全都处理成绝对路径 
		get_full_path (argv[argc-1] ,path_buf ) ;		
		if (ISDIR == is_directory(path_buf )) {
			printf ("target is a direcroty !\n") ;
			// 首先处理名字
			// 我需要st_mode 值 和 st_uid , st_gid值 然后去调函数设置	
			// 生成最终的文件名
			if ( '/' != path_buf[strlen(path_buf)-1] ){
				strcat (path_buf , "/") ;
			}
			cat_source_to_dest (argv[argc-2] , path_buf) ;
			path_buf[strlen(path_buf)-1] = 0 ;
			copy (argv[argc-2] , path_buf ) ;
		}else {
			// 判断文件是否存在
			if (!access (path_buf , F_OK)) {
			// 存在
				printf ("file now is exist ! overwrite it now !\n") ;
			}
			copy (argv[argc-2] , path_buf ) ;
			return TRUE ;
		}	
	}	
	return TRUE ;
}
예제 #9
0
int copy_custom_files(const char* path_dist, const char* path_src)
{
    if (ensure_path_mounted(path_dist) != 0) {
        LOGE("Can't mount %s\n", path_dist);
        return INSTALL_ERROR;
    }

    if (ensure_path_mounted(path_src) != 0) {
        LOGE("Can't mount %s\n", path_src);
        return INSTALL_ERROR;
    }

    if (copy_dir(path_dist, path_src) < 0)
        return INSTALL_ERROR;
    else
        return INSTALL_SUCCESS;

   
}
예제 #10
0
파일: cp.c 프로젝트: maxymania/muserland
int main(int argc,const string_t* argv){
	int status,i;
	struct stat statbuf;
	if(argc<3)
		goto printhowto;
	if(stat(argv[argc-1],&statbuf)){
		/*
		 * The destination file/dir does not exist.
		 */
		if(argc>3)
			goto printhowto;
	}else{
		/*
		 * The destination file/dir does exist.
		 */
		if(S_ISDIR(statbuf.st_mode))
			/*
			 * The destination is a directory.
			 */
			goto copydir;
		else /*if(!(S_ISREG(statbuf.st_mode)))*/
			/*
			 * If the destination is not a directory, fail.
			 */
			goto printhowto;
	}
	return copy_object(argv[1],argv[2]);
copydir:
	status = 0;
	for(i=1;i<argc-1;++i)
		if(copy_dir(argv[i],argv[argc-1]))
			status = 1;
	return status;
printhowto:
	fprintf(stderr,"Usage: cp from-file-or-dir dest-name; or cp file1 ... fileN dest-dir\n");
	return 1;
}
예제 #11
0
파일: lacy.c 프로젝트: teneighty/lacy
void
setup()
{
    str_init(&conf.shell);
    str_init(&conf.output_dir);
    str_init(&conf.static_dir);

    str_append_str(&conf.shell, "/bin/sh");
    str_append_str(&conf.output_dir, "_output");
    str_append_str(&conf.static_dir, "_static");

    if (0 != mkdir(conf.output_dir.s, 0777)) {
        if (EEXIST != errno) {
            fatal("Unable to mkdir %s\n", conf.output_dir.s);
        }
    }

    if (file_exists(conf.output_dir.s)) {
        if (0 != copy_dir(conf.static_dir.s, conf.output_dir.s)) {
            warn("Unable to copy %s to %s\n", 
                    conf.static_dir.s, conf.output_dir.s);
        }
    }
}
/*
 * copy_dir()
 *
 *	Copies either a directory or a single file within a directory.	If the
 *	source argument names a directory, we recursively copy that directory,
 *	otherwise we copy a single file.
 */
static int
copy_dir(const char *src, const char *dst, bool force)
{
	DIR		   *srcdir;
	struct dirent *de = NULL;
	struct stat fst;

	if (src == NULL || dst == NULL)
		return -1;

	/*
	 * Try to open the source directory - if it turns out not to be a
	 * directory, assume that it's a file and copy that instead.
	 */
	if ((srcdir = opendir(src)) == NULL)
	{
		if (errno == ENOTDIR)
			return copy_file(src, dst, true);
		return -1;
	}

	if (mkdir(dst, S_IRWXU) != 0)
	{
		/*
		 * ignore directory already exist error
		 */
		if (errno != EEXIST)
			return -1;
	}

	while ((de = readdir(srcdir)) != NULL)
	{
		char		src_file[MAXPGPATH];
		char		dest_file[MAXPGPATH];

		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
			continue;

		memset(src_file, 0, sizeof(src_file));
		memset(dest_file, 0, sizeof(dest_file));

		snprintf(src_file, sizeof(src_file), "%s/%s", src, de->d_name);
		snprintf(dest_file, sizeof(dest_file), "%s/%s", dst, de->d_name);

		if (stat(src_file, &fst) < 0)
		{
			if (srcdir != NULL)
			{
				closedir(srcdir);
				srcdir = NULL;
			}

			return -1;
		}

		if (fst.st_mode & S_IFDIR)
		{
			/* recurse to handle subdirectories */
			if (force)
				copy_dir(src_file, dest_file, true);
		}
		else if (fst.st_mode & S_IFREG)
		{
			if ((copy_file(src_file, dest_file, 1)) == -1)
			{
				if (srcdir != NULL)
				{
					closedir(srcdir);
					srcdir = NULL;
				}
				return -1;
			}
		}
	}

	if (srcdir != NULL)
	{
		closedir(srcdir);
		srcdir = NULL;
	}
	return 1;
}
예제 #13
0
int copy_dir(const char* path_dist, const char* path_src)
{
    int ret = 0;
    DIR* d;
    struct dirent* de;
    d = opendir(path_src);
    if (d == NULL) {
        LOGE("error opening %s: %s\n", path_src, strerror(errno));
        return -1;
    }

    if (mkdir(path_dist, 0666) != 0) {
        if (errno != EEXIST) {
            LOGE("Can't mkdir %s (%s)\n", path_dist, strerror(errno));
            return -1;
        }
    }

    //ui_print("copy %s  to %s \n", path_src, path_dist);

    while ((de = readdir(d)) != NULL) {
        int name_len = strlen(de->d_name);

        if (de->d_type == DT_DIR) {
            // skip "." and ".." entries
            if (name_len == 1 && de->d_name[0] == '.') continue;
            if (name_len == 2 && de->d_name[0] == '.' &&
                de->d_name[1] == '.') continue;

           
            char *path_dist_sub = dump_full_path(path_dist, de->d_name);
            char *path_src_sub = dump_full_path(path_src, de->d_name);
            if (path_dist_sub && path_src_sub) {
                if ( copy_dir(path_dist_sub, path_src_sub) ) {
                    ret = -1;
                }
            }
           
            if (path_dist_sub)
                free(path_dist_sub);
            if (path_src_sub)
                free(path_src_sub);
        } else if (de->d_type == DT_REG ) {
       
            char *file_dist = dump_full_path(path_dist, de->d_name);
            char *file_src = dump_full_path(path_src, de->d_name);
            if (file_dist && file_src) {
                //ui_print("copy %s  to %s \n", file_src, file_dist);
                if (copy_file(file_dist, file_src) < 0) {
                    ret = -1;
                    LOGE("Can't copy %s  to %s \n", file_src, file_dist);
                }
            }

            if (file_dist)
                free(file_dist);
            if (file_src)
                free(file_src);
        }
    }
    closedir(d);

    return ret;
}
예제 #14
0
파일: copydir.c 프로젝트: bfeeny/shadow
/*
 * copy_entry - copy the entry of a directory
 *
 *	Copy the entry src to dst.
 *	Depending on the type of entry, this function will forward the
 *	request to copy_dir(), copy_symlink(), copy_hardlink(),
 *	copy_special(), or copy_file().
 *
 *	The access and modification time will not be modified.
 *
 *	The permissions will be set to new_uid/new_gid.
 *
 *	If new_uid (resp. new_gid) is equal to -1, the user (resp. group) will
 *	not be modified.
 *
 *	Only the files owned (resp. group-owned) by old_uid (resp.
 *	old_gid) will be modified, unless old_uid (resp. old_gid) is set
 *	to -1.
 */
static int copy_entry (const char *src, const char *dst,
                       bool reset_selinux,
                       uid_t old_uid, uid_t new_uid,
                       gid_t old_gid, gid_t new_gid)
{
    int err = 0;
    struct stat sb;
    struct link_name *lp;
    struct timeval mt[2];

    if (LSTAT (src, &sb) == -1) {
        /* If we cannot stat the file, do not care. */
    } else {
#ifdef HAVE_STRUCT_STAT_ST_ATIM
        mt[0].tv_sec  = sb.st_atim.tv_sec;
        mt[0].tv_usec = sb.st_atim.tv_nsec / 1000;
#else				/* !HAVE_STRUCT_STAT_ST_ATIM */
        mt[0].tv_sec  = sb.st_atime;
# ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC
        mt[0].tv_usec = sb.st_atimensec / 1000;
# else				/* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
        mt[0].tv_usec = 0;
# endif				/* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
#endif				/* !HAVE_STRUCT_STAT_ST_ATIM */

#ifdef HAVE_STRUCT_STAT_ST_MTIM
        mt[1].tv_sec  = sb.st_mtim.tv_sec;
        mt[1].tv_usec = sb.st_mtim.tv_nsec / 1000;
#else				/* !HAVE_STRUCT_STAT_ST_MTIM */
        mt[1].tv_sec  = sb.st_mtime;
# ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
        mt[1].tv_usec = sb.st_mtimensec / 1000;
# else				/* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
        mt[1].tv_usec = 0;
# endif				/* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
#endif				/* !HAVE_STRUCT_STAT_ST_MTIM */

        if (S_ISDIR (sb.st_mode)) {
            err = copy_dir (src, dst, reset_selinux, &sb, mt,
                            old_uid, new_uid, old_gid, new_gid);
        }

#ifdef	S_IFLNK
        /*
         * Copy any symbolic links
         */

        else if (S_ISLNK (sb.st_mode)) {
            err = copy_symlink (src, dst, reset_selinux, &sb, mt,
                                old_uid, new_uid, old_gid, new_gid);
        }
#endif				/* S_IFLNK */

        /*
         * See if this is a previously copied link
         */

        else if ((lp = check_link (src, &sb)) != NULL) {
            err = copy_hardlink (dst, reset_selinux, lp);
        }

        /*
         * Deal with FIFOs and special files.  The user really
         * shouldn't have any of these, but it seems like it
         * would be nice to copy everything ...
         */

        else if (!S_ISREG (sb.st_mode)) {
            err = copy_special (src, dst, reset_selinux, &sb, mt,
                                old_uid, new_uid, old_gid, new_gid);
        }

        /*
         * Create the new file and copy the contents.  The new
         * file will be owned by the provided UID and GID values.
         */

        else {
            err = copy_file (src, dst, reset_selinux, &sb, mt,
                             old_uid, new_uid, old_gid, new_gid);
        }
    }

    return err;
}
예제 #15
0
파일: mkhome.c 프로젝트: Distrotech/proftpd
/* srcdir is to be considered a "skeleton" directory, in the manner of
 * /etc/skel, and destdir is a user's newly created home directory that needs
 * to be populated with the files in srcdir.
 */
static int copy_dir(pool *p, const char *src_dir, const char *dst_dir,
    uid_t uid, gid_t gid) {
  DIR *dh = NULL;
  struct dirent *dent = NULL;

  dh = opendir(src_dir);
  if (dh == NULL) {
    pr_log_pri(PR_LOG_WARNING, "CreateHome: error copying '%s' skel files: %s",
      src_dir, strerror(errno));
    return -1;
  }

  while ((dent = readdir(dh)) != NULL) {
    struct stat st;
    char *src_path, *dst_path;

    pr_signals_handle();

    /* Skip "." and ".." */
    if (strncmp(dent->d_name, ".", 2) == 0 ||
        strncmp(dent->d_name, "..", 3) == 0) {
      continue;
    }

    src_path = pdircat(p, src_dir, dent->d_name, NULL);
    dst_path = pdircat(p, dst_dir, dent->d_name, NULL);

    if (pr_fsio_lstat(src_path, &st) < 0) {
      pr_log_debug(DEBUG3, "CreateHome: unable to stat '%s' (%s), skipping",
        src_path, strerror(errno));
      continue;
    }

    /* Is this path to a directory? */
    if (S_ISDIR(st.st_mode)) {
      create_dir(dst_path, uid, gid, st.st_mode);
      copy_dir(p, src_path, dst_path, uid, gid);
      continue;

    /* Is this path to a regular file? */
    } else if (S_ISREG(st.st_mode)) {
      mode_t dst_mode = st.st_mode;

      /* Make sure to prevent S{U,G}ID permissions on target files. */

      if (dst_mode & S_ISUID)
        dst_mode &= ~S_ISUID;

      if (dst_mode & S_ISGID)
        dst_mode &= ~S_ISGID;

      (void) pr_fs_copy_file(src_path, dst_path);

      /* Make sure the destination file has the proper ownership and mode. */
      if (pr_fsio_chown(dst_path, uid, gid) < 0) {
        pr_log_pri(PR_LOG_WARNING, "CreateHome: error chown'ing '%s' "
          "to %u/%u: %s", dst_path, (unsigned int) uid, (unsigned int) gid,
          strerror(errno));
      }

      if (pr_fsio_chmod(dst_path, dst_mode) < 0) {
        pr_log_pri(PR_LOG_WARNING, "CreateHome: error chmod'ing '%s' to "
          "%04o: %s", dst_path, (unsigned int) dst_mode, strerror(errno));
      }

      continue;

    /* Is this path a symlink? */
    } else if (S_ISLNK(st.st_mode)) {

      copy_symlink(p, src_dir, src_path, dst_dir, dst_path, uid, gid);
      continue;

    /* All other file types are skipped */
    } else {
      pr_log_debug(DEBUG3, "CreateHome: skipping skel file '%s'", src_path);
      continue;
    }
  }

  closedir(dh);
  return 0;
}
예제 #16
0
파일: mkhome.c 프로젝트: proftpd/proftpd
/* Check for a CreateHome directive, and act on it if present.  If not, do
 * nothing.
 */
int create_home(pool *p, const char *home, const char *user, uid_t uid,
    gid_t gid) {
  int res;
  unsigned long flags = 0;
  config_rec *c;
  mode_t dir_mode, dst_mode;
  uid_t dir_uid, dst_uid;
  gid_t dir_gid, dst_gid, home_gid;

  c = find_config(main_server->conf, CONF_PARAM, "CreateHome", FALSE);
  if (c == NULL ||
      (c && *((unsigned char *) c->argv[0]) == FALSE)) {
    return 0;
  }

  /* Create the configured path. */

  dir_uid = *((uid_t *) c->argv[4]);
  dir_gid = *((gid_t *) c->argv[5]);
  dir_mode = *((mode_t *) c->argv[2]);
  home_gid = *((gid_t *) c->argv[6]);
  flags = *((unsigned long *) c->argv[7]);

  dst_uid = uid;
  dst_gid = (home_gid == (gid_t) -1) ? gid : home_gid;

  dst_mode = *((mode_t *) c->argv[1]);

  if (!(flags & PR_MKHOME_FL_USE_USER_PRIVS)) {
    PRIVS_ROOT
  }

  pr_event_generate("core.creating-home", user);

  res = create_path(p, home, user, dir_uid, dir_gid, dir_mode,
    dst_uid, dst_gid, dst_mode);

  if (res < 0 &&
      errno != EEXIST) {
    int xerrno = errno;

    PRIVS_RELINQUISH

    errno = xerrno;
    return -1;
  }

  if (res == 0 &&
      c->argv[3]) {
    char *skel_dir = c->argv[3];

    /* Populate the home directory with files from the configured
     * skeleton (a la /etc/skel) directory.
     */

    pr_trace_msg(trace_channel, 9, "copying skel files from '%s' into '%s'",
      skel_dir, home);
    pr_log_debug(DEBUG4, "CreateHome: copying skel files from '%s' into '%s'",
      skel_dir, home);

    pr_event_generate("core.copying-skel", user);

    if (copy_dir(p, skel_dir, home, uid, gid) < 0) {
      pr_log_debug(DEBUG4, "CreateHome: error copying skel files");

    } else {
      pr_event_generate("core.copied-skel", user);
    }
  }

  if (res == 0) {
    pr_event_generate("core.created-home", user);
  }

  PRIVS_RELINQUISH
  return 0;
}
예제 #17
0
copy_dir ()       /* source und dest sind global; bei Fehler: return (1) */
{
int source_len, dest_len, fd_source, fd_dest, error;
char dta[44];
long old_dta, fail, size, count;
   error=0;
   source_len=strlen(source);
   dest_len=strlen(dest);
   old_dta=Fgetdta();
   Fsetdta(dta);
   strcat(source,"\\*.*");
   fail=Fsfirst(source,16);
   source[source_len]=0;
   while (!fail)
   {  strcat(source,"\\");
      strcat(source,dta+30);
      strcat(dest,"\\");
      strcat(dest,dta+30);
      if (dta[21]==16)         /* Directory */
      {  if (strcmp(dta+30,".")&&strcmp(dta+30,".."))
            if (Dcreate(dest))
            {  printf("Ordner %s l„žt sich nicht anlegen.\n",dest);
               error=1;
            }
            else
               error|=copy_dir(source,dest);
      }
      else                     /* File */
      {  printf("%s  nach  %s\n",source,dest);
         if ((fd_source=Fopen(source,0))<0)
         {  printf("Datei %s l„žt sich nicht ”ffnen.\n",source);
            error=1;
         }
         else
            if ((fd_dest=Fcreate(dest,dta[21]&~1))<0)
            {  printf("Datei %s l„žt sich nicht einrichten.\n",dest);
               error=1;
            }
            else
            {  size=*(long*)(dta+26);
               while (size)
               {  count=(size<buf_size)?size:buf_size;
                  size-=count;
                  if (Fread(fd_source,count,buffer)!=count)
                  {  printf("Fehler beim Lesen von %s .\n",source);
                     error=1;
                     break;
                  }
                  if (Fwrite(fd_dest,count,buffer)!=count)
                  {  printf("Fehler beim Schreiben von %s .\n",dest);
                     error=1;
                     break;
                  }
               }
               Fclose(fd_source);
               Fclose(fd_dest);
               fd_dest=Fopen(dest,1);
               Fdatime(fd_dest,dta+22,1);
               Fclose(fd_dest);
            }
      }
      source[source_len]=0;
      dest[dest_len]=0;
      fail=Fsnext();
   }
   if (fail!=-49l)
   {  printf("Ordner %s nicht gefunden.\n",source);
      error=1;
   }
   Fsetdta(old_dta);
   return (error);
}
예제 #18
0
파일: cp_cmd.c 프로젝트: jgottula/automaton
int cp_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) {
#ifdef FF_UNICODE_SUPPORT
	const wchar_t			*szpSource, *szpDestination, *szpWildCard;
#else
	const char			*szpSource, *szpDestination, *szpWildCard;
#endif
	char				szsrcPath[FF_MAX_PATH], szdestPath[FF_MAX_PATH];
	FF_DIRENT			findData;
	
	FFT_GETOPT_CONTEXT	optionContext;	// CommandLine processing
	FF_T_BOOL			bRecursive = FF_FALSE, bVerbose = FF_FALSE;	// Option Flags.
	int 				option;

	memset(&optionContext, 0, sizeof(FFT_GETOPT_CONTEXT));			// Initialise the option context to zero.

	option = FFTerm_getopt(argc, (const char **) argv, "rRvx", &optionContext);		// Get the command line option charachters.

	while(option != EOF) {											// Process Commandline options
		switch(option) {
			case 'r':
			case 'R':
				bRecursive = FF_TRUE;								// Set recursive flag if -r or -R appears on the commandline.
				break;

			case 'v':
				bVerbose = FF_TRUE;									// Set verbose flag if -v appears on the commandline.
				break;

			case 'x':
				bExternal = FF_TRUE;
				break;

			default:
				break;
		}

		option = FFTerm_getopt(argc, (const char **) argv, "rRvx", &optionContext);	// Get the next option.
	}

	szpSource 		= FFTerm_getarg(argc, (const char **) argv, 0, &optionContext);	// The remaining options or non optional arguments.
	szpDestination 	= FFTerm_getarg(argc, (const char **) argv, 1, &optionContext);	// getarg() retrieves them intelligently.
	
	if(!szpSource) {
		printf("%s: No source file argument.\n", argv[0]);			// No source file provided.
		return 0;
	}

	if(!szpDestination) {
		printf("%s: No destination file argument.\n", argv[0]);		// No destination provided.
		return 0;
	}

	ProcessPath(szsrcPath, szpSource, pEnv);						// Process the paths into absolute paths.
	ProcessPath(szdestPath, szpDestination, pEnv);

	szpWildCard = GetWildcard(szpSource);							// Get the last token of the source path. (This may include a wildCard).

	if(strchr(szpWildCard, '*')) {									// If the 'WildCard' contains a * then its a wild card, otherwise its a file or directory.
		// WildCard Copying!
		//copy_wild();
		return 0;
	}

	if(FF_FindFirst(pEnv->pIoman, &findData, szsrcPath)) {			// Get the dirent for the file or directory, to detect if its a directory.
		// Not found!
		printf("%s: %s: no such file or directory.\n", argv[0], szpSource);
		return 0;
	}

	if(!strcmp(findData.FileName, szpWildCard) && (findData.Attrib & FF_FAT_ATTR_DIR)) {
		if(!bRecursive) {											// Its a dir!
			printf("%s: omitting directory '%s'\n", argv[0], szsrcPath);
			return 0;
		}
		copy_dir(szsrcPath, szdestPath, bRecursive, bVerbose, pEnv);// Start the copying!
		return 0;
	}

	copy_file(szsrcPath, szdestPath, bVerbose, pEnv);				// Final option, its simply a file to file copy
	
	return 0;
}
예제 #19
0
파일: cp_cmd.c 프로젝트: jgottula/automaton
static int copy_dir(const char *srcPath, const char *destPath, FF_T_BOOL bRecursive, FF_T_BOOL bVerbose, FF_ENVIRONMENT *pEnv) {
	FF_DIRENT	findData;
	FF_ERROR	RetVal;
	FF_T_INT8	szsrcFile[FF_MAX_PATH], szdestFile[FF_MAX_PATH];

	//const char	*szpWildCard;
	int i;

	strcpy(szsrcFile, srcPath);
	strcpy(szdestFile, destPath);

	// Ensure the paths both end in a '/' charachter
	i = strlen(szsrcFile);
	if(szsrcFile[i - 1] != '\\' || szsrcFile[i - 1] != '/') {
		strcat(szsrcFile, "\\");
	}
	i = strlen(szdestFile);
	if(szdestFile[i - 1] != '\\' || szdestFile[i - 1] != '/') {
		strcat(szdestFile, "\\");
	}

	RetVal = FF_FindFirst(pEnv->pIoman, &findData, szsrcFile);

	if(RetVal) {
		printf("cp: %s: No such file or directory.\n", srcPath);
		return 0;
	}

	while(!RetVal) {
		AppendFilename(szsrcFile, findData.FileName);
		AppendFilename(szdestFile, findData.FileName);

		if(!strcmp(szsrcFile, szdestFile)) {
			printf("cp: Source and Destination files are identical: illegal operation.\n");
			return 0;
		}

		if((findData.Attrib & FF_FAT_ATTR_DIR)) {
			if(!(findData.FileName[0] == '.' && !findData.FileName[1]) && !(findData.FileName[0] == '.' && findData.FileName[1] == '.' && !findData.FileName[2])) {
				// Add the wild card onto the end!
				if(bRecursive) {
					strcat(szsrcFile, "\\");
					//szpWildCard = getWildcard(srcPath);
					//strcat(szsrcFile, szpWildCard);
					
					strcat(szdestFile, "\\");
					//szpWildCard = getWildcard(destPath);
					//strcat(szdestFile, szpWildCard);
					

					// Make the dir if it doesn't already exist!
					copy_dir(szsrcFile, szdestFile, bRecursive, bVerbose, pEnv);

					strcpy(szsrcFile, srcPath);		// Reset the path.
				}
			}
		} else {
			copy_file(szsrcFile, szdestFile, bVerbose, pEnv);
		}

		RetVal = FF_FindNext(pEnv->pIoman, &findData);
	}

	return 0;
}
예제 #20
0
파일: copy.c 프로젝트: brokendragon/PERDICE
static int
copy_internal (const char *src_path, const char *dst_path,
	       int new_dst,
	       dev_t device,
	       struct dir_list *ancestors,
	       const struct cp_options *x,
	       int command_line_arg,
	       int *copy_into_self,
	       int *rename_succeeded)
{
  struct stat src_sb;
  struct stat dst_sb;
  mode_t src_mode;
  mode_t src_type;
  char *earlier_file = NULL;
  char *dst_backup = NULL;
  int backup_succeeded = 0;
  int delayed_fail;
  int copied_as_regular = 0;
  int ran_chown = 0;
  int preserve_metadata;

  if (x->move_mode && rename_succeeded)
    *rename_succeeded = 0;

  *copy_into_self = 0;
  if ((*(x->xstat)) (src_path, &src_sb))
    {
      error (0, errno, _("cannot stat %s"), quote (src_path));
      return 1;
    }

  src_type = src_sb.st_mode;

  src_mode = src_sb.st_mode;

  if (S_ISDIR (src_type) && !x->recursive)
    {
      error (0, 0, _("omitting directory %s"), quote (src_path));
      return 1;
    }

  /* Detect the case in which the same source file appears more than
     once on the command line and no backup option has been selected.
     If so, simply warn and don't copy it the second time.
     This check is enabled only if x->src_info is non-NULL.  */
  if (command_line_arg)
    {
      if ( ! S_ISDIR (src_sb.st_mode)
	   && x->backup_type == none
	   && seen_file (x->src_info, src_path, &src_sb))
	{
	  error (0, 0, _("warning: source file %s specified more than once"),
		 quote (src_path));
	  return 0;
	}

      record_file (x->src_info, src_path, &src_sb);
    }

  if (!new_dst)
    {
      if ((*(x->xstat)) (dst_path, &dst_sb))
	{
	  if (errno != ENOENT)
	    {
	      error (0, errno, _("cannot stat %s"), quote (dst_path));
	      return 1;
	    }
	  else
	    {
	      new_dst = 1;
	    }
	}
      else
	{
	  int return_now;
	  int ok = same_file_ok (src_path, &src_sb, dst_path, &dst_sb,
				 x, &return_now);
	  if (return_now)
	    return 0;

	  if (! ok)
	    {
	      error (0, 0, _("%s and %s are the same file"),
		     quote_n (0, src_path), quote_n (1, dst_path));
	      return 1;
	    }

	  if (!S_ISDIR (dst_sb.st_mode))
	    {
	      if (S_ISDIR (src_type))
		{
		  error (0, 0,
		     _("cannot overwrite non-directory %s with directory %s"),
			 quote_n (0, dst_path), quote_n (1, src_path));
		  return 1;
		}

	      /* Don't let the user destroy their data, even if they try hard:
		 This mv command must fail (likewise for cp):
		   rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
		 Otherwise, the contents of b/f would be lost.
		 In the case of `cp', b/f would be lost if the user simulated
		 a move using cp and rm.
		 Note that it works fine if you use --backup=numbered.  */
	      if (command_line_arg
		  && x->backup_type != numbered
		  && seen_file (x->dest_info, dst_path, &dst_sb))
		{
		  error (0, 0,
			 _("will not overwrite just-created %s with %s"),
			 quote_n (0, dst_path), quote_n (1, src_path));
		  return 1;
		}
	    }

	  if (!S_ISDIR (src_type))
	    {
	      if (S_ISDIR (dst_sb.st_mode))
		{
		  error (0, 0,
		       _("cannot overwrite directory %s with non-directory"),
			 quote (dst_path));
		  return 1;
		}

	      if (x->update && MTIME_CMP (src_sb, dst_sb) <= 0)
		{
		  /* We're using --update and the source file is older
		     than the destination file, so there is no need to
		     copy or move.  */
		  /* Pretend the rename succeeded, so the caller (mv)
		     doesn't end up removing the source file.  */
		  if (rename_succeeded)
		    *rename_succeeded = 1;
		  return 0;
		}
	    }

	  /* When there is an existing destination file, we may end up
	     returning early, and hence not copying/moving the file.
	     This may be due to an interactive `negative' reply to the
	     prompt about the existing file.  It may also be due to the
	     use of the --reply=no option.  */
	  if (!S_ISDIR (src_type))
	    {
	      /* cp and mv treat -i and -f differently.  */
	      if (x->move_mode)
		{
		  if ((x->interactive == I_ALWAYS_NO
		       && UNWRITABLE (dst_path, dst_sb.st_mode))
		      || ((x->interactive == I_ASK_USER
			   || (x->interactive == I_UNSPECIFIED
			       && x->stdin_tty
			       && UNWRITABLE (dst_path, dst_sb.st_mode)))
			  && (overwrite_prompt (dst_path, &dst_sb), 1)
			  && ! yesno ()))
		    {
		      /* Pretend the rename succeeded, so the caller (mv)
			 doesn't end up removing the source file.  */
		      if (rename_succeeded)
			*rename_succeeded = 1;
		      return 0;
		    }
		}
	      else
		{
		  if (x->interactive == I_ALWAYS_NO
		      || (x->interactive == I_ASK_USER
			  && (overwrite_prompt (dst_path, &dst_sb), 1)
			  && ! yesno ()))
		    {
		      return 0;
		    }
		}
	    }

	  if (x->move_mode)
	    {
	      /* In move_mode, DEST may not be an existing directory.  */
	      if (S_ISDIR (dst_sb.st_mode))
		{
		  error (0, 0, _("cannot overwrite directory %s"),
			 quote (dst_path));
		  return 1;
		}

	      /* Don't allow user to move a directory onto a non-directory.  */
	      if (S_ISDIR (src_sb.st_mode) && !S_ISDIR (dst_sb.st_mode))
		{
		  error (0, 0,
		       _("cannot move directory onto non-directory: %s -> %s"),
			 quote_n (0, src_path), quote_n (0, dst_path));
		  return 1;
		}
	    }

	  if (x->backup_type != none && !S_ISDIR (dst_sb.st_mode))
	    {
	      char *tmp_backup = find_backup_file_name (dst_path,
							x->backup_type);
	      if (tmp_backup == NULL)
		xalloc_die ();

	      /* Detect (and fail) when creating the backup file would
		 destroy the source file.  Before, running the commands
		 cd /tmp; rm -f a a~; : > a; echo A > a~; cp --b=simple a~ a
		 would leave two zero-length files: a and a~.  */
	      /* FIXME: but simply change e.g., the final a~ to `./a~'
		 and the source will still be destroyed.  */
	      if (STREQ (tmp_backup, src_path))
		{
		  const char *fmt;
		  fmt = (x->move_mode
		 ? _("backing up %s would destroy source;  %s not moved")
		 : _("backing up %s would destroy source;  %s not copied"));
		  error (0, 0, fmt,
			 quote_n (0, dst_path),
			 quote_n (1, src_path));
		  free (tmp_backup);
		  return 1;
		}

	      dst_backup = (char *) alloca (strlen (tmp_backup) + 1);
	      strcpy (dst_backup, tmp_backup);
	      free (tmp_backup);
	      if (rename (dst_path, dst_backup))
		{
		  if (errno != ENOENT)
		    {
		      error (0, errno, _("cannot backup %s"), quote (dst_path));
		      return 1;
		    }
		  else
		    {
		      dst_backup = NULL;
		    }
		}
	      else
		{
		  backup_succeeded = 1;
		}
	      new_dst = 1;
	    }
	  else if (! S_ISDIR (dst_sb.st_mode)
		   && (x->unlink_dest_before_opening
		       || (x->xstat == lstat
			   && ! S_ISREG (src_sb.st_mode))))
	    {
	      if (unlink (dst_path) && errno != ENOENT)
		{
		  error (0, errno, _("cannot remove %s"), quote (dst_path));
		  return 1;
		}
	      new_dst = 1;
	    }
	}
    }

  /* If the source is a directory, we don't always create the destination
     directory.  So --verbose should not announce anything until we're
     sure we'll create a directory. */
  if (x->verbose && !S_ISDIR (src_type))
    {
      printf ("%s -> %s", quote_n (0, src_path), quote_n (1, dst_path));
      if (backup_succeeded)
	printf (_(" (backup: %s)"), quote (dst_backup));
      putchar ('\n');
    }

  /* Associate the destination path with the source device and inode
     so that if we encounter a matching dev/ino pair in the source tree
     we can arrange to create a hard link between the corresponding names
     in the destination tree.

     Sometimes, when preserving links, we have to record dev/ino even
     though st_nlink == 1:
     - when using -H and processing a command line argument;
	that command line argument could be a symlink pointing to another
	command line argument.  With `cp -H --preserve=link', we hard-link
	those two destination files.
     - likewise for -L except that it applies to all files, not just
	command line arguments.

     Also record directory dev/ino when using --recursive.  We'll use that
     info to detect this problem: cp -R dir dir.  FIXME-maybe: ideally,
     directory info would be recorded in a separate hash table, since
     such entries are useful only while a single command line hierarchy
     is being copied -- so that separate table could be cleared between
     command line args.  Using the same hash table to preserve hard
     links means that it may not be cleared.  */

  if ((x->preserve_links
       && (1 < src_sb.st_nlink
	   || (command_line_arg
	       && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS)
	   || x->dereference == DEREF_ALWAYS))
      || (x->recursive && S_ISDIR (src_type)))
    {
      earlier_file = remember_copied (dst_path, src_sb.st_ino, src_sb.st_dev);
    }

  /* Did we copy this inode somewhere else (in this command line argument)
     and therefore this is a second hard link to the inode?  */

  if (earlier_file)
    {
      /* Avoid damaging the destination filesystem by refusing to preserve
	 hard-linked directories (which are found at least in Netapp snapshot
	 directories).  */
      if (S_ISDIR (src_type))
	{
	  /* If src_path and earlier_file refer to the same directory entry,
	     then warn about copying a directory into itself.  */
	  if (same_name (src_path, earlier_file))
	    {
	      error (0, 0, _("cannot copy a directory, %s, into itself, %s"),
		     quote_n (0, top_level_src_path),
		     quote_n (1, top_level_dst_path));
	      *copy_into_self = 1;
	    }
	  else
	    {
	      error (0, 0, _("will not create hard link %s to directory %s"),
		     quote_n (0, dst_path), quote_n (1, earlier_file));
	    }

	  goto un_backup;
	}

      {
	int link_failed;

	link_failed = link (earlier_file, dst_path);

	/* If the link failed because of an existing destination,
	   remove that file and then call link again.  */
	if (link_failed && errno == EEXIST)
	  {
	    if (unlink (dst_path))
	      {
		error (0, errno, _("cannot remove %s"), quote (dst_path));
		goto un_backup;
	      }
	    link_failed = link (earlier_file, dst_path);
	  }

	if (link_failed)
	  {
	    error (0, errno, _("cannot create hard link %s to %s"),
		   quote_n (0, dst_path), quote_n (1, earlier_file));
	    goto un_backup;
	  }

	return 0;
      }
    }

  if (x->move_mode)
    {
      if (rename (src_path, dst_path) == 0)
	{
	  if (x->verbose && S_ISDIR (src_type))
	    printf ("%s -> %s\n", quote_n (0, src_path), quote_n (1, dst_path));
	  if (rename_succeeded)
	    *rename_succeeded = 1;

	  if (command_line_arg)
	    {
	      /* Record destination dev/ino/filename, so that if we are asked
		 to overwrite that file again, we can detect it and fail.  */
	      /* It's fine to use the _source_ stat buffer (src_sb) to get the
	         _destination_ dev/ino, since the rename above can't have
		 changed those, and `mv' always uses lstat.
		 We could limit it further by operating
		 only on non-directories.  */
	      record_file (x->dest_info, dst_path, &src_sb);
	    }

	  return 0;
	}

      /* FIXME: someday, consider what to do when moving a directory into
	 itself but when source and destination are on different devices.  */

      /* This happens when attempting to rename a directory to a
	 subdirectory of itself.  */
      if (errno == EINVAL

	  /* When src_path is on an NFS file system, some types of
	     clients, e.g., SunOS4.1.4 and IRIX-5.3, set errno to EIO
	     instead.  Testing for this here risks misinterpreting a real
	     I/O error as an attempt to move a directory into itself, so
	     FIXME: consider not doing this.  */
	  || errno == EIO

	  /* And with SunOS-4.1.4 client and OpenBSD-2.3 server,
	     we get ENOTEMPTY.  */
	  || errno == ENOTEMPTY)
	{
	  /* FIXME: this is a little fragile in that it relies on rename(2)
	     failing with a specific errno value.  Expect problems on
	     non-POSIX systems.  */
	  error (0, 0, _("cannot move %s to a subdirectory of itself, %s"),
		 quote_n (0, top_level_src_path),
		 quote_n (1, top_level_dst_path));

	  /* Note that there is no need to call forget_created here,
	     (compare with the other calls in this file) since the
	     destination directory didn't exist before.  */

	  *copy_into_self = 1;
	  /* FIXME-cleanup: Don't return zero here; adjust mv.c accordingly.
	     The only caller that uses this code (mv.c) ends up setting its
	     exit status to nonzero when copy_into_self is nonzero.  */
	  return 0;
	}

      /* WARNING: there probably exist systems for which an inter-device
	 rename fails with a value of errno not handled here.
	 If/as those are reported, add them to the condition below.
	 If this happens to you, please do the following and send the output
	 to the bug-reporting address (e.g., in the output of cp --help):
	   touch k; perl -e 'rename "k","/tmp/k" or print "$!(",$!+0,")\n"'
	 where your current directory is on one partion and /tmp is the other.
	 Also, please try to find the E* errno macro name corresponding to
	 the diagnostic and parenthesized integer, and include that in your
	 e-mail.  One way to do that is to run a command like this
	   find /usr/include/. -type f \
	     | xargs grep 'define.*\<E[A-Z]*\>.*\<18\>' /dev/null
	 where you'd replace `18' with the integer in parentheses that
	 was output from the perl one-liner above.
	 If necessary, of course, change `/tmp' to some other directory.  */
      if (errno != EXDEV)
	{
	  /* There are many ways this can happen due to a race condition.
	     When something happens between the initial xstat and the
	     subsequent rename, we can get many different types of errors.
	     For example, if the destination is initially a non-directory
	     or non-existent, but it is created as a directory, the rename
	     fails.  If two `mv' commands try to rename the same file at
	     about the same time, one will succeed and the other will fail.
	     If the permissions on the directory containing the source or
	     destination file are made too restrictive, the rename will
	     fail.  Etc.  */
	  error (0, errno,
		 _("cannot move %s to %s"),
		 quote_n (0, src_path), quote_n (1, dst_path));
	  forget_created (src_sb.st_ino, src_sb.st_dev);
	  return 1;
	}

      /* The rename attempt has failed.  Remove any existing destination
	 file so that a cross-device `mv' acts as if it were really using
	 the rename syscall.  */
      if (unlink (dst_path) && errno != ENOENT)
	{
	  error (0, errno,
	     _("inter-device move failed: %s to %s; unable to remove target"),
		 quote_n (0, src_path), quote_n (1, dst_path));
	  forget_created (src_sb.st_ino, src_sb.st_dev);
	  return 1;
	}

      new_dst = 1;
    }

  delayed_fail = 0;

  /* In certain modes (cp's --symbolic-link), and for certain file types
     (symlinks and hard links) it doesn't make sense to preserve metadata,
     or it's possible to preserve only some of it.
     In such cases, set this variable to zero.  */
  preserve_metadata = 1;

  if (S_ISDIR (src_type))
    {
      struct dir_list *dir;

      /* If this directory has been copied before during the
         recursion, there is a symbolic link to an ancestor
         directory of the symbolic link.  It is impossible to
         continue to copy this, unless we've got an infinite disk.  */

      if (is_ancestor (&src_sb, ancestors))
	{
	  error (0, 0, _("cannot copy cyclic symbolic link %s"),
		 quote (src_path));
	  goto un_backup;
	}

      /* Insert the current directory in the list of parents.  */

      dir = (struct dir_list *) alloca (sizeof (struct dir_list));
      dir->parent = ancestors;
      dir->ino = src_sb.st_ino;
      dir->dev = src_sb.st_dev;

      if (new_dst || !S_ISDIR (dst_sb.st_mode))
	{
	  /* Create the new directory writable and searchable, so
             we can create new entries in it.  */

	  if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
	    {
	      error (0, errno, _("cannot create directory %s"),
		     quote (dst_path));
	      goto un_backup;
	    }

	  /* Insert the created directory's inode and device
             numbers into the search structure, so that we can
             avoid copying it again.  */

	  if (remember_created (dst_path))
	    goto un_backup;

	  if (x->verbose)
	    printf ("%s -> %s\n", quote_n (0, src_path), quote_n (1, dst_path));
	}

      /* Are we crossing a file system boundary?  */
      if (x->one_file_system && device != 0 && device != src_sb.st_dev)
	return 0;

      /* Copy the contents of the directory.  */

      if (copy_dir (src_path, dst_path, new_dst, &src_sb, dir, x,
		    copy_into_self))
	{
	  /* Don't just return here -- otherwise, the failure to read a
	     single file in a source directory would cause the containing
	     destination directory not to have owner/perms set properly.  */
	  delayed_fail = 1;
	}
    }
#ifdef S_ISLNK
  else if (x->symbolic_link)
    {
      preserve_metadata = 0;

      if (*src_path != '/')
	{
	  /* Check that DST_PATH denotes a file in the current directory.  */
	  struct stat dot_sb;
	  struct stat dst_parent_sb;
	  char *dst_parent;
	  int in_current_dir;

	  dst_parent = dir_name (dst_path);

	  in_current_dir = (STREQ (".", dst_parent)
			    /* If either stat call fails, it's ok not to report
			       the failure and say dst_path is in the current
			       directory.  Other things will fail later.  */
			    || stat (".", &dot_sb)
			    || stat (dst_parent, &dst_parent_sb)
			    || SAME_INODE (dot_sb, dst_parent_sb));
	  free (dst_parent);

	  if (! in_current_dir)
	    {
	      error (0, 0,
	   _("%s: can make relative symbolic links only in current directory"),
		     quote (dst_path));
	      goto un_backup;
	    }
	}
      if (symlink (src_path, dst_path))
	{
	  error (0, errno, _("cannot create symbolic link %s to %s"),
		 quote_n (0, dst_path), quote_n (1, src_path));
	  goto un_backup;
	}
    }
#endif
  else if (x->hard_link)
    {
      preserve_metadata = 0;
      if (link (src_path, dst_path))
	{
	  error (0, errno, _("cannot create link %s"), quote (dst_path));
	  goto un_backup;
	}
    }
  else if (S_ISREG (src_type)
	   || (x->copy_as_regular && !S_ISDIR (src_type)
#ifdef S_ISLNK
	       && !S_ISLNK (src_type)
#endif
	       ))
    {
      copied_as_regular = 1;
      /* POSIX says the permission bits of the source file must be
	 used as the 3rd argument in the open call, but that's not consistent
	 with historical practice.  */
      if (copy_reg (src_path, dst_path, x,
		    get_dest_mode (x, src_mode), &new_dst, &src_sb))
	goto un_backup;
    }
  else
#ifdef S_ISFIFO
  if (S_ISFIFO (src_type))
    {
      if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
	{
	  error (0, errno, _("cannot create fifo %s"), quote (dst_path));
	  goto un_backup;
	}
    }
  else
#endif
    if (S_ISBLK (src_type) || S_ISCHR (src_type)
#ifdef S_ISSOCK
	|| S_ISSOCK (src_type)
#endif
	)
    {
      if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))
	{
	  error (0, errno, _("cannot create special file %s"),
		 quote (dst_path));
	  goto un_backup;
	}
    }
  else
#ifdef S_ISLNK
  if (S_ISLNK (src_type))
    {
      char *src_link_val = xreadlink (src_path);
      if (src_link_val == NULL)
	{
	  error (0, errno, _("cannot read symbolic link %s"), quote (src_path));
	  goto un_backup;
	}

      if (!symlink (src_link_val, dst_path))
	free (src_link_val);
      else
	{
	  int saved_errno = errno;
	  int same_link = 0;
	  if (x->update && !new_dst && S_ISLNK (dst_sb.st_mode))
	    {
	      /* See if the destination is already the desired symlink.  */
	      size_t src_link_len = strlen (src_link_val);
	      char *dest_link_val = (char *) alloca (src_link_len + 1);
	      int dest_link_len = readlink (dst_path, dest_link_val,
					    src_link_len + 1);
	      if ((size_t) dest_link_len == src_link_len
		  && strncmp (dest_link_val, src_link_val, src_link_len) == 0)
		same_link = 1;
	    }
	  free (src_link_val);

	  if (! same_link)
	    {
	      error (0, saved_errno, _("cannot create symbolic link %s"),
		     quote (dst_path));
	      goto un_backup;
	    }
	}

      /* There's no need to preserve timestamps or permissions.  */
      preserve_metadata = 0;

      if (x->preserve_ownership)
	{
	  /* Preserve the owner and group of the just-`copied'
	     symbolic link, if possible.  */
# if HAVE_LCHOWN
	  if (DO_CHOWN (lchown, dst_path, src_sb.st_uid, src_sb.st_gid))
	    {
	      error (0, errno, _("failed to preserve ownership for %s"),
		     dst_path);
	      goto un_backup;
	    }
# else
	  /* Can't preserve ownership of symlinks.
	     FIXME: maybe give a warning or even error for symlinks
	     in directories with the sticky bit set -- there, not
	     preserving owner/group is a potential security problem.  */
# endif
	}
    }
  else
#endif
    {
      error (0, 0, _("%s has unknown file type"), quote (src_path));
      goto un_backup;
    }

  if (command_line_arg)
    record_file (x->dest_info, dst_path, NULL);

  if ( ! preserve_metadata)
    return 0;

  /* POSIX says that `cp -p' must restore the following:
     - permission bits
     - setuid, setgid bits
     - owner and group
     If it fails to restore any of those, we may give a warning but
     the destination must not be removed.
     FIXME: implement the above. */

  /* Adjust the times (and if possible, ownership) for the copy.
     chown turns off set[ug]id bits for non-root,
     so do the chmod last.  */

  if (x->preserve_timestamps)
    {
      struct utimbuf utb;

      /* There's currently no interface to set file timestamps with
	 better than 1-second resolution, so discard any fractional
	 part of the source timestamp.  */

      utb.actime = src_sb.st_atime;
      utb.modtime = src_sb.st_mtime;

      if (utime (dst_path, &utb))
	{
	  error (0, errno, _("preserving times for %s"), quote (dst_path));
	  if (x->require_preserve)
	    return 1;
	}
    }

  /* Avoid calling chown if we know it's not necessary.  */
  if (x->preserve_ownership
      && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
    {
      ran_chown = 1;
      if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid))
	{
	  error (0, errno, _("failed to preserve ownership for %s"),
		 quote (dst_path));
	  if (x->require_preserve)
	    return 1;
	}
    }

#if HAVE_STRUCT_STAT_ST_AUTHOR
  /* Preserve the st_author field.  */
  {
    file_t file = file_name_lookup (dst_path, 0, 0);
    if (file_chauthor (file, src_sb.st_author))
      error (0, errno, _("failed to preserve authorship for %s"),
	     quote (dst_path));
    mach_port_deallocate (mach_task_self (), file);
  }
#endif

  /* Permissions of newly-created regular files were set upon `open' in
     copy_reg.  But don't return early if there were any special bits and
     we had to run chown, because the chown must have reset those bits.  */
  if ((new_dst && copied_as_regular)
      && !(ran_chown && (src_mode & ~S_IRWXUGO)))
    return delayed_fail;

  if ((x->preserve_mode || new_dst)
      && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type)))
    {
      if (chmod (dst_path, get_dest_mode (x, src_mode)))
	{
	  error (0, errno, _("setting permissions for %s"), quote (dst_path));
	  if (x->set_mode || x->require_preserve)
	    return 1;
	}
    }

  return delayed_fail;

un_backup:

  /* We have failed to create the destination file.
     If we've just added a dev/ino entry via the remember_copied
     call above (i.e., unless we've just failed to create a hard link),
     remove the entry associating the source dev/ino with the
     destination file name, so we don't try to `preserve' a link
     to a file we didn't create.  */
  if (earlier_file == NULL)
    forget_created (src_sb.st_ino, src_sb.st_dev);

  if (dst_backup)
    {
      if (rename (dst_backup, dst_path))
	error (0, errno, _("cannot un-backup %s"), quote (dst_path));
      else
	{
	  if (x->verbose)
	    printf (_("%s -> %s (unbackup)\n"),
		    quote_n (0, dst_backup), quote_n (1, dst_path));
	}
    }
  return 1;
}
예제 #21
0
파일: dirn.c 프로젝트: mqudsi/testdisk
static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, file_data_t*dir_list, const unsigned long int inode, const unsigned int depth)
{
  /* Return value
   * -1: quit
   *  1: back
   *  other: new inode
   * */
  int quit=0;
  WINDOW *window=(WINDOW*)dir_data->display;
  do
  {
    int offset=0;
    int pos_num=0;
    file_data_t *pos=dir_list;
    int old_LINES=LINES;
    unsigned int status=FILE_STATUS_MARKED;
    aff_copy(window);
    wmove(window,3,0);
    aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS, disk, partition);
    wmove(window,4,0);
    wprintw(window,"Directory %s\n",dir_data->current_directory);
    do
    {
      int i;
      int car;
      const file_data_t *current_file;
      for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
      for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next)
      {
	char str[11];
	char		datestr[80];
	wmove(window, 6+i-offset, 0);
	wclrtoeol(window);	/* before addstr for BSD compatibility */
	if(current_file==pos)
	{
	  wattrset(window, A_REVERSE);
	  waddstr(window, ">");
	}
	else
	  waddstr(window, " ");
	if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(1));
	else if((current_file->status&FILE_STATUS_MARKED)!=0 && has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(2));
	if(current_file->td_mtime!=0)
	{
	  struct tm		*tm_p;
	  tm_p = localtime(&current_file->td_mtime);
	  snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d",
	      tm_p->tm_mday, monstr[tm_p->tm_mon],
	      1900 + tm_p->tm_year, tm_p->tm_hour,
	      tm_p->tm_min);
	  /* May have to use %d instead of %e */
	} else {
	  strncpy(datestr, "                 ",sizeof(datestr));
	}
	mode_string(current_file->st_mode, str);
	wprintw(window, "%s %5u %5u ", 
	    str, (unsigned int)current_file->st_uid, (unsigned int)current_file->st_gid);
	wprintw(window, "%9llu", (long long unsigned int)current_file->st_size);
	/* screen may overlap due to long filename */
	wprintw(window, " %s %s", datestr, current_file->name);
	if(((current_file->status&FILE_STATUS_DELETED)!=0 ||
	      (current_file->status&FILE_STATUS_MARKED)!=0) && has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	if(current_file==pos)
	  wattroff(window, A_REVERSE);
      }
      wmove(window, 6-1, 51);
      wclrtoeol(window);
      if(offset>0)
	wprintw(window, "Previous");
      /* Clear the last line, useful if overlapping */
      wmove(window,6+i-offset,0);
      wclrtoeol(window);
      wmove(window, 6+INTER_DIR, 51);
      wclrtoeol(window);
      if(current_file!=NULL)
	wprintw(window, "Next");
      if(dir_list==NULL)
      {
	wmove(window,6,0);
	wprintw(window,"No file found, filesystem may be damaged.");
      }
      /* Redraw the bottom of the screen everytime because very long filenames may have corrupt it*/
      mvwaddstr(window,LINES-3,0,"Use ");
      if(depth>0)
      {
	if(has_colors())
	  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(window, "Left");
	if(has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	waddstr(window," arrow to go back, ");
      }
      if(has_colors())
	wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(window,"Right");
      if(has_colors())
	wbkgdset(window,' ' | COLOR_PAIR(0));
      waddstr(window," to change directory");
      if((dir_data->capabilities&CAPA_LIST_DELETED)!=0)
      {
	waddstr(window,", ");
	if(has_colors())
	  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(window,"h");
	if(has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	if((dir_data->param&FLAG_LIST_DELETED)==0)
	  waddstr(window," to unhide deleted files");
	else
	  waddstr(window," to hide deleted files");
      }
      wmove(window,LINES-2,4);
      if(has_colors())
	wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(window,"q");
      if(has_colors())
	wbkgdset(window,' ' | COLOR_PAIR(0));
      waddstr(window," to quit");
      if(dir_data->copy_file!=NULL)
      {
	waddstr(window,", ");
	if(has_colors())
	  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(window,":");
	if(has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	waddstr(window," to select the current file, ");
	if(has_colors())
	  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(window,"a");
	if(has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	if((status&FILE_STATUS_MARKED)==FILE_STATUS_MARKED)
	  waddstr(window," to select all files  ");
	else
	  waddstr(window," to deselect all files");
	if(has_colors())
	  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
	mvwaddstr(window,LINES-1,4,"C");
	if(has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	waddstr(window," to copy the selected files, ");
	if(has_colors())
	  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(window,"c");
	if(has_colors())
	  wbkgdset(window,' ' | COLOR_PAIR(0));
	waddstr(window," to copy the current file");
      }
      wrefresh(window);
      /* Using gnome terminal under FC3, TERM=xterm, the screen is not always correct */
      wredrawln(window,0,getmaxy(window));	/* redrawwin def is boggus in pdcur24 */
      car=wgetch(window);
      wmove(window,5,0);
      wclrtoeol(window);
      switch(car)
      {
	case key_ESC:
	case 'q':
	case 'M':
	  quit=1;
	  break;
	case '-':
	case KEY_LEFT:
	case '4':
	  if(depth>0)
	    return 1;
	  break;
	case 'h':
	  if((dir_data->capabilities&CAPA_LIST_DELETED)!=0)
	    dir_data->param^=FLAG_LIST_DELETED;
	  return inode;
      }
      if(dir_list!=NULL)
      {
	switch(car)
	{
	  case KEY_UP:
	  case '8':
	    if(pos->prev!=NULL)
	    {
	      pos=pos->prev;
	      pos_num--;
	    }
	    break;
	  case KEY_DOWN:
	  case '2':
	    if(pos->next!=NULL)
	    {
	      pos=pos->next;
	      pos_num++;
	    }
	    break;
	  case ':':
	    if(!(pos->name[0]=='.' && pos->name[1]=='\0') &&
		!(pos->name[0]=='.' && pos->name[1]=='.' && pos->name[2]=='\0'))
	    pos->status^=FILE_STATUS_MARKED;
	    if(pos->next!=NULL)
	    {
	      pos=pos->next;
	      pos_num++;
	    }
	    break;
	  case 'a':
	    {
	      file_data_t *tmp;
	      for(tmp=dir_list; tmp!=NULL; tmp=tmp->next)
	      {
		if((tmp->name[0]=='.' && tmp->name[1]=='\0') ||
		    (tmp->name[0]=='.' && tmp->name[1]=='.' && tmp->name[2]=='\0'))
		{
		  tmp->status&=~FILE_STATUS_MARKED;
		}
		else
		{
		  if((tmp->status & FILE_STATUS_MARKED)!=status)
		    tmp->status^=FILE_STATUS_MARKED;
		}
	      }
	      status^=FILE_STATUS_MARKED;
	    }
	    break;
	  case 'p':
	  case 'P':
	  case '+':
	  case ' ':
	  case KEY_RIGHT:
	  case '\r':
	  case '\n':
	  case '6':
	  case KEY_ENTER:
#ifdef PADENTER
	  case PADENTER:
#endif
	    if((pos!=NULL) && (LINUX_S_ISDIR(pos->st_mode)!=0))
	    {
	      unsigned long int new_inode=pos->st_ino;
	      if((new_inode!=inode) &&(strcmp(pos->name,".")!=0))
	      {
		if(strcmp(pos->name,"..")==0)
		  return 1;
		if(strlen(dir_data->current_directory)+1+strlen(pos->name)+1<=sizeof(dir_data->current_directory))
		{
		  if(strcmp(dir_data->current_directory,"/"))
		    strcat(dir_data->current_directory,"/");
		  strcat(dir_data->current_directory,pos->name);
		  return (long int)new_inode;
		}
	      }
	    }
	    break;
	  case KEY_PPAGE:
	    for(i=0;(i<INTER_DIR-1)&&(pos->prev!=NULL);i++)
	    {
	      pos=pos->prev;
	      pos_num--;
	    }
	    break;
	  case KEY_NPAGE:
	    for(i=0;(i<INTER_DIR-1)&&(pos->next!=NULL);i++)
	    {
	      pos=pos->next;
	      pos_num++;
	    }
	    break;
	  case 'c':
	    if(dir_data->copy_file!=NULL)
	    {
	      const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
	      if(strcmp(pos->name,"..")!=0 &&
		  current_directory_namelength+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1)
	      {
		if(strcmp(dir_data->current_directory,"/"))
		  strcat(dir_data->current_directory,"/");
		if(strcmp(pos->name,".")!=0)
		  strcat(dir_data->current_directory,pos->name);
		if(dir_data->local_dir==NULL)
		{
		  if(LINUX_S_ISDIR(pos->st_mode)!=0)
		    dir_data->local_dir=ask_location("Please select a destination where %s and any files below will be copied.",
			dir_data->current_directory, NULL);
		  else
		    dir_data->local_dir=ask_location("Please select a destination where %s will be copied.",
			dir_data->current_directory, NULL);
		}
		if(dir_data->local_dir!=NULL)
		{
		  int res=-1;
		  wmove(window,5,0);
		  wclrtoeol(window);
		  if(has_colors())
		    wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
		  wprintw(window,"Copying, please wait...");
		  if(has_colors())
		    wbkgdset(window,' ' | COLOR_PAIR(0));
		  wrefresh(window);
		  if(LINUX_S_ISDIR(pos->st_mode)!=0)
		  {
		    res=copy_dir(disk, partition, dir_data, pos);
		  }
		  else if(LINUX_S_ISREG(pos->st_mode)!=0)
		  {
		    res=dir_data->copy_file(disk, partition, dir_data, pos);
		  }
		  wmove(window,5,0);
		  wclrtoeol(window);
		  if(res < -1)
		  {
		    if(has_colors())
		      wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
		    wprintw(window,"Copy failed!");
		  }
		  else
		  {
		    if(has_colors())
		      wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2));
		    if(res < 0)
		      wprintw(window,"Copy done! (Failed to copy some files)");
		    else
		      wprintw(window,"Copy done!");
		  }
		  if(has_colors())
		    wbkgdset(window,' ' | COLOR_PAIR(0));
		}
		dir_data->current_directory[current_directory_namelength]='\0';
	      }
	    }
	    break;
	  case 'C':
	    if(dir_data->copy_file!=NULL)
	    {
	      if(dir_data->local_dir==NULL)
	      {
		dir_data->local_dir=ask_location("Please select a destination where the marked files will be copied.", NULL, NULL);
	      }
	      if(dir_data->local_dir!=NULL)
	      {
		file_data_t *tmp;
		int copy_bad=0;
		int copy_ok=0;
		const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
		wmove(window,5,0);
		wclrtoeol(window);
		if(has_colors())
		  wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
		wprintw(window,"Copying, please wait...");
		if(has_colors())
		  wbkgdset(window,' ' | COLOR_PAIR(0));
		wrefresh(window);
		for(tmp=dir_list; tmp!=NULL; tmp=tmp->next)
		{
		  if((tmp->status&FILE_STATUS_MARKED)!=0 &&
		      current_directory_namelength + 1 + strlen(tmp->name) <
		      sizeof(dir_data->current_directory)-1)
		  {
		    if(strcmp(dir_data->current_directory,"/"))
		      strcat(dir_data->current_directory,"/");
		    if(strcmp(tmp->name,".")!=0)
		      strcat(dir_data->current_directory,tmp->name);
		    if(LINUX_S_ISDIR(tmp->st_mode)!=0)
		    {
		      const int res=copy_dir(disk, partition, dir_data, tmp);
		      if(res >=-1)
		      {
			tmp->status&=~FILE_STATUS_MARKED;
			copy_ok=1;
		      }
		      else if(res < 0)
			copy_bad=1;
		    }
		    else if(LINUX_S_ISREG(tmp->st_mode)!=0)
		    {
		      if(dir_data->copy_file(disk, partition, dir_data, tmp) == 0)
		      {
			tmp->status&=~FILE_STATUS_MARKED;
			copy_ok=1;
		      }
		      else
			copy_bad=1;
		    }
		  }
		  dir_data->current_directory[current_directory_namelength]='\0';
		}
		wmove(window,5,0);
		wclrtoeol(window);
		if(copy_bad > 0 && copy_ok==0)
		{
		  if(has_colors())
		    wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
		  wprintw(window,"Copy failed!");
		}
		else
		{
		  if(has_colors())
		    wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2));
		  if(copy_bad > 0)
		    wprintw(window,"Copy done! (Failed to copy some files)");
		  else if(copy_ok == 0)
		    wprintw(window,"No file selected");
		  else
		    wprintw(window,"Copy done!");
		}
		if(has_colors())
		  wbkgdset(window,' ' | COLOR_PAIR(0));
	      }
	    }
	    break;	
	  case 'f':
	    {
	      const char *needle=ask_string_ncurses("Filename to find ? ");
	      if(needle!=NULL && needle[0]!='\0')
	      {
		file_data_t *pos_org=pos;
		const int pos_num_org=pos_num;
		while(strcmp(pos->name, needle)!=0 && pos->next!=NULL)
		{
		  pos=pos->next;
		  pos_num++;
		}
		if(strcmp(pos->name, needle)!=0)
		{
		  pos=pos_org;
		  pos_num=pos_num_org;
		}
	      }
	    }
	    break;
	}
	if(pos_num<offset)
	  offset=pos_num;
	if(pos_num>=offset+INTER_DIR)
	  offset=pos_num-INTER_DIR+1;
      }
    } while(quit==0 && old_LINES==LINES);
  } while(quit==0);
  return -1;
}
예제 #22
0
int makeflow_archive_copy_preserved_files(struct archive_instance *a, struct batch_task *t, char *task_path ) {
	struct batch_file *f;
	struct stat buf;
	struct list_cursor *cur = list_cursor_create(t->output_files);
	// Iterate through output files
	for(list_seek(cur, 0); list_get(cur, (void**)&f); list_next(cur)) {
		char *file_name = xxstrdup(f->outer_name);
		debug(D_MAKEFLOW_HOOK,"Trying to copy file to %s",file_name);
		char *file_to_check = xxstrdup(file_name);
		//Check to see if the directory was copied as an empty file/incorrectly
		stat(dirname(file_to_check),&buf);
		if(S_ISREG(buf.st_mode)){
			debug(D_MAKEFLOW,"Removing empty file in the place of directory name %s",file_to_check);
			char *dirEmpty = string_format("rm -rf %s",file_to_check);
			system(dirEmpty);
			free(dirEmpty);
		}
		free(file_to_check);
		// Gets path of output file
		char *output_file_path = string_format("%s/output_files/%s",task_path,basename(file_name));
		char *directory_name = xxstrdup(file_name);
		debug(D_MAKEFLOW_HOOK,"Creating directory %s",dirname(directory_name));
		if(strcmp(directory_name,file_name) != 0){
			//Create the upper level directory to copy the output files into if necessary
			if (!create_dir(directory_name, 0777) && errno != EEXIST){
				debug(D_ERROR|D_MAKEFLOW_HOOK,"Failed to create directory %s",directory_name);
				free(directory_name);
				free(output_file_path);
				free(file_name);
				return 1;
			}
		}
		free(directory_name);
		// Copy output file or directory over to specified location
		if(path_is_dir(output_file_path) != 1){
			int success = copy_file_to_file(output_file_path, file_name);
			free(output_file_path);
			free(file_name);
			if (!success) {
				list_cursor_destroy(cur);
				debug(D_ERROR|D_MAKEFLOW_HOOK,"Failed to copy output file %s to %s\n", output_file_path, file_name);
				return 1;
			}
		}
		else{
			if(copy_dir(output_file_path, file_name) != 0){
				list_cursor_destroy(cur);
								debug(D_ERROR|D_MAKEFLOW_HOOK,"Failed to copy output file %s to %s\n", output_file_path, file_name);
				free(output_file_path);
							free(file_name);
								return 1;
						}
			free(output_file_path);
			free(file_name);
		}
		}


	list_cursor_destroy(cur);

	return 0;
}
예제 #23
0
파일: mod_copy.c 프로젝트: laoflch/proftpd
static int copy_dir(pool *p, const char *src_dir, const char *dst_dir) {
  DIR *dh = NULL;
  struct dirent *dent = NULL;
  int res = 0;
  pool *iter_pool = NULL;

  dh = opendir(src_dir);
  if (dh == NULL) {
    pr_log_pri(PR_LOG_WARNING, MOD_COPY_VERSION
      ": error reading directory '%s': %s", src_dir, strerror(errno));
    return -1;
  }

  while ((dent = readdir(dh)) != NULL) {
    struct stat st;
    char *src_path, *dst_path;

    pr_signals_handle();

    /* Skip "." and ".." */
    if (strncmp(dent->d_name, ".", 2) == 0 ||
        strncmp(dent->d_name, "..", 3) == 0) {
      continue;
    }

    if (iter_pool != NULL) {
      destroy_pool(iter_pool);
    }

    iter_pool = pr_pool_create_sz(p, 128);
    src_path = pdircat(iter_pool, src_dir, dent->d_name, NULL);
    dst_path = pdircat(iter_pool, dst_dir, dent->d_name, NULL);

    if (pr_fsio_lstat(src_path, &st) < 0) {
      pr_log_debug(DEBUG3, MOD_COPY_VERSION
        ": unable to stat '%s' (%s), skipping", src_path, strerror(errno));
      continue;
    }

    /* Is this path to a directory? */
    if (S_ISDIR(st.st_mode)) {
      if (create_path(iter_pool, dst_path) < 0) {
        res = -1;
        break;
      }

      if (copy_dir(iter_pool, src_path, dst_path) < 0) {
        res = -1;
        break;
      }
      continue;

    /* Is this path to a regular file? */
    } else if (S_ISREG(st.st_mode)) {
      cmd_rec *cmd;

      /* Dispatch fake COPY command, e.g. for mod_quotatab */
      cmd = pr_cmd_alloc(iter_pool, 4, pstrdup(iter_pool, "SITE"),
        pstrdup(iter_pool, "COPY"), pstrdup(iter_pool, src_path),
        pstrdup(iter_pool, dst_path));
      cmd->arg = pstrcat(iter_pool, "COPY ", src_path, " ", dst_path, NULL);
      cmd->cmd_class = CL_WRITE;

      pr_response_clear(&resp_list);
      pr_response_clear(&resp_err_list);

      if (pr_cmd_dispatch_phase(cmd, PRE_CMD, 0) < 0) {
        int xerrno = errno;

        pr_log_debug(DEBUG3, MOD_COPY_VERSION
          ": COPY of '%s' to '%s' blocked by COPY handler: %s", src_path,
          dst_path, strerror(xerrno));

        pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
        pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
        pr_response_clear(&resp_err_list);

        errno = xerrno;
        res = -1;
        break;

      } else {
        if (pr_fs_copy_file(src_path, dst_path) < 0) {
          pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
          pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
          pr_response_clear(&resp_err_list);

          res = -1;
          break;

        } else {
          char *abs_path;
          
          pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
          pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
          pr_response_clear(&resp_list);

          /* Write a TransferLog entry as well. */

          pr_fs_clear_cache2(dst_path);
          pr_fsio_stat(dst_path, &st);

          abs_path = dir_abs_path(p, dst_path, TRUE);

          if (session.sf_flags & SF_ANON) {
            xferlog_write(0, session.c->remote_name, st.st_size, abs_path,
               (session.sf_flags & SF_ASCII ? 'a' : 'b'), 'd', 'a',
               session.anon_user, 'c', "_");

          } else {
            xferlog_write(0, session.c->remote_name, st.st_size, abs_path,
              (session.sf_flags & SF_ASCII ? 'a' : 'b'), 'd', 'r',
              session.user, 'c', "_");
          }
        }
      }

      continue;

    /* Is this path a symlink? */
    } else if (S_ISLNK(st.st_mode)) {
      if (copy_symlink(iter_pool, src_path, dst_path) < 0) {
        res = -1;
        break;
      }
      continue;

    /* All other file types are skipped */
    } else {
      pr_log_debug(DEBUG3, MOD_COPY_VERSION ": skipping supported file '%s'",
        src_path);
      continue;
    }
  }

  if (iter_pool != NULL) {
    destroy_pool(iter_pool);
  }

  closedir(dh);
  return res;
}
예제 #24
0
파일: dirn.c 프로젝트: mqudsi/testdisk
static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir)
{
  static unsigned int dir_nbr=0;
  static unsigned long int inode_known[MAX_DIR_NBR];
  file_data_t *dir_list;
  const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
  file_data_t *current_file;
  char *dir_name;
  int copy_bad=0;
  int copy_ok=0;
  if(dir_data->get_dir==NULL || dir_data->copy_file==NULL)
    return -2;
  inode_known[dir_nbr++]=dir->st_ino;
  dir_name=mkdir_local(dir_data->local_dir, dir_data->current_directory);
  dir_list=dir_data->get_dir(disk, partition, dir_data, (const unsigned long int)dir->st_ino);
  for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
  {
    dir_data->current_directory[current_directory_namelength]='\0';
    if(current_directory_namelength+1+strlen(current_file->name)<sizeof(dir_data->current_directory)-1)
    {
      if(strcmp(dir_data->current_directory,"/"))
	strcat(dir_data->current_directory,"/");
      strcat(dir_data->current_directory,current_file->name);
      if(LINUX_S_ISDIR(current_file->st_mode)!=0)
      {
	const unsigned long int new_inode=current_file->st_ino;
	unsigned int new_inode_ok=1;
	unsigned int i;
	if(new_inode<2)
	  new_inode_ok=0;
	if(strcmp(current_file->name,"..")==0 || strcmp(current_file->name,".")==0)
	  new_inode_ok=0;
	for(i=0;i<dir_nbr && new_inode_ok!=0;i++)
	  if(new_inode==inode_known[i]) /* Avoid loop */
	    new_inode_ok=0;
	if(new_inode_ok>0)
	{
	  int tmp;
	  tmp=copy_dir(disk, partition, dir_data, current_file);
	  if(tmp>=-1)
	    copy_ok=1;
	  if(tmp<0)
	    copy_bad=1;
	}
      }
      else if(LINUX_S_ISREG(current_file->st_mode)!=0)
      {
//	log_trace("copy_file %s\n",dir_data->current_directory);
	int tmp;
	tmp=dir_data->copy_file(disk, partition, dir_data, current_file);
	if(tmp==0)
	  copy_ok=1;
	else
	  copy_bad=1;
      }
    }
  }
  dir_data->current_directory[current_directory_namelength]='\0';
  delete_list_file(dir_list);
  set_date(dir_name, dir->td_atime, dir->td_mtime);
  free(dir_name);
  dir_nbr--;
  return (copy_bad>0?(copy_ok>0?-1:-2):0);
}
예제 #25
0
/*
 * copy_dir: copy a directory
 *
 * If recurse is false, subdirectories are ignored.  Anything that's not
 * a directory or a regular file is ignored.
 */
void copy_dir(char *fromdir, char *todir, bool recurse)
{
	DIR *xldir;
	struct dirent *xlde;
	char fromfile[MAX_PG_PATH];
	char tofile[MAX_PG_PATH];

	if (mkdir(todir, S_IRWXU) != 0)
		ereport(ERROR, (errcode_file_access(),
		errmsg("could not create directory \"%s\": %m", todir)));

	xldir = alloc_dir(fromdir);
	if (xldir == NULL)
		ereport(ERROR, (errcode_file_access(),
		errmsg("could not open directory \"%s\": %m", fromdir)));

	while ((xlde = read_dir(xldir, fromdir)) != NULL) {
		struct stat fst;

		/* If we got a cancel signal during the copy of the directory,
		 * quit */
		CHECK_FOR_INTERRUPTS();

		if (strcmp(xlde->d_name, ".") == 0 || strcmp(xlde->d_name, "..") == 0)
			continue;

		snprintf(fromfile, MAX_PG_PATH, "%s/%s", fromdir, xlde->d_name);
		snprintf(tofile, MAX_PG_PATH, "%s/%s", todir, xlde->d_name);

		if (lstat(fromfile, &fst) < 0)
			ereport(ERROR, (errcode_file_access(),
			errmsg("could not stat file \"%s\": %m", fromfile)));

		if (S_ISDIR(fst.st_mode)) {
			/* recurse to handle subdirectories */
			if (recurse)
				copy_dir(fromfile, tofile, true);
		} else if (S_ISREG(fst.st_mode))
			copy_file(fromfile, tofile);
	}
	free_dir(xldir);

	/*
	 * Be paranoid here and fsync all files to ensure the copy is really 
	 * done.
	 */
	xldir = alloc_dir(todir);
	if (xldir == NULL)
		ereport(ERROR, (errcode_file_access(),
		errmsg("could not open directory \"%s\": %m", todir)));

	while ((xlde = read_dir(xldir, todir)) != NULL) {
		struct stat fst;

		if (strcmp(xlde->d_name, ".") == 0  || strcmp(xlde->d_name, "..") == 0)
			continue;

		snprintf(tofile, MAX_PG_PATH, "%s/%s", todir, xlde->d_name);

		/*
		 * We don't need to sync subdirectories here since the recursive
		 * copy_dir will do it before it returns
		 */
		if (lstat(tofile, &fst) < 0)
			ereport(ERROR, (errcode_file_access(),
			errmsg("could not stat file \"%s\": %m", tofile)));

		if (S_ISREG(fst.st_mode))
			fsync_fname(tofile, false);
	}
	free_dir(xldir);

	/*
	 * It's important to fsync the destination directory itself as 
	 * individual file fsyncs don't guarantee that the directory entry for
	 * the file is synced. Recent versions of ext4 have made the window much
	 * wider but it's been true for ext3 and other filesystems in the past.
	 */
	fsync_fname(todir, true);
}
예제 #26
0
파일: mod_copy.c 프로젝트: laoflch/proftpd
static int copy_paths(pool *p, const char *from, const char *to) {
  struct stat st;
  int res;
  xaset_t *set;

  set = get_dir_ctxt(p, (char *) to);
  res = pr_filter_allow_path(set, to);
  switch (res) {
    case 0:
      break;

    case PR_FILTER_ERR_FAILS_ALLOW_FILTER:
      pr_log_debug(DEBUG7, MOD_COPY_VERSION
        ": path '%s' denied by PathAllowFilter", to);
      errno = EPERM;
      return -1;

    case PR_FILTER_ERR_FAILS_DENY_FILTER:
      pr_log_debug(DEBUG7, MOD_COPY_VERSION
        ": path '%s' denied by PathDenyFilter", to);
      errno = EPERM;
      return -1;
  }

  /* Check whether from is a file, a directory, a symlink, or something
   * unsupported.
   */
  res = pr_fsio_lstat(from, &st);
  if (res < 0) {
    int xerrno = errno;

    pr_log_debug(DEBUG7, MOD_COPY_VERSION ": error checking '%s': %s", from,
      strerror(xerrno));

    errno = xerrno;
    return -1;
  }
   
  if (S_ISREG(st.st_mode)) { 
    char *abs_path;

    pr_fs_clear_cache2(to);
    res = pr_fsio_stat(to, &st);
    if (res == 0) {
      unsigned char *allow_overwrite;

      allow_overwrite = get_param_ptr(CURRENT_CONF, "AllowOverwrite", FALSE);
      if (allow_overwrite == NULL ||
          *allow_overwrite == FALSE) {
        pr_log_debug(DEBUG6,
          MOD_COPY_VERSION ": AllowOverwrite permission denied for '%s'", to);
        errno = EACCES;
        return -1;
      }
    }

    res = pr_fs_copy_file(from, to);
    if (res < 0) {
      int xerrno = errno;

      pr_log_debug(DEBUG7, MOD_COPY_VERSION
        ": error copying file '%s' to '%s': %s", from, to, strerror(xerrno));

      errno = xerrno;
      return -1;
    }

    pr_fs_clear_cache2(to);
    if (pr_fsio_stat(to, &st) < 0) {
      pr_trace_msg(trace_channel, 3,
        "error stat'ing '%s': %s", to, strerror(errno));
    }

    /* Write a TransferLog entry as well. */
    abs_path = dir_abs_path(p, to, TRUE);

    if (session.sf_flags & SF_ANON) {
      xferlog_write(0, session.c->remote_name, st.st_size, abs_path,
        (session.sf_flags & SF_ASCII ? 'a' : 'b'), 'd', 'a',
        session.anon_user, 'c', "_");

    } else {
      xferlog_write(0, session.c->remote_name, st.st_size, abs_path,
        (session.sf_flags & SF_ASCII ? 'a' : 'b'), 'd', 'r',
        session.user, 'c', "_");
    }

  } else if (S_ISDIR(st.st_mode)) {
    res = create_path(p, to);
    if (res < 0) {
      int xerrno = errno;

      pr_log_debug(DEBUG7, MOD_COPY_VERSION
        ": error creating path '%s': %s", to, strerror(xerrno));

      errno = xerrno;
      return -1;
    }

    res = copy_dir(p, from, to);
    if (res < 0) {
      int xerrno = errno;

      pr_log_debug(DEBUG7, MOD_COPY_VERSION
        ": error copying directory '%s' to '%s': %s", from, to,
        strerror(xerrno));

      errno = xerrno;
      return -1;
    }

  } else if (S_ISLNK(st.st_mode)) {
    pr_fs_clear_cache2(to);
    res = pr_fsio_stat(to, &st);
    if (res == 0) {
      unsigned char *allow_overwrite;

      allow_overwrite = get_param_ptr(CURRENT_CONF, "AllowOverwrite", FALSE);
      if (allow_overwrite == NULL ||
          *allow_overwrite == FALSE) {
        pr_log_debug(DEBUG6, MOD_COPY_VERSION
          ": AllowOverwrite permission denied for '%s'", to);
        errno = EACCES;
        return -1;
      }
    }

    res = copy_symlink(p, from, to);
    if (res < 0) {
      int xerrno = errno;

      pr_log_debug(DEBUG7, MOD_COPY_VERSION
        ": error copying symlink '%s' to '%s': %s", from, to, strerror(xerrno));

      errno = xerrno;
      return -1;
    }

  } else {
    pr_log_debug(DEBUG7, MOD_COPY_VERSION
      ": unsupported file type for '%s'", from);
    errno = EINVAL;
    return -1;
  }

  return 0;
}
예제 #27
0
/* Archive the specified file.
 * This includes several steps:
 *	1. Generate the id
 *	2. Copy file to id if non-existent
 *	3. Link back to creating task
 *
@return 0 if successfully archived, 1 if failed at any point.
 */
static int makeflow_archive_file(struct archive_instance *a, struct batch_file *f, char *job_file_archive_path) {
	/* Generate the file archive id (content based) if does not exist. */
	char * id;
	if(path_is_dir(f->inner_name) == 1){
		f->hash = batch_file_generate_id_dir(f->inner_name);
				id = xxstrdup(f->hash);
	}
	else{
		id = batch_file_generate_id(f);
	}

	struct stat buf;
	int rv = 0;

	char * file_archive_dir = string_format("%s/files/%.2s", a->dir, id);
	char * file_archive_path = string_format("%s/%s", file_archive_dir, id);
	char * job_file_archive_dir = NULL;

	/* Create the archive path with 2 character prefix. */
	if (!create_dir(file_archive_dir, 0777) && errno != EEXIST){
		debug(D_ERROR|D_MAKEFLOW_HOOK, "could not create file archiving directory %s: %d %s\n", 
			file_archive_dir, errno, strerror(errno));
		rv = 1;
		goto FAIL;
	}

	/* Check if file is already archived */
	if(stat(file_archive_path, &buf) >= 0) {
		debug(D_MAKEFLOW_HOOK, "file %s already archived at %s", f->outer_name, file_archive_path);
	/* File did not already exist, store in general file area */
	} else {
		if(path_is_dir(f->outer_name) != 1){
			if (!copy_file_to_file(f->outer_name, file_archive_path)){
				debug(D_ERROR|D_MAKEFLOW_HOOK, "could not archive output file %s at %s: %d %s\n",
					f->outer_name, file_archive_path, errno, strerror(errno));
				rv = 1;
				goto FAIL;
			}
		}
		else{
			debug(D_MAKEFLOW,"COPYING %s to the archive",f->outer_name);
			if(copy_dir(f->outer_name,file_archive_path) != 0){
				debug(D_ERROR|D_MAKEFLOW_HOOK, "could not archive output file %s at %s: %d %s\n",
										f->outer_name, file_archive_path, errno, strerror(errno));
								rv = 1;
								goto FAIL;
			}
		}
	}

	/* Create the directory structure for job_file_archive. */
	job_file_archive_dir = xxstrdup(job_file_archive_path);
	path_dirname(job_file_archive_path, job_file_archive_dir);
	if (!create_dir(job_file_archive_dir, 0777) && errno != EEXIST){
		debug(D_ERROR|D_MAKEFLOW_HOOK, "could not create job file directory %s: %d %s\n", 
			file_archive_dir, errno, strerror(errno));
		rv = 1;
		goto FAIL;
	}

	if(a->s3){
		int result = 1;
		// Check to see if file already exists in the s3 bucket
		if(a->s3_check){
			if(!in_s3_archive(a,id)){
				result = makeflow_archive_s3_file(a,id,file_archive_path);
			}
		}
		else
			result = makeflow_archive_s3_file(a,id,file_archive_path);
		/* Copy file to the s3 bucket*/
		if(!result){
			debug(D_ERROR|D_MAKEFLOW_HOOK, "could not copy file %s to s3 bucket: %d %s\n", id, errno, strerror(errno));
			rv = 1;
			goto FAIL;
		}
	}
	free(file_archive_path);
	file_archive_path = string_format("../../../../files/%.2s/%s", id, id);

	/* Create a symlink to task that used/created this file. */
	int symlink_failure = symlink(file_archive_path, job_file_archive_path);
	if (symlink_failure && errno != EEXIST) {
		debug(D_ERROR|D_MAKEFLOW_HOOK, "could not create symlink %s pointing to %s: %d %s\n", 
			job_file_archive_path, file_archive_path, errno, strerror(errno));
		rv = 1;
		goto FAIL;
	}

FAIL:
	free(id);
	free(file_archive_dir);
	free(file_archive_path);
	free(job_file_archive_dir);
	return rv;
}