Exemple #1
0
static int _xx_realpath_from_path(struct path *path, char *newname,
                                  int newname_len)
{
    struct dentry *dentry = path->dentry;
    int error = -ENOMEM;
    char *sp;

    if (!dentry || !path->mnt || !newname || newname_len <= 2048)
        return -EINVAL;
    if (dentry->d_op && dentry->d_op->d_dname) {
        /* For "socket:[\$]" and "pipe:[\$]". */
        static const int offset = 1536;
        sp = dentry->d_op->d_dname(dentry, newname + offset,
                                   newname_len - offset);
    }
    else {
        /* Taken from d_namespace_path(). */
        struct path ns_root = { };
        struct path root;
        struct path tmp;

        read_lock(&current->fs->lock);
        root = current->fs->root;
        path_get(&root);
        read_unlock(&current->fs->lock);
        spin_lock(&vfsmount_lock);
        if (root.mnt && root.mnt->mnt_ns)
            ns_root.mnt = mntget(root.mnt->mnt_ns->root);
        if (ns_root.mnt)
            ns_root.dentry = dget(ns_root.mnt->mnt_root);
        spin_unlock(&vfsmount_lock);
        spin_lock(&dcache_lock);
        tmp = ns_root;
        sp = __d_path(path, &tmp, newname, newname_len);
        spin_unlock(&dcache_lock);
        path_put(&root);
        path_put(&ns_root);
    }
    if (IS_ERR(sp)) {
        error = PTR_ERR(sp);
    }
    else {
        error = _xx_encode(newname, sp - newname, sp);
    }
#if 1
    /* Append trailing '/' if dentry is a directory. */
    if (!error && dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)
            && *newname) {
        sp = newname + strlen(newname);
        if (*(sp - 1) != '/') {
            if (sp < newname + newname_len - 4) {
                *sp++ = '/';
                *sp = '\0';
            } else {
                error = -ENOMEM;
            }
        }
    }
#endif
    return error;
}
Exemple #2
0
char *
file_mask_dialog (file_op_context_t * ctx, FileOperation operation,
                  gboolean only_one,
                  const char *format, const void *text, const char *def_text, gboolean * do_bg)
{
    size_t fmd_xlen;
    vfs_path_t *vpath;
    int source_easy_patterns = easy_patterns;
    char fmd_buf[BUF_MEDIUM];
    char *dest_dir, *tmp;
    char *def_text_secure;

    if (ctx == NULL)
        return NULL;

    /* unselect checkbox if target filesystem don't support attributes */
    ctx->op_preserve = filegui__check_attrs_on_fs (def_text);
    ctx->stable_symlinks = FALSE;
    *do_bg = FALSE;

    /* filter out a possible password from def_text */
    vpath = vfs_path_from_str_flags (def_text, only_one ? VPF_NO_CANON : VPF_NONE);
    tmp = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
    vfs_path_free (vpath);

    if (source_easy_patterns)
        def_text_secure = strutils_glob_escape (tmp);
    else
        def_text_secure = strutils_regex_escape (tmp);
    g_free (tmp);

    if (only_one)
    {
        int format_len, text_len;
        int max_len;

        format_len = str_term_width1 (format);
        text_len = str_term_width1 (text);
        max_len = COLS - 2 - 6;

        if (format_len + text_len <= max_len)
        {
            fmd_xlen = format_len + text_len + 6;
            fmd_xlen = max (fmd_xlen, 68);
        }
        else
        {
            text = str_trunc ((const char *) text, max_len - format_len);
            fmd_xlen = max_len + 6;
        }

        g_snprintf (fmd_buf, sizeof (fmd_buf), format, (const char *) text);
    }
    else
    {
        fmd_xlen = COLS * 2 / 3;
        fmd_xlen = max (fmd_xlen, 68);
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, *(const int *) text);
    }

    {
        char *source_mask, *orig_mask;
        int val;
        struct stat buf;

        quick_widget_t quick_widgets[] = {
            /* *INDENT-OFF* */
            QUICK_LABELED_INPUT (fmd_buf, input_label_above,
                                 easy_patterns ? "*" : "^(.*)$", "input-def", &source_mask,
                                 NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
            QUICK_START_COLUMNS,
                QUICK_SEPARATOR (FALSE),
            QUICK_NEXT_COLUMN,
                QUICK_CHECKBOX (N_("&Using shell patterns"), &source_easy_patterns, NULL),
            QUICK_STOP_COLUMNS,
            QUICK_LABELED_INPUT (N_("to:"), input_label_above,
                                 def_text_secure, "input2", &dest_dir, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
            QUICK_SEPARATOR (TRUE),
            QUICK_START_COLUMNS,
                QUICK_CHECKBOX (N_("Follow &links"), &ctx->follow_links, NULL),
                QUICK_CHECKBOX (N_("Preserve &attributes"), &ctx->op_preserve, NULL),
            QUICK_NEXT_COLUMN,
                QUICK_CHECKBOX (N_("Di&ve into subdir if exists"), &ctx->dive_into_subdirs, NULL),
                QUICK_CHECKBOX (N_("&Stable symlinks"), &ctx->stable_symlinks, NULL),
            QUICK_STOP_COLUMNS,
            QUICK_START_BUTTONS (TRUE, TRUE),
                QUICK_BUTTON (N_("&OK"), B_ENTER, NULL, NULL),
#ifdef ENABLE_BACKGROUND
                QUICK_BUTTON (N_("&Background"), B_USER, NULL, NULL),
#endif /* ENABLE_BACKGROUND */
                QUICK_BUTTON (N_("&Cancel"), B_CANCEL, NULL, NULL),
            QUICK_END
            /* *INDENT-ON* */
        };

        quick_dialog_t qdlg = {
            -1, -1, fmd_xlen,
            op_names[operation], "[Mask Copy/Rename]",
            quick_widgets, NULL, NULL
        };

      ask_file_mask:
        val = quick_dialog_skip (&qdlg, 4);

        if (val == B_CANCEL)
        {
            g_free (def_text_secure);
            return NULL;
        }

        if (ctx->follow_links)
            ctx->stat_func = mc_stat;
        else
            ctx->stat_func = mc_lstat;

        if (ctx->op_preserve)
        {
            ctx->preserve = TRUE;
            ctx->umask_kill = 0777777;
            ctx->preserve_uidgid = (geteuid () == 0);
        }
        else
        {
            int i2;

            ctx->preserve = ctx->preserve_uidgid = FALSE;
            i2 = umask (0);
            umask (i2);
            ctx->umask_kill = i2 ^ 0777777;
        }

        if ((dest_dir == NULL) || (*dest_dir == '\0'))
        {
            g_free (def_text_secure);
            g_free (source_mask);
            return dest_dir;
        }

        ctx->search_handle = mc_search_new (source_mask, -1, NULL);

        if (ctx->search_handle == NULL)
        {
            message (D_ERROR, MSG_ERROR, _("Invalid source pattern '%s'"), source_mask);
            g_free (dest_dir);
            g_free (source_mask);
            goto ask_file_mask;
        }

        g_free (def_text_secure);
        g_free (source_mask);

        ctx->search_handle->is_case_sensitive = TRUE;
        if (source_easy_patterns)
            ctx->search_handle->search_type = MC_SEARCH_T_GLOB;
        else
            ctx->search_handle->search_type = MC_SEARCH_T_REGEX;

        tmp = dest_dir;
        dest_dir = tilde_expand (tmp);
        g_free (tmp);
        vpath = vfs_path_from_str (dest_dir);

        ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
        if (ctx->dest_mask == NULL)
            ctx->dest_mask = dest_dir;
        else
            ctx->dest_mask++;
        orig_mask = ctx->dest_mask;
        if (*ctx->dest_mask == '\0'
            || (!ctx->dive_into_subdirs && !is_wildcarded (ctx->dest_mask)
                && (!only_one
                    || (mc_stat (vpath, &buf) == 0 && S_ISDIR (buf.st_mode))))
            || (ctx->dive_into_subdirs
                && ((!only_one && !is_wildcarded (ctx->dest_mask))
                    || (only_one && mc_stat (vpath, &buf) == 0 && S_ISDIR (buf.st_mode)))))
            ctx->dest_mask = g_strdup ("\\0");
        else
        {
            ctx->dest_mask = g_strdup (ctx->dest_mask);
            *orig_mask = '\0';
        }
        if (*dest_dir == '\0')
        {
            g_free (dest_dir);
            dest_dir = g_strdup ("./");
        }
        vfs_path_free (vpath);
        if (val == B_USER)
            *do_bg = TRUE;
    }

    return dest_dir;
}
Exemple #3
0
static void
copy_out_one_file (int handle, dynamic_string *input_name,
		   struct stat *stat_info)
{
  struct new_cpio_header header;
  int input_handle;		/* source file descriptor */
  char *p;

  /* Set values in output header.  */
  header.c_magic = 070707;
  header.c_dev_maj = major (stat_info->st_dev);
  header.c_dev_min = minor (stat_info->st_dev);
  header.c_ino = stat_info->st_ino;
#if DOSWIN
  /* DJGPP doesn't support st_rdev.  Repair that.  */
  stat_info->st_rdev = stat_info->st_dev;
#endif
  /* For POSIX systems that don't define the S_IF macros, we can't assume that
     S_ISfoo means the standard Unix S_IFfoo bit(s) are set.  So do it
     manually, with a different name.  Bleah.  */
  header.c_mode = (stat_info->st_mode & 07777);
  if (S_ISREG (stat_info->st_mode))
    header.c_mode |= CP_IFREG;
  else if (S_ISDIR (stat_info->st_mode))
    header.c_mode |= CP_IFDIR;
#ifdef S_ISBLK
  else if (S_ISBLK (stat_info->st_mode))
    header.c_mode |= CP_IFBLK;
#endif
#ifdef S_ISCHR
  else if (S_ISCHR (stat_info->st_mode))
    header.c_mode |= CP_IFCHR;
#endif
#ifdef S_ISFIFO
  else if (S_ISFIFO (stat_info->st_mode))
    header.c_mode |= CP_IFIFO;
#endif
#ifdef S_ISLNK
  else if (S_ISLNK (stat_info->st_mode))
    header.c_mode |= CP_IFLNK;
#endif
#ifdef S_ISSOCK
  else if (S_ISSOCK (stat_info->st_mode))
    header.c_mode |= CP_IFSOCK;
#endif
#ifdef S_ISNWK
  else if (S_ISNWK (stat_info->st_mode))
    header.c_mode |= CP_IFNWK;
#endif
  header.c_uid = stat_info->st_uid;
  header.c_gid = stat_info->st_gid;
  header.c_nlink = stat_info->st_nlink;
  header.c_rdev_maj = major (stat_info->st_rdev);
  header.c_rdev_min = minor (stat_info->st_rdev);
  header.c_mtime = (stat_info->st_mtime < 0) ? 0 :stat_info->st_mtime;
  header.c_filesize = stat_info->st_size;
  header.c_chksum = 0;
  header.c_tar_linkname = NULL;

  /* Handle HPUX CDF files.  */
  possibly_munge_cdf_directory_name (input_name->string, &header);

  if ((*name_too_long) (header.c_name))
    {
      error (0, 0, _("%s: file name too long"), header.c_name);
      return;
    }

  /* FIXME: there is a memory leak here, between this and the HPUX stuff
     above.  */
  header.c_name = possibly_rename_file (header.c_name);

  /* Copy the named file to the output.  */
  switch (header.c_mode & CP_IFMT)
    {
    case CP_IFREG:
#ifndef __MSDOS__
      if (archive_format == V7_FORMAT || archive_format == POSIX_FORMAT
	  || archive_format == GNUTAR_FORMAT)
	{
	  char *otherfile;
	  if ((otherfile = find_inode_file (header.c_ino,
					    header.c_dev_maj,
					    header.c_dev_min)))
	    {
	      header.c_tar_linkname = otherfile;
	      (*header_writer) (&header, handle);
	      break;
	    }
	}
      if ((archive_format == NEW_ASCII_FORMAT
	   || archive_format == CRC_ASCII_FORMAT)
	  && header.c_nlink > 1)
	if (last_link (&header) )
	  writeout_other_defers (&header, handle);
	else
	  {
	    add_link_defer (&header);
	    break;
	  }
#endif
      input_handle = open (input_name->string,
			  O_RDONLY | O_BINARY, 0);
      if (input_handle < 0)
	{
	  error (0, errno, "%s", input_name->string);
	  return;
	}

      if (archive_format == CRC_ASCII_FORMAT)
	header.c_chksum = read_for_checksum (input_handle,
					     header.c_filesize,
					     input_name->string);

      (*header_writer) (&header, handle);
      copy_files_disk_to_tape (input_handle, handle,
			       header.c_filesize,
			       input_name->string);

#ifndef __MSDOS__
      if (archive_format == V7_FORMAT
	  || archive_format == POSIX_FORMAT
	  || archive_format == GNUTAR_FORMAT)
	add_inode (header.c_ino, header.c_name,
		   header.c_dev_maj, header.c_dev_min);
#endif

      tape_pad_output (handle, header.c_filesize);

      if (close (input_handle) < 0)
	error (0, errno, "%s", input_name->string);
      if (reset_access_time_option)
	{
	  struct utimbuf times;

	  /* Initialize this in case it has members we don't
	     know to set.  */
	  memset (&times, 0, sizeof (struct utimbuf));
	  times.actime = stat_info->st_atime;
	  times.modtime = stat_info->st_mtime;
	  /* Silently ignore EROFS because reading the file won't have upset
	     its timestamp if it's on a read-only filesystem.  */
	  if (utime (header.c_name, &times) < 0 && errno != EROFS)
	    error (0, errno, _("%s: error resetting file access time"),
		   header.c_name);
	}
      break;

    case CP_IFDIR:
      header.c_filesize = 0;
      (*header_writer) (&header, handle);
      break;

#ifndef __MSDOS__
    case CP_IFCHR:
    case CP_IFBLK:
#ifdef CP_IFSOCK
    case CP_IFSOCK:
#endif
#ifdef CP_IFIFO
    case CP_IFIFO:
#endif
      if (archive_format == V7_FORMAT)
	{
	  error (0, 0, _("%s not dumped: not a regular file"), header.c_name);
	  return;
	}
      else if (archive_format == POSIX_FORMAT
	       || archive_format == GNUTAR_FORMAT)
	{
	  char *otherfile
	    = find_inode_file (header.c_ino,
			       header.c_dev_maj, header.c_dev_min);

	  if (otherfile)
	    {
	      /* This file is linked to another file already in the archive,
		 so write it out as a hard link.  */
	      header.c_mode = (stat_info->st_mode & 07777);
	      header.c_mode |= CP_IFREG;
	      header.c_tar_linkname = otherfile;
	      (*header_writer) (&header, handle);
	      break;
	    }
	  add_inode (header.c_ino, header.c_name,
		     header.c_dev_maj, header.c_dev_min);
	}
      header.c_filesize = 0;
      (*header_writer) (&header, handle);
      break;
#endif

#ifdef CP_IFLNK
    case CP_IFLNK:
      {
	char *link_name = (char *) xmalloc (stat_info->st_size + 1);
	int link_size = readlink (input_name->string, link_name,
				  stat_info->st_size);

	if (link_size < 0)
	  {
	    error (0, errno, "%s", input_name->string);
	    free (link_name);
	    return;
	  }
	header.c_filesize = link_size;
	if (archive_format == V7_FORMAT
	    || archive_format == POSIX_FORMAT
	    || archive_format == GNUTAR_FORMAT)
	  {
	    /* FIXME: tar can do long symlinks.  */
	    if (link_size + 1 > 100)
	      error (0, 0, _("%s: symbolic link too long"),
		     header.c_name);
	    else
	      {
		link_name[link_size] = '\0';
		header.c_tar_linkname = link_name;
		(*header_writer) (&header, handle);
	      }
	  }
	else
	  {
	    (*header_writer) (&header, handle);
	    tape_buffered_write (link_name, handle, link_size);
	    tape_pad_output (handle, link_size);
	  }
	free (link_name);
      }
      break;
#endif

    default:
      error (0, 0, _("%s: unknown file type"), input_name->string);
    }

  /* FIXME shouldn't do this for each file.  Should maintain a dstring
     somewhere.  */
  free (header.c_name);
  header.c_name = NULL;
}
int fuse_valid_type(int m)
{
	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
}
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
			     u64 child_nodeid, struct qstr *name)
{
	int err = -ENOTDIR;
	struct inode *parent;
	struct dentry *dir;
	struct dentry *entry;

	parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
	if (!parent)
		return -ENOENT;

	mutex_lock(&parent->i_mutex);
	if (!S_ISDIR(parent->i_mode))
		goto unlock;

	err = -ENOENT;
	dir = d_find_alias(parent);
	if (!dir)
		goto unlock;

	entry = d_lookup(dir, name);
	dput(dir);
	if (!entry)
		goto unlock;

	fuse_invalidate_attr(parent);
	fuse_invalidate_entry(entry);

	if (child_nodeid != 0 && entry->d_inode) {
		mutex_lock(&entry->d_inode->i_mutex);
		if (get_node_id(entry->d_inode) != child_nodeid) {
			err = -ENOENT;
			goto badentry;
		}
		if (d_mountpoint(entry)) {
			err = -EBUSY;
			goto badentry;
		}
		if (S_ISDIR(entry->d_inode->i_mode)) {
			shrink_dcache_parent(entry);
			if (!simple_empty(entry)) {
				err = -ENOTEMPTY;
				goto badentry;
			}
			entry->d_inode->i_flags |= S_DEAD;
		}
		dont_mount(entry);
		clear_nlink(entry->d_inode);
		err = 0;
 badentry:
		mutex_unlock(&entry->d_inode->i_mutex);
		if (!err)
			d_delete(entry);
	} else {
		err = 0;
	}
	dput(entry);

 unlock:
	mutex_unlock(&parent->i_mutex);
	iput(parent);
	return err;
}
static u32 build_default_directory_structure()
{
	u32 inode;
	u32 root_inode;
	struct dentry dentries = {
			.filename = "lost+found",
			.file_type = EXT4_FT_DIR,
			.mode = S_IRWXU,
			.uid = 0,
			.gid = 0,
			.mtime = 0,
	};
	root_inode = make_directory(0, 1, &dentries, 1);
	inode = make_directory(root_inode, 0, NULL, 0);
	*dentries.inode = inode;
	inode_set_permissions(inode, dentries.mode,
		dentries.uid, dentries.gid, dentries.mtime);

	return root_inode;
}

#ifndef USE_MINGW
/* Read a local directory and create the same tree in the generated filesystem.
   Calls itself recursively with each directory in the given directory.
   full_path is an absolute or relative path, with a trailing slash, to the
   directory on disk that should be copied, or NULL if this is a directory
   that does not exist on disk (e.g. lost+found).
   dir_path is an absolute path, with trailing slash, to the same directory
   if the image were mounted at the specified mount point */
static u32 build_directory_structure(const char *full_path, const char *dir_path,
		u32 dir_inode, fs_config_func_t fs_config_func,
		struct selabel_handle *sehnd, int verbose)
{
	int entries = 0;
	struct dentry *dentries;
	struct dirent **namelist = NULL;
	struct stat stat;
	int ret;
	int i;
	u32 inode;
	u32 entry_inode;
	u32 dirs = 0;
	bool needs_lost_and_found = false;

	if (full_path) {
		entries = scandir(full_path, &namelist, filter_dot, (void*)alphasort);
		if (entries < 0) {
			error_errno("scandir");
			return EXT4_ALLOCATE_FAILED;
		}
	}

	if (dir_inode == 0) {
		/* root directory, check if lost+found already exists */
		for (i = 0; i < entries; i++)
			if (strcmp(namelist[i]->d_name, "lost+found") == 0)
				break;
		if (i == entries)
			needs_lost_and_found = true;
	}

	dentries = calloc(entries, sizeof(struct dentry));
	if (dentries == NULL)
		critical_error_errno("malloc");

	for (i = 0; i < entries; i++) {
		dentries[i].filename = strdup(namelist[i]->d_name);
		if (dentries[i].filename == NULL)
			critical_error_errno("strdup");

		asprintf(&dentries[i].path, "%s%s", dir_path, namelist[i]->d_name);
		asprintf(&dentries[i].full_path, "%s%s", full_path, namelist[i]->d_name);

		free(namelist[i]);

		ret = lstat(dentries[i].full_path, &stat);
		if (ret < 0) {
			error_errno("lstat");
			i--;
			entries--;
			continue;
		}

		dentries[i].size = stat.st_size;
		dentries[i].mode = stat.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
		dentries[i].mtime = stat.st_mtime;
		uint64_t capabilities;
		if (fs_config_func != NULL) {
#ifdef ANDROID
			unsigned int mode = 0;
			unsigned int uid = 0;
			unsigned int gid = 0;
			int dir = S_ISDIR(stat.st_mode);
			fs_config_func(dentries[i].path, dir, &uid, &gid, &mode, &capabilities);
			dentries[i].mode = mode;
			dentries[i].uid = uid;
			dentries[i].gid = gid;
			dentries[i].capabilities = capabilities;
#else
			error("can't set android permissions - built without android support");
#endif
		}
#ifndef USE_MINGW
		if (sehnd) {
			if (selabel_lookup(sehnd, &dentries[i].secon, dentries[i].path, stat.st_mode) < 0) {
				error("cannot lookup security context for %s", dentries[i].path);
			}

			if (dentries[i].secon && verbose)
				printf("Labeling %s as %s\n", dentries[i].path, dentries[i].secon);
		}
#endif

		if (S_ISREG(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_REG_FILE;
		} else if (S_ISDIR(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_DIR;
			dirs++;
		} else if (S_ISCHR(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_CHRDEV;
		} else if (S_ISBLK(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_BLKDEV;
		} else if (S_ISFIFO(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_FIFO;
		} else if (S_ISSOCK(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_SOCK;
		} else if (S_ISLNK(stat.st_mode)) {
			dentries[i].file_type = EXT4_FT_SYMLINK;
			dentries[i].link = calloc(info.block_size, 1);
			readlink(dentries[i].full_path, dentries[i].link, info.block_size - 1);
		} else {
			error("unknown file type on %s", dentries[i].path);
			i--;
			entries--;
		}
	}
	free(namelist);

	if (needs_lost_and_found) {
		/* insert a lost+found directory at the beginning of the dentries */
		struct dentry *tmp = calloc(entries + 1, sizeof(struct dentry));
		memset(tmp, 0, sizeof(struct dentry));
		memcpy(tmp + 1, dentries, entries * sizeof(struct dentry));
		dentries = tmp;

		dentries[0].filename = strdup("lost+found");
		asprintf(&dentries[0].path, "%slost+found", dir_path);
		dentries[0].full_path = NULL;
		dentries[0].size = 0;
		dentries[0].mode = S_IRWXU;
		dentries[0].file_type = EXT4_FT_DIR;
		dentries[0].uid = 0;
		dentries[0].gid = 0;
		if (sehnd) {
			if (selabel_lookup(sehnd, &dentries[0].secon, dentries[0].path, dentries[0].mode) < 0)
				error("cannot lookup security context for %s", dentries[0].path);
		}
		entries++;
		dirs++;
	}

	inode = make_directory(dir_inode, entries, dentries, dirs);

	for (i = 0; i < entries; i++) {
		if (dentries[i].file_type == EXT4_FT_REG_FILE) {
			entry_inode = make_file(dentries[i].full_path, dentries[i].size);
		} else if (dentries[i].file_type == EXT4_FT_DIR) {
			char *subdir_full_path = NULL;
			char *subdir_dir_path;
			if (dentries[i].full_path) {
				ret = asprintf(&subdir_full_path, "%s/", dentries[i].full_path);
				if (ret < 0)
					critical_error_errno("asprintf");
			}
			ret = asprintf(&subdir_dir_path, "%s/", dentries[i].path);
			if (ret < 0)
				critical_error_errno("asprintf");
			entry_inode = build_directory_structure(subdir_full_path,
					subdir_dir_path, inode, fs_config_func, sehnd, verbose);
			free(subdir_full_path);
			free(subdir_dir_path);
		} else if (dentries[i].file_type == EXT4_FT_SYMLINK) {
			entry_inode = make_link(dentries[i].link);
		} else {
			error("unknown file type on %s", dentries[i].path);
			entry_inode = 0;
		}
		*dentries[i].inode = entry_inode;

		ret = inode_set_permissions(entry_inode, dentries[i].mode,
			dentries[i].uid, dentries[i].gid,
			dentries[i].mtime);
		if (ret)
			error("failed to set permissions on %s\n", dentries[i].path);

		/*
		 * It's important to call inode_set_selinux() before
		 * inode_set_capabilities(). Extended attributes need to
		 * be stored sorted order, and we guarantee this by making
		 * the calls in the proper order.
		 * Please see xattr_assert_sane() in contents.c
		 */
		ret = inode_set_selinux(entry_inode, dentries[i].secon);
		if (ret)
			error("failed to set SELinux context on %s\n", dentries[i].path);
		ret = inode_set_capabilities(entry_inode, dentries[i].capabilities);
		if (ret)
			error("failed to set capability on %s\n", dentries[i].path);

		free(dentries[i].path);
		free(dentries[i].full_path);
		free(dentries[i].link);
		free((void *)dentries[i].filename);
		free(dentries[i].secon);
	}

	free(dentries);
	return inode;
}
Exemple #7
0
DIR *
__opendir2(const char *name, int flags)
{
  DIR *dirp = NULL;
  int fd;
  int serrno;
  struct stat sb;
  int incr;

  _DIAGASSERT(name != NULL);

  if ((fd = open(name, O_RDONLY | O_NONBLOCK, 0)) == -1 ||
      fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
    goto error;
  if (fstat(fd, &sb) || !S_ISDIR(sb.st_mode)) {
    errno = ENOTDIR;
    goto error;
  }
  if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL)
    goto error;
  dirp->dd_buf = NULL;

  /*
   * If the machine's page size is an exact multiple of DIRBLKSIZ,
   * use a buffer that is cluster boundary aligned.
   * Hopefully this can be a big win someday by allowing page trades
   * to user space to be done by getdirentries()
   */
  incr = DIRBLKSIZ;

  dirp->dd_len = incr;
  dirp->dd_buf = malloc((size_t)dirp->dd_len);
  if (dirp->dd_buf == NULL)
    goto error;
  dirp->dd_seek = 0;
  flags &= ~DTF_REWIND;

  dirp->dd_loc = 0;
  dirp->dd_fd = fd;
  dirp->dd_flags = flags;

  /*
   * Set up seek point for rewinddir.
   */
#ifdef _REENTRANT
  if (__isthreaded) {
    if ((dirp->dd_lock = malloc(sizeof(mutex_t))) == NULL)
      goto error;
    mutex_init((mutex_t *)dirp->dd_lock, NULL);
  }
#endif
  dirp->dd_internal = NULL;
  return (dirp);
error:
  serrno = errno;
  if (dirp && dirp->dd_buf)
    free(dirp->dd_buf);
  if (dirp)
    free(dirp);
  if (fd != -1)
    (void)close(fd);
  errno = serrno;
  return NULL;
}
Exemple #8
0
int main (int argc, char* argv[]){
	
	if (argc!=2){
		fprintf(stderr, "Error: Expected 1 parameter.\n"
				"Usage: %s <pathname>\n", argv[0]);
		return(EXIT_FAILURE);
	}
	
	DIR* FD1;
	struct dirent* in_file;
	list lista = NULL;
	list scan,head;
	unsigned char c[MD5_DIGEST_LENGTH];
	struct stat statbuf;

	
	FILE *f;
	int i;
	
	chdir(argv[1]);
	
	if (NULL == (FD1 = opendir ("."))){
		fprintf(stderr, "Error : Failed to open directory - %s\n", strerror(errno));
		return -1;
	}
	
	while ((in_file = readdir(FD1))){
		if(!strncmp(in_file->d_name,".",1)) continue;							//ignoro file nascosti
		stat(in_file->d_name, &statbuf);
		if(S_ISDIR(statbuf.st_mode)) continue;									//ignoro le directory
		f = fopen (in_file->d_name, "rb");
		insert(&lista, in_file->d_name, f);
		for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", lista->hash[i]);

		printf(" %s\n",lista->name);
		
	}
	head=lista;
	while(lista!=NULL){
		scan=lista;
		while(scan!=NULL){
			if(!strcmp(lista->hash,scan->next->hash)){
				printf("Same hash!\n");
				if(equal(lista->name,scan->next->name)){
					printf("And they are also the same file!!\n");
					link(lista->name,scan->next->name);
					printf("Removing %s from the list\n",scan->next->name);
					removelem(&scan->next);
				}
			}
			else scan=scan->next;
		}
		lista=lista->next;
	}
	
	while(head!=NULL){
		printf("%s\n", head->name);
	}
	
	
	return 0;
}
Exemple #9
0
static int dev_create(char *root, dev_res *dev)
{
	char buf1[STR_SIZE];
	char buf2[STR_SIZE];
	struct stat st, st2;
	int ret;
	const char* udev_paths[] = {
		"/lib/udev/devices",
		"/etc/udev/devices",
		NULL};
	int i;

	if (!dev->name[0])
		return 0;
	if (check_var(root, "VE_ROOT is not set"))
		return VZ_VE_ROOT_NOTSET;
	/* If device does not exist inside CT get
	* information from CT0 and create it
	*/
	snprintf(buf1, sizeof(buf1), "%s/dev/%s", root, dev->name);
	ret = lstat(buf1, &st);
	if (ret && errno != ENOENT) {
		logger(-1, errno, "Unable to stat device %s", buf1);
		return VZ_SET_DEVICES;
	} else if (!ret)
		return 0;
	snprintf(buf2, sizeof(buf2), "/dev/%s", dev->name);
	if (stat(buf2, &st)) {
		if (errno == ENOENT)
			logger(-1, 0, "Incorrect name or no such device %s",
				buf2);
		else
			logger(-1, errno, "Unable to stat device %s", buf2);
		return VZ_SET_DEVICES;
	}
	if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
		logger(-1, 0, "The %s is not block or character device", buf2);
		return VZ_SET_DEVICES;
	}
	if (make_dir(buf1, 0))
		return VZ_SET_DEVICES;
	if (mknod(buf1, st.st_mode, st.st_rdev)) {
		logger(-1, errno, "Unable to create device %s", buf1);
		return VZ_SET_DEVICES;
	}
	/* Try to create static device node for udev */
	for (i = 0; udev_paths[i] != NULL; i++) {
		if (stat(udev_paths[i], &st2) == 0) {
			if (S_ISDIR(st2.st_mode)) {
				snprintf(buf1, sizeof(buf1),
						"%s/%s/%s",
						root, udev_paths[i],
						dev->name);
				make_dir(buf1, 0);
				mknod(buf1, st.st_mode, st.st_rdev);
				break;
			}
		}
	}
	return 0;
}
int LocalFilesRecursiveDir (
	struct collectionFormat *collection,
        int (*documentExist)(struct collectionFormat *collection,struct crawldocumentExistFormat *crawldocumentExist),
        int (*documentAdd)(struct collectionFormat *collection,struct crawldocumentAddFormat *crawldocumentAdd),
	char prefix[],
	char dirname[],
	int accessmode ) {


	//char *dokument_buff = malloc(_dokument_buff_size +1);
	char *dokument_buff;

	printf("opening dir \"%s\", prefix %s\n",dirname,prefix);

	DIR *DIRH;
	struct dirent *dp;
	char nextdirname[512];
	char filname[512];
	char lotinternfilname[512];
	FILE *FH;
	struct stat inode;      // lager en struktur for fstat å returnere.
	int dokument_size;
	int diraccessmode;
	int filecessmode;
	struct passwd *pw;
	struct group  *gp;
	//char acl[4][64];
	char acl[3 * 64];
	int count;
	char uri[512];

	struct crawldocumentExistFormat crawldocumentExist;
        struct crawldocumentAddFormat crawldocumentAdd;

	if (stat(dirname,&inode) != 0) {
		perror("stat");
		return 0;
	}
	//har ownaccessmode som den laveste i hele pathen
	int ownaccessmode = inode.st_mode & accessmode;
	
	if ((DIRH = opendir(dirname)) == NULL) {
		perror(dirname);	
		return;
	}	
	
	while ((dp = readdir(DIRH)) != NULL) {

		sprintf(nextdirname,"%s/%s",dirname,dp->d_name);

		if (stat(nextdirname,&inode) != 0) {
			perror("fstat");
			continue;
		}


		if (dp->d_name[0] == '.') {
			printf(". domain (\"%s\")\n",dp->d_name);
		}
		//else if (dp->d_type == DT_DIR) {
		else if (S_ISDIR(inode.st_mode)) {

			sprintf(nextdirname,"%s/%s",dirname,dp->d_name);
			printf("dir (nextdirname %s)\n",nextdirname);

			//kaller seg selv rekurift
			LocalFilesRecursiveDir(collection,documentExist,documentAdd,prefix,nextdirname,ownaccessmode);
		}
		//else if (dp->d_type == DT_REG) {
		else if (S_ISREG(inode.st_mode)) {
			sprintf(filname,"%s/%s",dirname,dp->d_name);
			snprintf(uri,sizeof(uri),"%s/%s",prefix,filname);
			//sprintf(lotinternfilname,"%s%s",lotinternpath,dp->d_name);
			printf("file %s\n",filname);	

			//rSendFile(filname,lotinternfilname,lotNr, "w",subname);
			if ((FH = fopen(filname,"rb")) == NULL) {
				perror(filname);
				//exit(1);
				continue;
			}
			


			crawldocumentExist.documenturi = uri;
                        crawldocumentExist.lastmodified = inode.st_mtime;
                        crawldocumentExist.dokument_size = inode.st_size;


			//spør Boitho om filområdet finnes
			//if (!(documentExist)(collection, &crawldocumentExist ) ) {
				dokument_size = inode.st_size;
				dokument_buff = malloc(dokument_size +1);

				printf("uid %i, gid %i\n",inode.st_uid,inode.st_gid);
				//lager acl
				acl[0] = '\0';
				filecessmode = ownaccessmode & inode.st_mode;
				printf("mode %i\n",(int)inode.st_mode);
				if (filecessmode & S_IRUSR) {
					printf("ovner have read permission. S_IRUSR %i\n",inode.st_mode & S_IRUSR);
					//find username and appendit
					if ((pw = getpwuid(inode.st_uid)) == NULL) {
						printf("unknown user id %i\n",inode.st_uid);
					}
					else {
						printf("user name is %s\n",pw->pw_name);
						//strcmp(acl[nrofacls++],pw->pw_name);
						strcat(acl,pw->pw_name);
						strcat(acl,",");
					}
				}
				if (filecessmode & S_IRGRP) {
					printf("group have read permission. S_IRGRP %i\n",inode.st_mode & S_IRGRP);
					if ((gp = getgrgid(inode.st_gid)) == NULL) {
						printf("unknown group id %i\n",inode.st_gid);
					}
					else {
						printf("group is %s\n",gp->gr_name);					
						//strcmp(acl[nrofacls++],gp->gr_name);
						strcat(acl,gp->gr_name);
						strcat(acl,",");

					}
				}
				if (filecessmode & S_IROTH) {
					printf("others have read permission. S_IROTH %i\n",inode.st_mode & S_IROTH);
					//strcmp(acl[nrofacls++],"EVERYONE");
					strcat(acl,"Everyone"); //toDo bruker msad sin gruppe fro alle her. Bør kansje ha en engen??
					strcat(acl,",");

				}
				//uefektift, bruker strlen() to ganger
				if (acl[strlen(acl)] == ',') {
					acl[strlen(acl)] = '\0';
				}				

				//leser hele dokumentet
				fread(dokument_buff,sizeof(char),dokument_size,FH);


				crawldocumentAdd.documenturi    = uri;
                                crawldocumentAdd.documenttype   = "";
                                crawldocumentAdd.document       = dokument_buff;
                                crawldocumentAdd.dokument_size  = dokument_size;
                                crawldocumentAdd.lastmodified   = inode.st_mtime;
                                crawldocumentAdd.acl            = acl;
                                crawldocumentAdd.title          = dp->d_name;
                                crawldocumentAdd.doctype        = "";

				printf("\tdokument_size \"%i\"\n",dokument_size);

                                (*documentAdd)(collection ,&crawldocumentAdd);


				//bbdn_docadd(bbdh,collection,filname,"",dokument_buff,dokument_size,(unsigned int)inode.st_mtime,acl,dp->d_name,"");
				free(dokument_buff);
			//}

			fclose(FH);
		}
		else {
			printf("unknown type %i. Name \"%s\"\n",inode.st_mode,dp->d_name);
		}
		//printf("%s %i\n",dp->d_name,dp->d_type);

	}

	closedir(DIRH);

}
Exemple #11
0
/*
 * RENAME
 * FIXME: Some nfsds, like the Linux user space nfsd, may generate a
 * different file handle for the same inode after a rename (e.g. when
 * moving to a different directory). A fail-safe method to do so would
 * be to look up old_dir/old_name, create a link to new_dir/new_name and
 * rename the old file using the sillyrename stuff. This way, the original
 * file in old_dir will go away when the last process iput()s the inode.
 *
 * FIXED.
 * 
 * It actually works quite well. One needs to have the possibility for
 * at least one ".nfs..." file in each directory the file ever gets
 * moved or linked to which happens automagically with the new
 * implementation that only depends on the dcache stuff instead of
 * using the inode layer
 *
 * Unfortunately, things are a little more complicated than indicated
 * above. For a cross-directory move, we want to make sure we can get
 * rid of the old inode after the operation.  This means there must be
 * no pending writes (if it's a file), and the use count must be 1.
 * If these conditions are met, we can drop the dentries before doing
 * the rename.
 */
static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
		      struct inode *new_dir, struct dentry *new_dentry)
{
	struct inode *old_inode = old_dentry->d_inode;
	struct inode *new_inode = new_dentry->d_inode;
	struct dentry *dentry = NULL, *rehash = NULL;
	int error = -EBUSY;

	/*
	 * To prevent any new references to the target during the rename,
	 * we unhash the dentry and free the inode in advance.
	 */
	if (!d_unhashed(new_dentry)) {
		d_drop(new_dentry);
		rehash = new_dentry;
	}

	dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
		 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
		 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
		 atomic_read(&new_dentry->d_count));

	/*
	 * First check whether the target is busy ... we can't
	 * safely do _any_ rename if the target is in use.
	 *
	 * For files, make a copy of the dentry and then do a 
	 * silly-rename. If the silly-rename succeeds, the
	 * copied dentry is hashed and becomes the new target.
	 */
	if (!new_inode)
		goto go_ahead;
	if (S_ISDIR(new_inode->i_mode))
		goto out;
	else if (atomic_read(&new_dentry->d_count) > 1) {
		int err;
		/* copy the target dentry's name */
		dentry = d_alloc(new_dentry->d_parent,
				 &new_dentry->d_name);
		if (!dentry)
			goto out;

		/* silly-rename the existing target ... */
		err = nfs_sillyrename(new_dir, new_dentry);
		if (!err) {
			new_dentry = rehash = dentry;
			new_inode = NULL;
			/* instantiate the replacement target */
			d_instantiate(new_dentry, NULL);
		}

		/* dentry still busy? */
		if (atomic_read(&new_dentry->d_count) > 1) {
#ifdef NFS_PARANOIA
			printk("nfs_rename: target %s/%s busy, d_count=%d\n",
			       new_dentry->d_parent->d_name.name,
			       new_dentry->d_name.name,
			       atomic_read(&new_dentry->d_count));
#endif
			goto out;
		}
	}

go_ahead:
	/*
	 * ... prune child dentries and writebacks if needed.
	 */
	if (atomic_read(&old_dentry->d_count) > 1) {
		nfs_wb_all(old_inode);
		shrink_dcache_parent(old_dentry);
	}

	if (new_inode)
		d_delete(new_dentry);

	nfs_zap_caches(new_dir);
	nfs_zap_caches(old_dir);
	error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
					   new_dir, &new_dentry->d_name);
out:
	if (rehash)
		d_rehash(rehash);
	if (!error && !S_ISDIR(old_inode->i_mode))
		d_move(old_dentry, new_dentry);

	/* new dentry created? */
	if (dentry)
		dput(dentry);
	return error;
}
static int
acl_backend_vfile_read(struct acl_object *aclobj, bool global, const char *path,
		       struct acl_vfile_validity *validity, bool try_retry,
		       bool *is_dir_r)
{
	struct istream *input;
	struct stat st;
	struct acl_rights rights;
	const char *line, *error;
	unsigned int linenum;
	int fd, ret = 0;

	*is_dir_r = FALSE;

	fd = nfs_safe_open(path, O_RDONLY);
	if (fd == -1) {
		if (errno == ENOENT || errno == ENOTDIR) {
			if (aclobj->backend->debug)
				i_debug("acl vfile: file %s not found", path);
			validity->last_mtime = ACL_VFILE_VALIDITY_MTIME_NOTFOUND;
		} else if (errno == EACCES) {
			if (aclobj->backend->debug)
				i_debug("acl vfile: no access to file %s",
					path);

			acl_object_remove_all_access(aclobj);
			validity->last_mtime = ACL_VFILE_VALIDITY_MTIME_NOACCESS;
		} else {
			i_error("open(%s) failed: %m", path);
			return -1;
		}

		validity->last_size = 0;
		validity->last_read_time = ioloop_time;
		return 1;
	}

	if (fstat(fd, &st) < 0) {
		if (errno == ESTALE && try_retry) {
			i_close_fd(&fd);
			return 0;
		}

		i_error("fstat(%s) failed: %m", path);
		i_close_fd(&fd);
		return -1;
	}
	if (S_ISDIR(st.st_mode)) {
		/* we opened a directory. */
		*is_dir_r = TRUE;
		i_close_fd(&fd);
		return 0;
	}

	if (aclobj->backend->debug)
		i_debug("acl vfile: reading file %s", path);

	input = i_stream_create_fd(fd, (size_t)-1, FALSE);
	i_stream_set_return_partial_line(input, TRUE);
	linenum = 1;
	while ((line = i_stream_read_next_line(input)) != NULL) {
		T_BEGIN {
			ret = acl_rights_parse_line(line, aclobj->rights_pool,
						    &rights, &error);
			rights.global = global;
			if (ret < 0) {
				i_error("ACL file %s line %u: %s",
					path, linenum, error);
			} else {
				array_append(&aclobj->rights, &rights, 1);
			}
		} T_END;
		if (ret < 0)
			break;
		linenum++;
	}

	if (ret < 0) {
		/* parsing failure */
	} else if (input->stream_errno != 0) {
		if (input->stream_errno == ESTALE && try_retry)
			ret = 0;
		else {
			ret = -1;
			i_error("read(%s) failed: %m", path);
		}
	} else {
		if (fstat(fd, &st) < 0) {
			if (errno == ESTALE && try_retry)
				ret = 0;
			else {
				ret = -1;
				i_error("fstat(%s) failed: %m", path);
			}
		} else {
			ret = 1;
			validity->last_read_time = ioloop_time;
			validity->last_mtime = st.st_mtime;
			validity->last_size = st.st_size;
		}
	}

	i_stream_unref(&input);
	if (close(fd) < 0) {
		if (errno == ESTALE && try_retry)
			return 0;

		i_error("close(%s) failed: %m", path);
		return -1;
	}
	return ret;
}
Exemple #13
0
/*
 * new path should be added to combine diff
 *
 * 3 cases on how/when it should be called and behaves:
 *
 *	 t, !tp		-> path added, all parents lack it
 *	!t,  tp		-> path removed from all parents
 *	 t,  tp		-> path modified/added
 *			   (M for tp[i]=tp[imin], A otherwise)
 */
static struct combine_diff_path *emit_path(struct combine_diff_path *p,
	struct strbuf *base, struct diff_options *opt, int nparent,
	struct tree_desc *t, struct tree_desc *tp,
	int imin)
{
	unsigned mode;
	const char *path;
	const unsigned char *sha1;
	int pathlen;
	int old_baselen = base->len;
	int i, isdir, recurse = 0, emitthis = 1;

	/* at least something has to be valid */
	assert(t || tp);

	if (t) {
		/* path present in resulting tree */
		sha1 = tree_entry_extract(t, &path, &mode);
		pathlen = tree_entry_len(&t->entry);
		isdir = S_ISDIR(mode);
	} else {
		/*
		 * a path was removed - take path from imin parent. Also take
		 * mode from that parent, to decide on recursion(1).
		 *
		 * 1) all modes for tp[i]=tp[imin] should be the same wrt
		 *    S_ISDIR, thanks to base_name_compare().
		 */
		tree_entry_extract(&tp[imin], &path, &mode);
		pathlen = tree_entry_len(&tp[imin].entry);

		isdir = S_ISDIR(mode);
		sha1 = NULL;
		mode = 0;
	}

	if (DIFF_OPT_TST(opt, RECURSIVE) && isdir) {
		recurse = 1;
		emitthis = DIFF_OPT_TST(opt, TREE_IN_RECURSIVE);
	}

	if (emitthis) {
		int keep;
		struct combine_diff_path *pprev = p;
		p = path_appendnew(p, nparent, base, path, pathlen, mode, sha1);

		for (i = 0; i < nparent; ++i) {
			/*
			 * tp[i] is valid, if present and if tp[i]==tp[imin] -
			 * otherwise, we should ignore it.
			 */
			int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);

			const unsigned char *sha1_i;
			unsigned mode_i;

			p->parent[i].status =
				!t ? DIFF_STATUS_DELETED :
					tpi_valid ?
						DIFF_STATUS_MODIFIED :
						DIFF_STATUS_ADDED;

			if (tpi_valid) {
				sha1_i = tp[i].entry.sha1;
				mode_i = tp[i].entry.mode;
			}
			else {
				sha1_i = NULL;
				mode_i = 0;
			}

			p->parent[i].mode = mode_i;
			hashcpy(p->parent[i].oid.hash, sha1_i ? sha1_i : null_sha1);
		}

		keep = 1;
		if (opt->pathchange)
			keep = opt->pathchange(opt, p);

		/*
		 * If a path was filtered or consumed - we don't need to add it
		 * to the list and can reuse its memory, leaving it as
		 * pre-allocated element on the tail.
		 *
		 * On the other hand, if path needs to be kept, we need to
		 * correct its .next to NULL, as it was pre-initialized to how
		 * much memory was allocated.
		 *
		 * see path_appendnew() for details.
		 */
		if (!keep)
			p = pprev;
		else
			p->next = NULL;
	}

	if (recurse) {
		const unsigned char **parents_sha1;

		parents_sha1 = xalloca(nparent * sizeof(parents_sha1[0]));
		for (i = 0; i < nparent; ++i) {
			/* same rule as in emitthis */
			int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);

			parents_sha1[i] = tpi_valid ? tp[i].entry.sha1
						    : NULL;
		}

		strbuf_add(base, path, pathlen);
		strbuf_addch(base, '/');
		p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
		xalloca_free(parents_sha1);
	}

	strbuf_setlen(base, old_baselen);
	return p;
}
Exemple #14
0
int runsv_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
    struct stat s;
    int fd;
    int r;
    char buf[256];

    INIT_G();

    if (!argv[1] || argv[2])
        bb_show_usage();
    dir = argv[1];

    xpiped_pair(selfpipe);
    close_on_exec_on(selfpipe.rd);
    close_on_exec_on(selfpipe.wr);
    ndelay_on(selfpipe.rd);
    ndelay_on(selfpipe.wr);

    sig_block(SIGCHLD);
    bb_signals_recursive(1 << SIGCHLD, s_child);
    sig_block(SIGTERM);
    bb_signals_recursive(1 << SIGTERM, s_term);

    xchdir(dir);
    /* bss: svd[0].pid = 0; */
    if (S_DOWN) svd[0].state = S_DOWN; /* otherwise already 0 (bss) */
    if (C_NOOP) svd[0].ctrl = C_NOOP;
    if (W_UP) svd[0].want = W_UP;
    /* bss: svd[0].islog = 0; */
    /* bss: svd[1].pid = 0; */
    gettimeofday_ns(&svd[0].start);
    if (stat("down", &s) != -1) svd[0].want = W_DOWN;

    if (stat("log", &s) == -1) {
        if (errno != ENOENT)
            warn_cannot("stat ./log");
    } else {
        if (!S_ISDIR(s.st_mode)) {
            errno = 0;
            warn_cannot("stat log/down: log is not a directory");
        } else {
            haslog = 1;
            svd[1].state = S_DOWN;
            svd[1].ctrl = C_NOOP;
            svd[1].want = W_UP;
            svd[1].islog = 1;
            gettimeofday_ns(&svd[1].start);
            if (stat("log/down", &s) != -1)
                svd[1].want = W_DOWN;
            xpiped_pair(logpipe);
            close_on_exec_on(logpipe.rd);
            close_on_exec_on(logpipe.wr);
        }
    }

    if (mkdir("supervise", 0700) == -1) {
        r = readlink("supervise", buf, sizeof(buf));
        if (r != -1) {
            if (r == sizeof(buf))
                fatal2x_cannot("readlink ./supervise", ": name too long");
            buf[r] = 0;
            mkdir(buf, 0700);
        } else {
            if ((errno != ENOENT) && (errno != EINVAL))
                fatal_cannot("readlink ./supervise");
        }
    }
    svd[0].fdlock = xopen3("log/supervise/lock"+4,
                           O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
    if (lock_exnb(svd[0].fdlock) == -1)
        fatal_cannot("lock supervise/lock");
    close_on_exec_on(svd[0].fdlock);
    if (haslog) {
        if (mkdir("log/supervise", 0700) == -1) {
            r = readlink("log/supervise", buf, 256);
            if (r != -1) {
                if (r == 256)
                    fatal2x_cannot("readlink ./log/supervise", ": name too long");
                buf[r] = 0;
                fd = xopen(".", O_RDONLY|O_NDELAY);
                xchdir("./log");
                mkdir(buf, 0700);
                if (fchdir(fd) == -1)
                    fatal_cannot("change back to service directory");
                close(fd);
            }
            else {
                if ((errno != ENOENT) && (errno != EINVAL))
                    fatal_cannot("readlink ./log/supervise");
            }
        }
        svd[1].fdlock = xopen3("log/supervise/lock",
                               O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
        if (lock_ex(svd[1].fdlock) == -1)
            fatal_cannot("lock log/supervise/lock");
        close_on_exec_on(svd[1].fdlock);
    }

    mkfifo("log/supervise/control"+4, 0600);
    svd[0].fdcontrol = xopen("log/supervise/control"+4, O_RDONLY|O_NDELAY);
    close_on_exec_on(svd[0].fdcontrol);
    svd[0].fdcontrolwrite = xopen("log/supervise/control"+4, O_WRONLY|O_NDELAY);
    close_on_exec_on(svd[0].fdcontrolwrite);
    update_status(&svd[0]);
    if (haslog) {
        mkfifo("log/supervise/control", 0600);
        svd[1].fdcontrol = xopen("log/supervise/control", O_RDONLY|O_NDELAY);
        close_on_exec_on(svd[1].fdcontrol);
        svd[1].fdcontrolwrite = xopen("log/supervise/control", O_WRONLY|O_NDELAY);
        close_on_exec_on(svd[1].fdcontrolwrite);
        update_status(&svd[1]);
    }
    mkfifo("log/supervise/ok"+4, 0600);
    fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY);
    close_on_exec_on(fd);
    if (haslog) {
        mkfifo("log/supervise/ok", 0600);
        fd = xopen("log/supervise/ok", O_RDONLY|O_NDELAY);
        close_on_exec_on(fd);
    }
    for (;;) {
        struct pollfd x[3];
        unsigned deadline;
        char ch;

        if (haslog)
            if (!svd[1].pid && svd[1].want == W_UP)
                startservice(&svd[1]);
        if (!svd[0].pid)
            if (svd[0].want == W_UP || svd[0].state == S_FINISH)
                startservice(&svd[0]);

        x[0].fd = selfpipe.rd;
        x[0].events = POLLIN;
        x[1].fd = svd[0].fdcontrol;
        x[1].events = POLLIN;
        /* x[2] is used only if haslog == 1 */
        x[2].fd = svd[1].fdcontrol;
        x[2].events = POLLIN;
        sig_unblock(SIGTERM);
        sig_unblock(SIGCHLD);
        poll(x, 2 + haslog, 3600*1000);
        sig_block(SIGTERM);
        sig_block(SIGCHLD);

        while (read(selfpipe.rd, &ch, 1) == 1)
            continue;

        for (;;) {
            int child;
            int wstat;

            child = wait_any_nohang(&wstat);
            if (!child)
                break;
            if ((child == -1) && (errno != EINTR))
                break;
            if (child == svd[0].pid) {
                svd[0].pid = 0;
                pidchanged = 1;
                svd[0].ctrl &=~ C_TERM;
                if (svd[0].state != S_FINISH) {
                    fd = open_read("finish");
                    if (fd != -1) {
                        close(fd);
                        svd[0].state = S_FINISH;
                        update_status(&svd[0]);
                        continue;
                    }
                }
                svd[0].state = S_DOWN;
                deadline = svd[0].start.tv_sec + 1;
                gettimeofday_ns(&svd[0].start);
                update_status(&svd[0]);
                if (LESS(svd[0].start.tv_sec, deadline))
                    sleep(1);
            }
            if (haslog) {
                if (child == svd[1].pid) {
                    svd[1].pid = 0;
                    pidchanged = 1;
                    svd[1].state = S_DOWN;
                    svd[1].ctrl &= ~C_TERM;
                    deadline = svd[1].start.tv_sec + 1;
                    gettimeofday_ns(&svd[1].start);
                    update_status(&svd[1]);
                    if (LESS(svd[1].start.tv_sec, deadline))
                        sleep(1);
                }
            }
        } /* for (;;) */
        if (read(svd[0].fdcontrol, &ch, 1) == 1)
            ctrl(&svd[0], ch);
        if (haslog)
            if (read(svd[1].fdcontrol, &ch, 1) == 1)
                ctrl(&svd[1], ch);

        if (sigterm) {
            ctrl(&svd[0], 'x');
            sigterm = 0;
        }

        if (svd[0].want == W_EXIT && svd[0].state == S_DOWN) {
            if (svd[1].pid == 0)
                _exit(0);
            if (svd[1].want != W_EXIT) {
                svd[1].want = W_EXIT;
                /* stopservice(&svd[1]); */
                update_status(&svd[1]);
                close(logpipe.wr);
                close(logpipe.rd);
            }
        }
    } /* for (;;) */
    /* not reached */
    return 0;
}
Exemple #15
0
char* menu_browsedir(char* fpathname, char* file, char *title, char *exts){
    /* this routine has side effects with fpathname and file, FIXME */
	DIR *dir;
	struct dirent *d;
	int n=0, i, j;
	char *files[1<<16];  /* 256Kb */
#ifndef  DT_DIR
	struct stat s;
	char tmpfname[PATH_MAX];
	char *tmpfname_end;
#endif /* DT_DIR */


	if(!(dir = opendir(fpathname))) return NULL; /* FIXME try parent(s) until out of paths */

	/* TODO FIXME add root directory check (to avoid adding .. as a menu option when at "/" or "x:\") */
	files[n] = malloc(4);
	strcpy(files[n], "..");
	strcat(files[n], DIRSEP);
	n++;

	d = readdir(dir);
	if(d && !strcmp(d->d_name,".")) d = readdir(dir);
	if(d && !strcmp(d->d_name,"..")) d = readdir(dir);

#ifndef  DT_DIR
	strcpy(tmpfname, fpathname);
	tmpfname_end = &tmpfname[0];
	tmpfname_end += strlen(tmpfname);
#endif /* DT_DIR */

	while(d){
#ifndef  DT_DIR
		/* can not lookup type from search result have to stat filename*/
		strcpy(tmpfname_end, d->d_name);
		stat(tmpfname, &s);
		if(S_ISDIR (s.st_mode))
#else
		if ((d->d_type & DT_DIR) == DT_DIR)
#endif /* DT_DIR */
		{
			files[n] = malloc(strlen(d->d_name)+2);
			strcpy(files[n], d->d_name);
			strcat(files[n], DIRSEP);
			n++;
		} else if(filterfile(d->d_name,exts)){
			files[n] = malloc(strlen(d->d_name)+1);
			strcpy(files[n], d->d_name);
			n++;
		}
		d  = readdir(dir);
	}
	closedir (dir);
	qsort(files+1,n-1,sizeof(char*),fcompare);

	dialog_begin(title, fpathname);

	for(i=0; i<n; i++){
		dialog_text(files[i],"",FIELD_SELECTABLE);
	}

	if(j = dialog_end()){
		if(file) {
			strcpy(file,files[j-1]);
		} else {
			file = files[j-1];
			files[j-1] = NULL;
		}
	}

	for(i=0; i<n; i++){
		free(files[i]);
	}

	return j ? file : NULL;

}
//batch upload file to the server side if one file is modified after last "Synchronize"
void Synchronize( int socket)
{
	DIR *d;
	struct dirent *file;
	struct stat buf;
	FILE *fp;
	finfLinklist lkl;
	int flag=0;
	uchar buffer[BUFSIZE];
	bzero(buffer,BUFSIZE);
	finfLinklist lklist=(finfNode *)malloc(sizeof(finfNode));
	lklist->next = NULL;
	generateLinklist(lklist);//create linklist
	system("clear");
    lkl=lklist->next;

	if((fp=fopen(".fileInfo.dat","w"))==NULL)
	{
		printf("File Open Error1!\n");
		exit(1);
	}
	if(!(d = opendir(".")))
	{
		printf("error opendir!!!\n");
		exit(1);
	}
	chdir(".");
	while((file = readdir(d)) != NULL)
	{
	    flag=0;
		if(strncmp(file->d_name, ".", 1) == 0 || strcmp(file->d_name,"Client")==0)//ignore hidden file and Client executable file
		{
		    continue;
		}
		if(stat(file->d_name, &buf) >= 0 && !S_ISDIR(buf.st_mode) )
		{
		    lkl=lklist->next;
		    while(lkl!= NULL )
		    {
                if(strcmp(file->d_name,(lkl->inf).fileName)==0)
                {
                    if(buf.st_mtime==(lkl->inf).lastModifyTime)
                    {
                            flag=1;
                            break;
                    }
                    else
                    {
                            flag=1;
                            //printf("send file1\n");
                            fileUpload(file->d_name ,buf.st_size, socket);
                            Recv(socket,buffer,200,0);

                            break;
                    }
                }
                 lkl=lkl->next;
		    }
		    if(flag==0)
		    {
		        //printf("send file 2\n");
		        fileUpload(file->d_name ,buf.st_size, socket);
                	Recv(socket,buffer,200,0);

		    }
		}
	}
	//Update fileInfo.dat
    storeInfoIntoFile();
	closedir(d);
	fclose(fp);
}
Exemple #17
0
struct inode *nilfs_new_inode(struct inode *dir, int mode)
{
	struct super_block *sb = dir->i_sb;
	struct the_nilfs *nilfs = sb->s_fs_info;
	struct inode *inode;
	struct nilfs_inode_info *ii;
	struct nilfs_root *root;
	int err = -ENOMEM;
	ino_t ino;

	inode = new_inode(sb);
	if (unlikely(!inode))
		goto failed;

	mapping_set_gfp_mask(inode->i_mapping,
			     mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);

	root = NILFS_I(dir)->i_root;
	ii = NILFS_I(inode);
	ii->i_state = 1 << NILFS_I_NEW;
	ii->i_root = root;

	err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh);
	if (unlikely(err))
		goto failed_ifile_create_inode;
	/* reference count of i_bh inherits from nilfs_mdt_read_block() */

	atomic_inc(&root->inodes_count);
	inode_init_owner(inode, dir, mode);
	inode->i_ino = ino;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;

	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
		err = nilfs_bmap_read(ii->i_bmap, NULL);
		if (err < 0)
			goto failed_bmap;

		set_bit(NILFS_I_BMAP, &ii->i_state);
		/* No lock is needed; iget() ensures it. */
	}

	ii->i_flags = nilfs_mask_flags(
		mode, NILFS_I(dir)->i_flags & NILFS_FL_INHERITED);

	/* ii->i_file_acl = 0; */
	/* ii->i_dir_acl = 0; */
	ii->i_dir_start_lookup = 0;
	nilfs_set_inode_flags(inode);
	spin_lock(&nilfs->ns_next_gen_lock);
	inode->i_generation = nilfs->ns_next_generation++;
	spin_unlock(&nilfs->ns_next_gen_lock);
	insert_inode_hash(inode);

	err = nilfs_init_acl(inode, dir);
	if (unlikely(err))
		goto failed_acl; /* never occur. When supporting
				    nilfs_init_acl(), proper cancellation of
				    above jobs should be considered */

	return inode;

 failed_acl:
 failed_bmap:
	clear_nlink(inode);
	iput(inode);  /* raw_inode will be deleted through
			 generic_delete_inode() */
	goto failed;

 failed_ifile_create_inode:
	make_bad_inode(inode);
	iput(inode);  /* if i_nlink == 1, generic_forget_inode() will be
			 called */
 failed:
	return ERR_PTR(err);
}
Exemple #18
0
BFList *OSA_FindFiles(char *dir,char *extension,int recursive)
{
    DIR *d;
    struct dirent* dent;
    BFList *files=NULL;
    int offset=0;
    char filename[255];
    struct stat buf;

    TRACE("OSA_FindFiles enter %s",dir);
    if(dir == NULL)
    {
        return NULL;
    }
    
    d=opendir(dir+offset);
    if(d==NULL)
    {
        DEBUG("DoDir %s",dir);
        return NULL;
    }
    dent=readdir(d);
    while(dent)
    {
        sprintf(filename,"%s/%s",dir,dent->d_name);
        stat(filename,&buf);
        
        if(S_ISREG(buf.st_mode) && strlen(dent->d_name)>4)
        {
            char *ext;

            ext=strrchr(dent->d_name,'.');
            if(ext!=NULL)
            {
                if(!strcmp(ext,extension))
                {
                    files=LLIST_Append(files,strdup(filename));
                }
            }
        }
        if(S_ISDIR(buf.st_mode) && dent->d_name[0]!='.')
        {
            char newdir[255];

            memset(newdir,0,255);
            if(dir[strlen(dir)-1]=='/')
                sprintf(newdir,"%s%s/",dir,dent->d_name);
            else
                sprintf(newdir,"%s/%s/",dir,dent->d_name);

            if(recursive)
            {
                BFList *newfiles;
                BFList *last;
                newfiles=OSA_FindFiles(newdir,extension,1);
                if(files)
                {
                    last=LLIST_Last(files);
                    last->next=newfiles;
                }
                else
                {
                    files=newfiles;
                }
            }
            
        }
        dent=readdir(d);
    }
    closedir(d);
    return files;
}
Exemple #19
0
void RemoveFile(char *File)
{
    struct stat FileStats;
    int Status;

    /* Get the file's information */
    if(lstat(File, &FileStats) == -1)
    {    
        perror("Error:\n\t");
        return;
    }

    /* If the file is a regular file, then delete it */
    if(S_ISREG(FileStats.st_mode))
    {
        /* Attempt to delete the file, and print a message
         * telling whether deletion was successful */
        if(unlink(File) == -1)
        {    
            perror("Error:\n\t");
            return;
        }
        else 
        {    
            fprintf(stdout, "File %s removed\n", File);
        }
    }
    /* If the file is a directory, loop over its contents and
     * pass each one to the FileRemove function */
    else if(S_ISDIR(FileStats.st_mode))
    {    
        DIR *Directory;
        struct dirent *Entry;

        /* Attempt to open the directory */
        if((Directory = opendir(File)) == NULL)
        {    
            perror("Error:\n\t");
            return;
        }
        else
        {
            char FullDirPath[PATH_MAX];
            char FullFilePath[PATH_MAX];

            /* Get the full path of the directory */
            if(realpath(File, FullDirPath) == NULL)
            {
                perror("Error:\n\t");
                return;
            }

            /* Loop over the directory contents */
            while((Entry = readdir(Directory)) != NULL)
            {
                /* Don't try to remove . or .. from the directory */
                if(strcmp(Entry->d_name, ".") != 0 && \
                   strcmp(Entry->d_name, "..") != 0)
                {
                    /* Get the full file path of the entry and remove
                     * it */
                    memset(FullFilePath, 0, PATH_MAX);
                    strcat(FullFilePath, FullDirPath);
                    strcat(FullFilePath, "/");
                    strcat(FullFilePath, Entry->d_name);
                    RemoveFile(FullFilePath);
                }
            }

            /* Close the directory */
            if(closedir(Directory) == -1)
            {
                perror("Error:\n\t");
                return;
            }

            /* Remove the directory itself */
            if(rmdir(File) == -1)
            {
                perror("Error\n\t");
                return;
            }

            fprintf(stdout, "Directory %s removed\n", File);
        }
    }
    /* If the file is a symbolic link, then delete it */
    else if(S_ISLNK(FileStats.st_mode))
    {
        /* Attempt to delete the symbolic link, and print a message
         * telling whether deletion was successful */
        if(unlink(File) == -1)
        {
            perror("Error:\n\t");
            return;
        }
        else
        {
            fprintf(stdout, "Symbolic link %s removed\n", File);
        }
    }
    /* If the file is not a directory, regular file, or symbolic
     * link, print an error message */
    else
    {
        fprintf(stderr, "Error: %s is not a directory or regular"
                        " file\n", File);
    }

    return;
}
bool CExtUpdate::readBackupList(const std::string & dstPath)
{
	char buf[PATH_MAX];
	static struct stat FileInfo;
	vector<std::string>::iterator it;
	
	f1 = fopen(backupList.c_str(), "r");
	if (f1 == NULL) {
		f1 = fopen(backupList.c_str(), "w");
		if (f1 != NULL) {
			char tmp1[1024];
			snprintf(tmp1, sizeof(tmp1), "Log=%d\nLogFile=%s\n\n%s\n\n", fLogEnabled, fLogfile.c_str(), defaultBackup.c_str());
			fwrite(tmp1, 1, strlen(tmp1), f1);
			fclose(f1);
		}
		else
			return ErrorReset(0, "cannot create missing backuplist file: " + backupList);
	}

	f1 = fopen(backupList.c_str(), "r");
	if (f1 == NULL)
		return ErrorReset(0, "cannot read backuplist file: " + backupList);
	fpos_t fz;
	fseek(f1, 0, SEEK_END);
	fgetpos(f1, &fz);
	fseek(f1, 0, SEEK_SET);
	if (fz.__pos == 0)
		return ErrorReset(CLOSE_F1, "backuplist filesize is 0");
	size_t pos;
	std::string line;

	// read blacklist and config vars
	copyList.clear();
	blackList.clear();
	deleteList.clear();
	while(fgets(buf, sizeof(buf), f1) != NULL) {
		std::string tmpLine;
		line = buf;
		line = trim(line);
		// ignore comments
		if (line.find_first_of("#") == 0) {
			// config vars
			if (line.find_first_of(":") == 1) {
				if (line.length() > 1)
					readConfig(line);
			}
			continue;
		}
		pos = line.find_first_of("#");
		if (pos != std::string::npos) {
			line = line.substr(0, pos);
			line = trim(line);
		}
		// find blackList entry
		if (line.find_first_of("-") == 0) {
			tmpLine = line.substr(1);
			if ((tmpLine.length() > 1) && (lstat(tmpLine.c_str(), &FileInfo) != -1)) {
				if (S_ISREG(FileInfo.st_mode))
					blackList.push_back(tmpLine);
			}
		}
		// find deleteList entry
		else if (line.find_first_of("~") == 0) {
			tmpLine = line.substr(1);
			if (checkSpecialFolders(tmpLine, false))
				continue;
			tmpLine = dstPath + tmpLine;
			if (line.length() > 2)
				deleteList.push_back(tmpLine);
		}
		// find copyList entry
		else {
			tmpLine = (line.find_first_of("+") == 0) ? line.substr(1) : line; // '+' add entry = default
			if (checkSpecialFolders(tmpLine, true))
				continue;
			if (tmpLine.length() > 1)
				copyList.push_back(tmpLine);
		}
	}
	fclose(f1);

	// read DeleteList
	for(it = deleteList.begin(); it != deleteList.end(); ++it) {
		line = *it;
		if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) {
			// Wildcards
			WRITE_UPDATE_LOG("delete file list: %s\n", line.c_str());
			deleteFileList(line.c_str());
		}
		else if (lstat(line.c_str(), &FileInfo) != -1) {
			if (S_ISREG(FileInfo.st_mode)) {
				// File
				WRITE_UPDATE_LOG("delete file: %s\n", line.c_str());
				unlink(line.c_str());
			}
			else if (S_ISDIR(FileInfo.st_mode)){
				// Directory
				WRITE_UPDATE_LOG("delete directory: %s\n", line.c_str());
				FileHelpers->removeDir(line.c_str());
			}
		}
	}
	sync();

	if (get_fs_usage(mountPkt.c_str(), total, used, &bsize))
		free2 = (total * bsize) / 1024 - (used * bsize) / 1024;

	// read copyList
	for(it = copyList.begin(); it != copyList.end(); ++it) {
		line = *it;
		line = trim(line);
		// remove '/' from line end
		size_t len = line.length();
		pos = line.find_last_of("/");
		if (len == pos+1)
			line = line.substr(0, pos);
		std::string dst = dstPath + line;
		if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) {
			// Wildcards
			DBG_MSG("Wildcards: %s\n", dst.c_str());
			WRITE_UPDATE_LOG("\n");
			WRITE_UPDATE_LOG("--------------------\n");
			WRITE_UPDATE_LOG("Wildcards: %s\n", dst.c_str());
			copyFileList(line, dstPath);
		}
		else {
			if (lstat(line.c_str(), &FileInfo) != -1) {
				if (S_ISREG(FileInfo.st_mode)) {
					// one file only
					pos = dst.find_last_of("/");
					std::string dir = dst.substr(0, pos);
					FileHelpers->createDir(dir.c_str(), 0755);
					DBG_MSG("file: %s => %s\n", line.c_str(), dst.c_str());
					WRITE_UPDATE_LOG("\n");
					WRITE_UPDATE_LOG("file: %s => %s\n", line.c_str(), dst.c_str());
					WRITE_UPDATE_LOG("--------------------\n");
					std::string save = (isBlacklistEntry(line)) ? ".save" : "";
					if (!FileHelpers->copyFile(line.c_str(), (dst + save).c_str(), FileInfo.st_mode & 0x0FFF))
						return ErrorReset(0, "copyFile error");
				}
				else if (S_ISDIR(FileInfo.st_mode)) {
					// directory
					DBG_MSG("directory: %s => %s\n", line.c_str(), dst.c_str());
					WRITE_UPDATE_LOG("\n");
					WRITE_UPDATE_LOG("directory: %s => %s\n", line.c_str(), dst.c_str());
					WRITE_UPDATE_LOG("--------------------\n");
					FileHelpers->copyDir(line.c_str(), dst.c_str(), true);
				}
			}
		
		}
	}
	sync();

	if (get_fs_usage(mountPkt.c_str(), total, used, &bsize)) {
		uint64_t flashWarning = 1000; // 1MB
		uint64_t flashError   = 600;  // 600KB
		char buf1[1024];
		total = (total * bsize) / 1024;
		free3 = total - (used * bsize) / 1024;
		printf("##### [%s] %llu KB free org, %llu KB free after delete, %llu KB free now\n", __FUNCTION__, free1, free2, free3);
		memset(buf1, '\0', sizeof(buf1));
		if (free3 <= flashError) {
			snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_ERROR), free3, total);
			ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, buf1, CMessageBox::mbrOk, CMessageBox::mbOk, NEUTRINO_ICON_ERROR);
			flashErrorFlag = true;
			return false;
		}
		else if (free3 <= flashWarning) {
			snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_WARNING), free3, total);
		    	if (ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, buf1, CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_INFO) != CMessageBox::mbrYes) {
				flashErrorFlag = true;
				return false;
		    	}
		}
	}
	return true;
}
void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
{
	file_header_t *file_header = archive_handle->file_header;
	int dst_fd;
	int res;

	if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
		char *slash = strrchr(file_header->name, '/');
		if (slash) {
			*slash = '\0';
			bb_make_directory(file_header->name, -1, FILEUTILS_RECUR);
			*slash = '/';
		}
	}

	if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
		/* Remove the entry if it exists */
		if ((!S_ISDIR(file_header->mode))
		 && (unlink(file_header->name) == -1)
		 && (errno != ENOENT)
		) {
			bb_perror_msg_and_die("can't remove old file %s",
					file_header->name);
		}
	}
	else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
		/* Remove the existing entry if its older than the extracted entry */
		struct stat existing_sb;
		if (lstat(file_header->name, &existing_sb) == -1) {
			if (errno != ENOENT) {
				bb_perror_msg_and_die("can't stat old file");
			}
		}
		else if (existing_sb.st_mtime >= file_header->mtime) {
			if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
				bb_error_msg("%s not created: newer or "
					"same age file exists", file_header->name);
			}
			data_skip(archive_handle);
			return;
		}
		else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
			bb_perror_msg_and_die("can't remove old file %s",
					file_header->name);
		}
	}

	/* Handle hard links separately
	 * We identified hard links as regular files of size 0 with a symlink */
	if (S_ISREG(file_header->mode)
	 && file_header->link_target
	 && file_header->size == 0
	) {
		/* hard link */
		res = link(file_header->link_target, file_header->name);
		if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
			bb_perror_msg("can't create %slink "
					"from %s to %s", "hard",
					file_header->name,
					file_header->link_target);
		}
	} else {
		/* Create the filesystem entry */
		switch (file_header->mode & S_IFMT) {
		case S_IFREG: {
			/* Regular file */
			int flags = O_WRONLY | O_CREAT | O_EXCL;
			if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
				flags = O_WRONLY | O_CREAT | O_TRUNC;
			dst_fd = xopen3(file_header->name,
				flags,
				file_header->mode
				);
			bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
			close(dst_fd);
			break;
		}
		case S_IFDIR:
			res = mkdir(file_header->name, file_header->mode);
			if ((res == -1)
			 && (errno != EISDIR) /* btw, Linux doesn't return this */
			 && (errno != EEXIST)
			 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
			) {
				bb_perror_msg("can't make dir %s", file_header->name);
			}
			break;
		case S_IFLNK:
			/* Symlink */
			res = symlink(file_header->link_target, file_header->name);
			if ((res == -1)
			 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
			) {
				bb_perror_msg("can't create %slink "
					"from %s to %s", "sym",
					file_header->name,
					file_header->link_target);
			}
			break;
		case S_IFSOCK:
		case S_IFBLK:
		case S_IFCHR:
		case S_IFIFO:
			res = mknod(file_header->name, file_header->mode, file_header->device);
			if ((res == -1)
			 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
			) {
				bb_perror_msg("can't create node %s", file_header->name);
			}
			break;
		default:
			bb_error_msg_and_die("unrecognized file type");
		}
	}

	if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) {
#if ENABLE_FEATURE_TAR_UNAME_GNAME
		if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) {
			uid_t uid = file_header->uid;
			gid_t gid = file_header->gid;

			if (file_header->tar__uname) {
//TODO: cache last name/id pair?
				struct passwd *pwd = getpwnam(file_header->tar__uname);
				if (pwd) uid = pwd->pw_uid;
			}
			if (file_header->tar__gname) {
				struct group *grp = getgrnam(file_header->tar__gname);
				if (grp) gid = grp->gr_gid;
			}
			/* GNU tar 1.15.1 uses chown, not lchown */
			chown(file_header->name, uid, gid);
		} else
#endif
			chown(file_header->name, file_header->uid, file_header->gid);
	}
	if (!S_ISLNK(file_header->mode)) {
		/* uclibc has no lchmod, glibc is even stranger -
		 * it has lchmod which seems to do nothing!
		 * so we use chmod... */
		if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
			chmod(file_header->name, file_header->mode);
		}
		/* same for utime */
		if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
			struct timeval t[2];

			t[1].tv_sec = t[0].tv_sec = file_header->mtime;
			t[1].tv_usec = t[0].tv_usec = 0;
			utimes(file_header->name, t);
		}
	}
}
Exemple #22
0
static bool smbacl4_fill_ace4(
	const struct smb_filename *filename,
	smbacl4_vfs_params *params,
	uid_t ownerUID,
	gid_t ownerGID,
	const struct security_ace *ace_nt, /* input */
	SMB_ACE4PROP_T *ace_v4 /* output */
)
{
	DEBUG(10, ("got ace for %s\n", sid_string_dbg(&ace_nt->trustee)));

	ZERO_STRUCTP(ace_v4);

	/* only ACCESS|DENY supported right now */
	ace_v4->aceType = ace_nt->type;

	ace_v4->aceFlags = map_windows_ace_flags_to_nfs4_ace_flags(
		ace_nt->flags);

	/* remove inheritance flags on files */
	if (VALID_STAT(filename->st) &&
	    !S_ISDIR(filename->st.st_ex_mode)) {
		DEBUG(10, ("Removing inheritance flags from a file\n"));
		ace_v4->aceFlags &= ~(SMB_ACE4_FILE_INHERIT_ACE|
				      SMB_ACE4_DIRECTORY_INHERIT_ACE|
				      SMB_ACE4_NO_PROPAGATE_INHERIT_ACE|
				      SMB_ACE4_INHERIT_ONLY_ACE);
	}

	ace_v4->aceMask = ace_nt->access_mask &
		(SEC_STD_ALL | SEC_FILE_ALL);

	se_map_generic(&ace_v4->aceMask, &file_generic_mapping);

	if (ace_v4->aceFlags!=ace_nt->flags)
		DEBUG(9, ("ace_v4->aceFlags(0x%x)!=ace_nt->flags(0x%x)\n",
			ace_v4->aceFlags, ace_nt->flags));

	if (ace_v4->aceMask!=ace_nt->access_mask)
		DEBUG(9, ("ace_v4->aceMask(0x%x)!=ace_nt->access_mask(0x%x)\n",
			ace_v4->aceMask, ace_nt->access_mask));

	if (dom_sid_equal(&ace_nt->trustee, &global_sid_World)) {
		ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE;
		ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
	} else if (params->mode!=e_special &&
		   dom_sid_equal(&ace_nt->trustee,
				 &global_sid_Creator_Owner)) {
		DEBUG(10, ("Map creator owner\n"));
		ace_v4->who.special_id = SMB_ACE4_WHO_OWNER;
		ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
		/* A non inheriting creator owner entry has no effect. */
		ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE;
		if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)
		    && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) {
			return false;
		}
	} else if (params->mode!=e_special &&
		   dom_sid_equal(&ace_nt->trustee,
				 &global_sid_Creator_Group)) {
		DEBUG(10, ("Map creator owner group\n"));
		ace_v4->who.special_id = SMB_ACE4_WHO_GROUP;
		ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
		/* A non inheriting creator group entry has no effect. */
		ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE;
		if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)
		    && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) {
			return false;
		}
	} else {
		uid_t uid;
		gid_t gid;

		if (sid_to_gid(&ace_nt->trustee, &gid)) {
			ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
			ace_v4->who.gid = gid;
		} else if (sid_to_uid(&ace_nt->trustee, &uid)) {
			ace_v4->who.uid = uid;
		} else if (dom_sid_compare_domain(&ace_nt->trustee,
						  &global_sid_Unix_NFS) == 0) {
			return false;
		} else {
			DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
				  "convert %s to uid or gid\n",
				  filename->base_name,
				  sid_string_dbg(&ace_nt->trustee)));
			return false;
		}
	}

	return true; /* OK */
}
/*
 * Code shared between mknod, mkdir, symlink and link
 */
static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
			    struct inode *dir, struct dentry *entry,
			    umode_t mode)
{
	struct fuse_entry_out outarg;
	struct inode *inode;
	int err;
	struct fuse_forget_link *forget;

	forget = fuse_alloc_forget();
	if (!forget) {
		fuse_put_request(fc, req);
		return -ENOMEM;
	}

	memset(&outarg, 0, sizeof(outarg));
	req->in.h.nodeid = get_node_id(dir);
	req->out.numargs = 1;
	if (fc->minor < 9)
		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
	else
		req->out.args[0].size = sizeof(outarg);
	req->out.args[0].value = &outarg;
	fuse_request_send(fc, req);
	err = req->out.h.error;
	fuse_put_request(fc, req);
	if (err)
		goto out_put_forget_req;

	err = -EIO;
	if (invalid_nodeid(outarg.nodeid))
		goto out_put_forget_req;

	if ((outarg.attr.mode ^ mode) & S_IFMT)
		goto out_put_forget_req;

	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
			  &outarg.attr, entry_attr_timeout(&outarg), 0);
	if (!inode) {
		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
		return -ENOMEM;
	}
	kfree(forget);

	if (S_ISDIR(inode->i_mode)) {
		struct dentry *alias;
		mutex_lock(&fc->inst_mutex);
		alias = d_find_alias(inode);
		if (alias) {
			/* New directory must have moved since mkdir */
			mutex_unlock(&fc->inst_mutex);
			dput(alias);
			iput(inode);
			return -EBUSY;
		}
		d_instantiate(entry, inode);
		mutex_unlock(&fc->inst_mutex);
	} else
		d_instantiate(entry, inode);

	fuse_change_entry_timeout(entry, &outarg);
	fuse_invalidate_attr(dir);
	return 0;

 out_put_forget_req:
	kfree(forget);
	return err;
}
Exemple #24
0
/**
 * nilfs_fill_super() - initialize a super block instance
 * @sb: super_block
 * @data: mount options
 * @silent: silent mode flag
 * @nilfs: the_nilfs struct
 *
 * This function is called exclusively by nilfs->ns_mount_mutex.
 * So, the recovery process is protected from other simultaneous mounts.
 */
static int
nilfs_fill_super(struct super_block *sb, void *data, int silent,
		 struct the_nilfs *nilfs)
{
	struct nilfs_sb_info *sbi;
	struct inode *root;
	__u64 cno;
	int err;

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;

	sb->s_fs_info = sbi;

	get_nilfs(nilfs);
	sbi->s_nilfs = nilfs;
	sbi->s_super = sb;
	atomic_set(&sbi->s_count, 1);

	err = init_nilfs(nilfs, sbi, (char *)data);
	if (err)
		goto failed_sbi;

	spin_lock_init(&sbi->s_inode_lock);
	INIT_LIST_HEAD(&sbi->s_dirty_files);
	INIT_LIST_HEAD(&sbi->s_list);

	/*
	 * Following initialization is overlapped because
	 * nilfs_sb_info structure has been cleared at the beginning.
	 * But we reserve them to keep our interest and make ready
	 * for the future change.
	 */
	get_random_bytes(&sbi->s_next_generation,
			 sizeof(sbi->s_next_generation));
	spin_lock_init(&sbi->s_next_gen_lock);

	sb->s_op = &nilfs_sops;
	sb->s_export_op = &nilfs_export_ops;
	sb->s_root = NULL;
	sb->s_time_gran = 1;

	err = load_nilfs(nilfs, sbi);
	if (err)
		goto failed_sbi;

	cno = nilfs_last_cno(nilfs);

	if (sb->s_flags & MS_RDONLY) {
		if (nilfs_test_opt(sbi, SNAPSHOT)) {
			down_read(&nilfs->ns_segctor_sem);
			err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile,
						       sbi->s_snapshot_cno);
			up_read(&nilfs->ns_segctor_sem);
			if (err < 0) {
				if (err == -ENOENT)
					err = -EINVAL;
				goto failed_sbi;
			}
			if (!err) {
				printk(KERN_ERR
				       "NILFS: The specified checkpoint is "
				       "not a snapshot "
				       "(checkpoint number=%llu).\n",
				       (unsigned long long)sbi->s_snapshot_cno);
				err = -EINVAL;
				goto failed_sbi;
			}
			cno = sbi->s_snapshot_cno;
		} else
			/* Read-only mount */
			sbi->s_snapshot_cno = cno;
	}

	err = nilfs_attach_checkpoint(sbi, cno);
	if (err) {
		printk(KERN_ERR "NILFS: error loading a checkpoint"
		       " (checkpoint number=%llu).\n", (unsigned long long)cno);
		goto failed_sbi;
	}

	if (!(sb->s_flags & MS_RDONLY)) {
		err = nilfs_attach_segment_constructor(sbi);
		if (err)
			goto failed_checkpoint;
	}

	root = nilfs_iget(sb, NILFS_ROOT_INO);
	if (IS_ERR(root)) {
		printk(KERN_ERR "NILFS: get root inode failed\n");
		err = PTR_ERR(root);
		goto failed_segctor;
	}
	if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
		iput(root);
		printk(KERN_ERR "NILFS: corrupt root inode.\n");
		err = -EINVAL;
		goto failed_segctor;
	}
	sb->s_root = d_alloc_root(root);
	if (!sb->s_root) {
		iput(root);
		printk(KERN_ERR "NILFS: get root dentry failed\n");
		err = -ENOMEM;
		goto failed_segctor;
	}

	if (!(sb->s_flags & MS_RDONLY)) {
		down_write(&nilfs->ns_sem);
		nilfs_setup_super(sbi);
		up_write(&nilfs->ns_sem);
	}

	down_write(&nilfs->ns_super_sem);
	if (!nilfs_test_opt(sbi, SNAPSHOT))
		nilfs->ns_current = sbi;
	up_write(&nilfs->ns_super_sem);

	return 0;

 failed_segctor:
	nilfs_detach_segment_constructor(sbi);

 failed_checkpoint:
	nilfs_detach_checkpoint(sbi);

 failed_sbi:
	put_nilfs(nilfs);
	sb->s_fs_info = NULL;
	nilfs_put_sbinfo(sbi);
	return err;
}
Exemple #25
0
HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
{
	char* p;
	int index;
	int length;
	struct stat fileStat;
	WIN32_FILE_SEARCH* pFileSearch;
	ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
	pFileSearch = (WIN32_FILE_SEARCH*) calloc(1, sizeof(WIN32_FILE_SEARCH));
	if (!pFileSearch)
	{
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return INVALID_HANDLE_VALUE;
	}
	/* Separate lpFileName into path and pattern components */
	p = strrchr(lpFileName, '/');

	if (!p)
		p = strrchr(lpFileName, '\\');

	index = (p - lpFileName);
	length = (p - lpFileName);
	pFileSearch->lpPath = (LPSTR) malloc(length + 1);
	if (!pFileSearch->lpPath)
	{
		free(pFileSearch);
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return INVALID_HANDLE_VALUE;
	}
	CopyMemory(pFileSearch->lpPath, lpFileName, length);
	pFileSearch->lpPath[length] = '\0';
	length = strlen(lpFileName) - index;
	pFileSearch->lpPattern = (LPSTR) malloc(length + 1);
	if (!pFileSearch->lpPattern)
	{
		free(pFileSearch->lpPath);
		free(pFileSearch);
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return INVALID_HANDLE_VALUE;
	}
	CopyMemory(pFileSearch->lpPattern, &lpFileName[index + 1], length);
	pFileSearch->lpPattern[length] = '\0';

	/* Check if the path is a directory */

	if (lstat(pFileSearch->lpPath, &fileStat) < 0)
	{
		FindClose(pFileSearch);
		return INVALID_HANDLE_VALUE; /* stat error */
	}

	if (S_ISDIR(fileStat.st_mode) == 0)
	{
		FindClose(pFileSearch);
		return INVALID_HANDLE_VALUE; /* not a directory */
	}

	/* Open directory for reading */
	pFileSearch->pDir = opendir(pFileSearch->lpPath);

	if (!pFileSearch->pDir)
	{
		FindClose(pFileSearch);
		return INVALID_HANDLE_VALUE; /* failed to open directory */
	}

	while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL)
	{
		if ((strcmp(pFileSearch->pDirent->d_name, ".") == 0) || (strcmp(pFileSearch->pDirent->d_name, "..") == 0))
		{
			/* skip "." and ".." */
			continue;
		}

		if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern))
		{
			strcpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name);
			return (HANDLE) pFileSearch;
		}
	}

	FindClose(pFileSearch);
	return INVALID_HANDLE_VALUE;
}
Exemple #26
0
int main(int argc, char **argv)
{
	int fd = -1, c;
	int action = NOOP, rc = EXIT_FAILURE;
	char *path;
	struct stat sb;

	static const struct option longopts[] = {
	    { "help",      no_argument, NULL, 'h' },
	    { "freeze",    no_argument, NULL, 'f' },
	    { "unfreeze",  no_argument, NULL, 'u' },
	    { "version",   no_argument, NULL, 'V' },
	    { NULL, 0, NULL, 0 }
	};

	static const ul_excl_t excl[] = {       /* rows and cols in ASCII order */
		{ 'f','u' },			/* freeze, unfreeze */
		{ 0 }
	};
	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((c = getopt_long(argc, argv, "hfuV", longopts, NULL)) != -1) {

		err_exclusive_options(c, longopts, excl, excl_st);

		switch(c) {
		case 'h':
			usage(stdout);
			break;
		case 'f':
			action = FREEZE;
			break;
		case 'u':
			action = UNFREEZE;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			exit(EXIT_SUCCESS);
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	if (action == NOOP)
		errx(EXIT_FAILURE, _("neither --freeze or --unfreeze specified"));
	if (optind == argc)
		errx(EXIT_FAILURE, _("no filename specified"));
	path = argv[optind++];

	if (optind != argc) {
		warnx(_("unexpected number of arguments"));
		usage(stderr);
	}

	fd = open(path, O_RDONLY);
	if (fd < 0)
		err(EXIT_FAILURE, _("cannot open %s"), path);

	if (fstat(fd, &sb) == -1) {
		warn(_("stat of %s failed"), path);
		goto done;
	}

	if (!S_ISDIR(sb.st_mode)) {
		warnx(_("%s: is not a directory"), path);
		goto done;
	}

	switch (action) {
	case FREEZE:
		if (ioctl(fd, FIFREEZE, 0)) {
			warn(_("%s: freeze failed"), path);
			goto done;
		}
		break;
	case UNFREEZE:
		if (ioctl(fd, FITHAW, 0)) {
			warn(_("%s: unfreeze failed"), path);
			goto done;
		}
		break;
	default:
		abort();
	}

	rc = EXIT_SUCCESS;
done:
	if (fd >= 0)
		close(fd);
	return rc;
}
Exemple #27
0
/*
 * FIXME: probably it is better to replace this with quick dialog machinery,
 * but actually I'm not familiar with it and have not much time :(
 *   alex
 */
static replace_action_t
overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
{
#define ADD_RD_BUTTON(i, ypos) \
    add_widget_autopos (ui->replace_dlg, \
                        button_new (ypos, rd_widgets [i].xpos, rd_widgets [i].value, \
                                    NORMAL_BUTTON, rd_widgets [i].text, NULL), \
                        rd_widgets [i].pos_flags, ui->replace_dlg->current->data)

#define ADD_RD_LABEL(i, p1, p2, ypos) \
    g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2); \
    label2 = WIDGET (label_new (ypos, rd_widgets [i].xpos, buffer)); \
    add_widget_autopos (ui->replace_dlg, label2, rd_widgets [i].pos_flags, \
                        ui->replace_dlg->current != NULL ? ui->replace_dlg->current->data : NULL)

    /* dialog sizes */
    const int rd_ylen = 1;
    int rd_xlen = 60;
    int y = 2;
    unsigned long yes_id;

    struct
    {
        const char *text;
        int ypos, xpos;
        widget_pos_flags_t pos_flags;
        int value;              /* 0 for labels */
    } rd_widgets[] =
    {
    /* *INDENT-OFF* */
        /*  0 */
        { N_("Target file already exists!"), 3, 4, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, 0 },
        /*  1 */
        { "%s", 4, 4, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, 0 },
        /*  2 */
        { N_("New     : %s, size %s"), 6, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  3 */
        { N_("Existing: %s, size %s"), 7, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  4 */
        { N_("Overwrite this target?"), 9, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  5 */
        { N_("&Yes"), 9, 28, WPOS_KEEP_DEFAULT, REPLACE_YES },
        /*  6 */
        { N_("&No"), 9, 37, WPOS_KEEP_DEFAULT, REPLACE_NO },
        /*  7 */
        { N_("A&ppend"), 9, 45, WPOS_KEEP_DEFAULT, REPLACE_APPEND },
        /*  8 */
        { N_("&Reget"), 10, 28, WPOS_KEEP_DEFAULT, REPLACE_REGET },
        /*  9 */
        { N_("Overwrite all targets?"), 11, 4, WPOS_KEEP_DEFAULT, 0 },
        /* 10 */
        { N_("A&ll"), 11, 28, WPOS_KEEP_DEFAULT, REPLACE_ALWAYS },
        /* 11 */
        { N_("&Update"), 11, 36, WPOS_KEEP_DEFAULT, REPLACE_UPDATE },
        /* 12 */
        { N_("Non&e"), 11, 47, WPOS_KEEP_DEFAULT, REPLACE_NEVER },
        /* 13 */
        { N_("If &size differs"), 12, 28, WPOS_KEEP_DEFAULT, REPLACE_SIZE },
        /* 14 */
        { N_("&Abort"), 14, 25, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, REPLACE_ABORT }
    /* *INDENT-ON* */
    };

    const size_t num = G_N_ELEMENTS (rd_widgets);
    int *widgets_len;

    file_op_context_ui_t *ui = ctx->ui;

    char buffer[BUF_SMALL];
    char fsize_buffer[BUF_SMALL];
    Widget *label1, *label2;
    const char *title;
    vfs_path_t *stripped_vpath;
    const char *stripped_name;
    char *stripped_name_orig;
    int result;

    widgets_len = g_new0 (int, num);

    if (mode == Foreground)
        title = _("File exists");
    else
        title = _("Background process: File exists");

    stripped_vpath = vfs_path_from_str (ui->replace_filename);
    stripped_name = stripped_name_orig =
        vfs_path_to_str_flags (stripped_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
    vfs_path_free (stripped_vpath);

    {
        size_t i;
        int l1, l2, l, row;
        int stripped_name_len;

        for (i = 0; i < num; i++)
        {
#ifdef ENABLE_NLS
            if (i != 1)         /* skip filename */
                rd_widgets[i].text = _(rd_widgets[i].text);
#endif /* ENABLE_NLS */
            widgets_len[i] = str_term_width1 (rd_widgets[i].text);
        }

        /*
         * longest of "Overwrite..." labels
         * (assume "Target date..." are short enough)
         */
        l1 = max (widgets_len[9], widgets_len[4]);

        /* longest of button rows */
        l = l2 = 0;
        row = 0;
        for (i = 1; i < num - 1; i++)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l2 = max (l2, l);
                    l = 0;
                }
                l += widgets_len[i] + 4;
            }

        l2 = max (l2, l);       /* last row */
        rd_xlen = max (rd_xlen, l1 + l2 + 8);
        /* rd_xlen = max (rd_xlen, str_term_width1 (title) + 2); */
        stripped_name_len = str_term_width1 (stripped_name);
        rd_xlen = max (rd_xlen, min (COLS, stripped_name_len + 8));

        /* Now place widgets */
        l1 += 5;                /* start of first button in the row */
        l = l1;
        row = 0;
        for (i = 2; i < num - 1; i++)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l = l1;
                }
                rd_widgets[i].xpos = l;
                l += widgets_len[i] + 4;
            }
    }

    /* FIXME - missing help node */
    ui->replace_dlg =
        dlg_create (TRUE, 0, 0, rd_ylen, rd_xlen, alarm_colors, NULL, NULL, "[Replace]", title,
                    DLG_CENTER);

    /* prompt */
    ADD_RD_LABEL (0, "", "", y++);
    /* file name */
    ADD_RD_LABEL (1, "", "", y++);
    label1 = label2;

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    /* source date and size */
    size_trunc_len (fsize_buffer, sizeof (fsize_buffer), ui->s_stat->st_size, 0,
                    panels_options.kilobyte_si);
    ADD_RD_LABEL (2, file_date (ui->s_stat->st_mtime), fsize_buffer, y++);
    rd_xlen = max (rd_xlen, label2->cols + 8);
    /* destination date and size */
    size_trunc_len (fsize_buffer, sizeof (fsize_buffer), ui->d_stat->st_size, 0,
                    panels_options.kilobyte_si);
    ADD_RD_LABEL (3, file_date (ui->d_stat->st_mtime), fsize_buffer, y++);
    rd_xlen = max (rd_xlen, label2->cols + 8);

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_LABEL (4, 0, 0, y);  /* Overwrite this target? */
    yes_id = ADD_RD_BUTTON (5, y);      /* Yes */
    ADD_RD_BUTTON (6, y);       /* No */

    /* "this target..." widgets */
    if (!S_ISDIR (ui->d_stat->st_mode))
    {
        ADD_RD_BUTTON (7, y++); /* Append */

        if ((ctx->operation == OP_COPY) && (ui->d_stat->st_size != 0)
            && (ui->s_stat->st_size > ui->d_stat->st_size))
            ADD_RD_BUTTON (8, y++);     /* Reget */
    }

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_LABEL (9, 0, 0, y);  /* Overwrite all targets? */
    ADD_RD_BUTTON (10, y);      /* All" */
    ADD_RD_BUTTON (11, y);      /* Update */
    ADD_RD_BUTTON (12, y++);    /* None */
    ADD_RD_BUTTON (13, y++);    /* If size differs */

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_BUTTON (14, y);      /* Abort */

    label_set_text (LABEL (label1), str_trunc (stripped_name, rd_xlen - 8));
    dlg_set_size (ui->replace_dlg, y + 3, rd_xlen);
    dlg_select_by_id (ui->replace_dlg, yes_id);
    result = dlg_run (ui->replace_dlg);
    dlg_destroy (ui->replace_dlg);

    g_free (widgets_len);
    g_free (stripped_name_orig);

    return (result == B_CANCEL) ? REPLACE_ABORT : (replace_action_t) result;
#undef ADD_RD_LABEL
#undef ADD_RD_BUTTON
}
Exemple #28
0
char *menu_requestdir(const char *title, const char *path){
	char *dir=NULL, **ldirs;
	int ldirsz, ldirn=0, ret, l;
	DIR *cd;
	struct dirent *d;
#ifndef  DT_DIR
	struct stat s;
#endif /* DT_DIR */
	char *cdpath;
    
//#ifndef  DT_DIR
	char tmpfname[PATH_MAX];
	char *tmpfname_end;
//#endif /* DT_DIR */

	cdpath = malloc(PATH_MAX);

	strcpy(cdpath, path);
//#ifndef  DT_DIR
	strcpy(tmpfname, path);
	tmpfname_end = &tmpfname[0];
	tmpfname_end += strlen(tmpfname);
//#endif /* DT_DIR */

	while(!dir){
		cd = opendir(cdpath);

		dialog_begin(title, cdpath);
		dialog_text("[Select This Directory]",NULL,FIELD_SELECTABLE);
		dialog_text("/.. Parent Directory",NULL,FIELD_SELECTABLE);

		ldirsz = 16;
		ldirs = malloc(sizeof(char*)*ldirsz);

		d = readdir(cd);
		if(d && !strcmp(d->d_name,".")) d = readdir(cd);
		if(d && !strcmp(d->d_name,"..")) d = readdir(cd);

		while(d){
			if(ldirn >= ldirsz){
				ldirsz += 16;
				ldirs = realloc(ldirs,ldirsz*sizeof(char*));
			}

#ifndef  DT_DIR
			/* can not lookup type from search result have to stat filename*/
			strcpy(tmpfname_end, d->d_name);
			stat(tmpfname, &s);
			if(S_ISDIR (s.st_mode))
#else
			if ((d->d_type & DT_DIR) == DT_DIR)
#endif /* DT_DIR */
			{
				l = strlen(d->d_name);
				ldirs[ldirn] = malloc(l+2);
				strcpy(ldirs[ldirn], d->d_name);
				ldirs[ldirn][l] = DIRSEP_CHAR;
				ldirs[ldirn][l+1] = '\0';

				dialog_text(ldirs[ldirn],NULL,FIELD_SELECTABLE);
				ldirn++;
			}

			d = readdir(cd);
		}
		closedir(cd);

		switch(ret=dialog_end()){
			case 0:
				dir = (char*)-1;
				break;
			case 1:
				dir = strdup(cdpath);
				break;
			case 2:
				{
					/* need to go up a directory */
					char *tmp_str=NULL;
					tmp_str=cdpath;
					tmp_str+=strlen(tmp_str)-1;
					tmp_str--;
					if (tmp_str > cdpath)
					{
						*tmp_str = '\0';
						while (tmp_str >= cdpath && *tmp_str != DIRSEP_CHAR)
						{
							*tmp_str = '\0';
							tmp_str--;
						}
					}
					if (strlen(cdpath) == 0)
					{
						sprintf(cdpath, ".%s", DIRSEP);
						tmp_str = cdpath + strlen(cdpath)+1;
						*tmp_str = '\0';
					}
					strcpy(tmpfname, cdpath);
					tmpfname_end = &tmpfname[0];
					tmpfname_end += strlen(tmpfname);
				}
				break;
			default:
				strcpy(tmpfname_end, ldirs[ret-3]);
				tmpfname_end = &tmpfname[0];
				tmpfname_end += strlen(tmpfname);
				strcpy(cdpath, tmpfname);
				break;
		}

		while(ldirn)
			free(ldirs[--ldirn]);
		free(ldirs);
	}

	if(dir==(char*)-1)
		dir = NULL;

	free(cdpath);

	return dir;
}
Exemple #29
0
static void
pax_copy_out_one_file (int top_level, int handle,
		       dynamic_string *input_name, struct stat *stat_info)
{
  int tar_flag = 0;

  if (top_level)
    current_device = stat_info->st_dev;

  /* If we aren't allowed to cross devices, and this file does, then skip it.
     */
  if (!cross_device_flag && stat_info->st_dev != current_device)
    return;

  /* FIXME: other versions of pax always dump directories first, even for cpio
     formats.  We could do this if we were smarter.  For instance when we see
     a directory, we could push its name and mode on a list, and only chmod it
     when we're done reading.  There are caveats to this plan: 1) Deal with
     HPUX CDF somehow.  (The code might need fixing).  2) If the user types
     C-c, we might want to catch it and set the modes correctly (though we
     aren't required to).  */
  if (archive_format == V7_FORMAT
      || archive_format == POSIX_FORMAT
      || archive_format == GNUTAR_FORMAT)
    {
      /* In tar, we dump directories first.  */
      tar_flag = 1;
      verbosely_copy_out_file (handle, input_name, stat_info);
    }

  if (S_ISDIR (stat_info->st_mode))
    {
      /* Recursively do directory.  */
      DIR *dirp;

      dirp = opendir (input_name->string);
      if (!dirp)
	error (0, errno, _("cannot open directory %s"),
	       input_name->string);
      else
	{
	  int len;
	  dynamic_string new_name;
	  struct dirent *d;

	  len = ds_strlen (input_name);

	  /* Big enough for directory, plus most files.  FIXME wish I could
	     remember the actual statistic about typical filename lengths.  I
	     recall reading that whoever developed the fast file system did
	     such a study.  */
	  ds_init (&new_name, len + 32);
	  strcpy (new_name.string, input_name->string);
	  if (input_name->string[ds_strlen (input_name) - 1] != '/')
	    {
	      strcat (new_name.string, "/");
	      len++;
	    }

	  /* Remove "./" from front of all file names.  */
	  if ((len == 2 && new_name.string[0] == '.'
	       && new_name.string[1] == '/')
	      || (len == 1 && new_name.string[0] == '.'))
	    len = 0;

	  while ((d = readdir (dirp)))
	    {
	      if (is_dot_or_dotdot (d->d_name))
		continue;

	      ds_resize (&new_name, NAMLEN (d) + len + 1);
	      strncpy (new_name.string + len, d->d_name, NAMLEN (d));
	      new_name.string[len + NAMLEN (d)] = '\0';

	      dump_one_file (0, handle, &new_name);
	    }

	  closedir (dirp);
	  ds_destroy (&new_name);
	}
    }

  if (!tar_flag)
    /* In cpio formats, we dump directories last.  */
    verbosely_copy_out_file (handle, input_name, stat_info);
}
Exemple #30
0
/*
 * When you add any new common ioctls to the switches above and below
 * please update compat_sys_ioctl() too.
 *
 * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
 * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
 */
int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
	     unsigned long arg)
{
	int error = 0;
	int __user *argp = (int __user *)arg;
#ifdef CONFIG_LTT_LITE
	char ltt_string[LTT_LITE_MAX_LOG_STRING_SIZE];

	sprintf(ltt_string, "fd=%X/cmd=%X/arg=%X/pid=%d\n", fd,
		cmd, (int)arg, current->pid);
	ltt_lite_syscall_param(LTT_EV_FILE_SYSTEM_IOCTL, ltt_string,
		strlen(ltt_string));
	sprintf(ltt_string, "f_op=%X/pid=%d\n", (int)filp->f_op, current->pid);
	ltt_lite_syscall_param(LTT_EV_FILE_SYSTEM_IOCTL, ltt_string,
		strlen(ltt_string));
#endif

	switch (cmd) {
	case FIOCLEX:
		set_close_on_exec(fd, 1);
		break;

	case FIONCLEX:
		set_close_on_exec(fd, 0);
		break;

	case FIONBIO:
		/* BKL needed to avoid races tweaking f_flags */
		lock_kernel();
		error = ioctl_fionbio(filp, argp);
		unlock_kernel();
		break;

	case FIOASYNC:
		/* BKL needed to avoid races tweaking f_flags */
		lock_kernel();
		error = ioctl_fioasync(fd, filp, argp);
		unlock_kernel();
		break;

	case FIOQSIZE:
		if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) ||
		    S_ISREG(filp->f_path.dentry->d_inode->i_mode) ||
		    S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) {
			loff_t res =
				inode_get_bytes(filp->f_path.dentry->d_inode);
			error = copy_to_user((loff_t __user *)arg, &res,
					     sizeof(res)) ? -EFAULT : 0;
		} else
			error = -ENOTTY;
		break;

	case FIFREEZE:
		error = ioctl_fsfreeze(filp);
		break;

	case FITHAW:
		error = ioctl_fsthaw(filp);
		break;

	default:
		if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
			error = file_ioctl(filp, cmd, arg);
		else
			error = vfs_ioctl(filp, cmd, arg);
		break;
	}
	return error;
}