示例#1
0
void ListView::show_file_list(file_list_t* lst)
{
    Gtk::TreeModel::Row row;

    m_refTreeModel->clear();

    for ( file_list_t::iterator a = lst->begin(); a != lst->end(); ++a ) {
        char buffer[256];
        row = *( m_refTreeModel->append() );
        sprintf( buffer, "%lu", a->size );
        row[m_Columns.m_col_name] = &( a->name[0] );
        row[m_Columns.m_col_size] = &( buffer[0] );

        row[m_Columns.m_col_permission] = get_file_mode( a->permissions ); 

        sprintf( buffer, "%s:%s", a->owner, a->group );
        row[m_Columns.m_col_users] = &( buffer[0] );

        strftime( buffer, 256, "%d/%m/%Y %T",
                localtime( &( a->last_modified.tv_sec ) ) );

        row[m_Columns.m_col_modified] = &( buffer[0] );

        strcpy( buffer, a->type );
        row[m_Columns.m_col_type] = &( buffer[0] );
    }
    lst->clear();
}
示例#2
0
void build_ustar_header_from_file(FILE_HEADER* header, char* filename) {
	struct stat buffer;
	errno = 0;

	if(stat(filename, &buffer) == 0 && errno == 0) {
		clean_up_header(header);

		get_prefix_and_name(filename, header->name, header->prefix);
		get_file_mode(header->mode, buffer.st_mode);
		get_id(header->uid, buffer.st_uid);
		get_id(header->gid, buffer.st_gid);
		get_size(header->size, buffer.st_size);
		get_modification_time(header->mtime, buffer.st_mtime);
		get_file_type(header->typeflag, buffer.st_mode);
		strcpy(header->magic, "ustar ");
		strcpy(header->version, " \0");
		get_username(header->uname, buffer.st_uid);
		get_groupname(header->gname, buffer.st_gid);
		get_device_numbers(header->devmajor, header->devminor, buffer.st_dev);
		calculate_checksum(header);
	}
	else
		fprintf(stderr, "%s '%s': %s\n", STAT_FAILURE_ERR, filename,
															strerror(errno));
}
示例#3
0
/*
** Name: PCgetexecname	    - exec the lp64 version of the running exe
**
** Description:
** 	exec the lp64 version of the running exe
**
** Inputs:
**
** Outputs:
**	none
**
** Returns:
**	STATUS
**
** History:
**	15-aug-2002 (hanch04/somsa01)
**	    Created
**	15-Jun-2004 (schka24)
**	    Watch out for buffer overrun
**	28-Apr-2005 (hanje04)
**	    Fix up prototypes to quiet warnings.
**	23-Jun-2008 (bonro01)
**	    Replace deprecated getwd() with getcwd().
*/
STATUS
PCgetexecname(char *argv0, char *buf)
{
    char	*path;

    if (*argv0 == '/')
    {
	strcpy(buf, argv0);
	return(0);
    }

    if (*argv0 == '.' && *(argv0+1) == '/')
    {
	strcpy(buf, argv0 + 2);
	goto found;
    }
    if (*argv0 == '.' && *(argv0+1) == '.' && *(argv0+2) == '/' )
    {
	strcpy(buf, argv0);
	goto found;
    }

    path = getenv("PATH");

    while(path != 0)
    {
	path = getPathElement(path, buf);
	if (*buf == '\0')
	    continue;  /* ignore empty components (::) */
	strcat(buf, "/");
	strcat(buf, argv0);
	if (access(buf, X_OK) == 0)
	{
	    /* watch out for directories that happen to match */
	    if((get_file_mode(buf) & S_IFMT) == S_IFDIR)
		continue;

	    /* Got it.  Now if it is not absolute, just prepend cwd */
	    if (*buf != '/')
	    {
		char	tmpbuf[PATH_MAX];

found:
		strcpy(tmpbuf, buf);
		if (getcwd(buf,PATH_MAX) == 0)
		    break;
		strcat(buf, "/");
		strcat(buf, tmpbuf);
	    }
	    return(0);
	}
    }

    /* Not found */
    *buf = 0;
    return(-1);
}
示例#4
0
/**
 * Opens a file in read, write, or append mode.
 *
 * @param args list of args
 * @param c number of args
 * @returns LuciFileObj opened from the filename in the first arg
 */
LuciObject *luci_fopen(LuciObject **args, unsigned int c)
{
    char *filename;
    char *req_mode;
    int mode;
    FILE *file = NULL;

    if (c < 2) {
        LUCI_DIE("%s", "Missing parameter to open()\n");
    }

    LuciObject *fname_obj = args[0];
    if (!ISTYPE(fname_obj, obj_string_t)) {
        LUCI_DIE("%s", "Parameter 1 to open must be a string\n");
    }
    LuciObject *mode_obj = args[1];
    if (!ISTYPE(mode_obj, obj_string_t)) {
        LUCI_DIE("%s", "Parameter 2 to open must be a string\n");
    }

    filename = AS_STRING(fname_obj)->s;
    req_mode = AS_STRING(mode_obj)->s;

    mode = get_file_mode(req_mode);
    if (mode < 0) {
        LUCI_DIE("%s\n", "Invalid mode to open()");
    }

    /*
       Open in read-binary mode and fseek to SEEK_END to
       calculate the file's size in bytes.
       Then close it and reopen it the way the user requests
    */
    long file_length;
    /* store the FILE's byte length */
    if (!(file = fopen(filename, "rb"))) {
        file_length = 0;
    }
    else {
        fseek(file, 0, SEEK_END);
        file_length = ftell(file);
        fseek(file, 0, SEEK_SET);
        close_file(file);
    }

    if (!(file = fopen(filename, req_mode)))
    {
        LUCI_DIE("Could not open file %s\n", filename);
    }

    LuciObject *ret = LuciFile_new(file, file_length, mode);

    LUCI_DEBUG("Opened file %s of size %ld bytes with mode %s.\n",
            filename, file_length, req_mode);

    return ret;
}
示例#5
0
文件: gfreg.c 项目: krichter722/gfarm
static void
register_fragment(int is_dir, char *gfarm_url, int index, int nfragments,
	char *hostname,
	char *filename, int use_file_mode, gfarm_mode_t file_mode)
{
	char *e;
	int fd, fd_needs_close;
	char *target_url;
	GFS_File gf;
	char section[GFARM_INT32STRLEN + 1];

	if (!open_file(filename, &fd, &fd_needs_close))
		return;
	if (!use_file_mode && !get_file_mode(fd, filename, &file_mode))
		goto finish;

	if (!is_dir)
		target_url = gfarm_url;
	else if (!concat_dir_name(gfarm_url, gfarm_path_dir_skip(filename),
	    &target_url))
		goto finish;

	if (nfragments == GFARM_FILE_DONTCARE &&
	    !get_nsections(target_url, &nfragments))
		goto finish_url;

	sprintf(section, "%d", index);
	if (opt_force || section_does_not_exists(target_url, section)) {
		e = gfs_pio_create(target_url,
		    GFARM_FILE_WRONLY|GFARM_FILE_TRUNC, file_mode, &gf);
		if (e != NULL) {
			fprintf(stderr, "%s: cannot open %s: %s\n",
			    program_name, target_url, e);
			error_happened = 1;
		} else {
			if ((e = gfs_pio_set_view_index(gf, nfragments, index,
			    hostname, 0)) != NULL) {
				fprintf(stderr, "%s: cannot open %s:%d: %s\n",
				    program_name, target_url, index, e);
				error_happened = 1;
			} else {
				copy_file(fd, gf, target_url, section);
			}
			gfs_pio_close(gf);
		}
	}
 finish_url:
	if (target_url != gfarm_url)
		free(target_url);
 finish:
	if (fd_needs_close)
		close(fd);
}
示例#6
0
文件: gfreg.c 项目: krichter722/gfarm
static void
register_program(int is_dir, char *gfarm_url, char *section, char *hostname,
	char *filename, int use_file_mode, gfarm_mode_t file_mode)
{
	char *e;
	int fd, fd_needs_close;
	char *target_url;
	GFS_File gf;

	if (!open_file(filename, &fd, &fd_needs_close))
		return;
	if (!use_file_mode && !get_file_mode(fd, filename, &file_mode))
		goto finish;

	if (!is_dir)
		target_url = gfarm_url;
	else if (!concat_dir_name(gfarm_url, gfarm_path_dir_skip(filename),
	    &target_url))
		goto finish;

	if (opt_force || section_does_not_exists(target_url, section)) {
		e = gfs_pio_create(target_url,
		    GFARM_FILE_WRONLY|GFARM_FILE_TRUNC, file_mode, &gf);
		if (e != NULL) {
			fprintf(stderr, "%s: cannot open %s: %s\n",
			    program_name, target_url, e);
			error_happened = 1;
		} else {
			if ((e = gfs_pio_set_view_section(gf, section,
			    hostname, 0)) != NULL) {
				fprintf(stderr, "%s: cannot open %s:%s: %s\n",
				    program_name, target_url, section, e);
				error_happened = 1;
			} else {
				copy_file(fd, gf, target_url, section);
			}
			gfs_pio_close(gf);
		}
	}
	if (target_url != gfarm_url)
		free(target_url);
 finish:
	if (fd_needs_close)
		close(fd);
}
示例#7
0
int main(int argc, char *argv[])
{
	struct stat info;
	char buf[100], *p = buf;
	
	if (argc != 2)
	{
		fprintf(stderr, "Usage:ls filename\n");
		return;
	}
	memset(buf, 0, sizeof(buf));
	
	if (lstat(argv[1], &info) == 0)
	{
		p += get_file_type(info.st_mode, p);
		p += get_file_mode(info.st_mode, p);
		p += get_file_others(&info, p);
		printf("%s %s\n", buf, argv[1]);
	}
	else
		fprintf(stderr, "Open file failed.\n");
	return 0;
}
示例#8
0
文件: tools.c 项目: dimkr/beaver
void file_info (gint CurrentPage)
{
  GtkWidget *FileInfoWindow;
  GtkWidget *Button;
  GtkWidget *HBox;
  GtkWidget *FileInfoLabelLeft, *FileInfoLabelRight;
  gint BufferSize, FileSize, Difference;
  gboolean NewFile = FALSE;
  
  if (!OpenedFilesCnt) return;
  if (stat (FPROPS(CurrentPage, Name), &FPROPS(CurrentPage, Stats)) == -1)
    NewFile = TRUE;
  BufferSize = gtk_text_get_length (GTK_TEXT(FPROPS(CurrentPage, Text)));
  FileSize = NewFile ? 0 : (gint)FPROPS(CurrentPage, Stats).st_size;
  Difference = BufferSize - FileSize;
  FileInfoWindow = gtk_dialog_new ();
  gtk_window_set_title (GTK_WINDOW(FileInfoWindow), "File Information"); 
  gtk_window_set_policy (GTK_WINDOW(FileInfoWindow), FALSE, FALSE, FALSE);
  gtk_signal_connect_object (GTK_OBJECT(FileInfoWindow), "delete_event",
			     (GtkSignalFunc) gtk_widget_destroy,
			     GTK_OBJECT(FileInfoWindow));
  gtk_signal_connect_object (GTK_OBJECT (FileInfoWindow), "destroy",
			     (GtkSignalFunc) gtk_widget_destroy,
			     GTK_OBJECT(FileInfoWindow));
  HBox = gtk_hbox_new (FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER(HBox), 5);
  FileInfoLabelLeft = gtk_label_new
    ("Base name :"
     "\nFull name :"
     "\nLanguage :"
     "\n"
     "\nModified :"
     "\nReadonly :"
     "\n"
     "\nBuffer Size :"
     "\nFile Size :"
     "\nDifference :"
#ifndef WIN32
     "\n"
     "\nPermissions :"
     "\nOwner UID :"
     "\nOwner GID :"
#endif
       );
  gtk_label_set_justify (GTK_LABEL(FileInfoLabelLeft), GTK_JUSTIFY_LEFT); 
  FileInfoLabelRight = gtk_label_new
    (g_strconcat
     (FPROPS(CurrentPage, BaseName),
      "\n", FPROPS(CurrentPage, Name),
      "\n", FPROPS(CurrentPage, WidgetInfo.Lg) == -1 ?
      UNKNOWN : Prefs.L[FPROPS(CurrentPage, WidgetInfo.Lg)].Description,
      "\n",
      "\n", FPROPS(CurrentPage, Changed[0]) ? "Yes" : "No",
      "\n", FPROPS(CurrentPage, ReadOnly) ? "Yes" : "No",
      "\n",
      "\n", g_strdup_printf ("%d", BufferSize),
      ((BufferSize == -1) || (BufferSize == 0) || (BufferSize == 1)) ?
      " Byte" : " Bytes",
      "\n", g_strdup_printf ("%d", FileSize),
      ((FileSize == -1) || (FileSize == 0) || (FileSize == 1)) ?
      " Byte" : " Bytes",
      "\n", g_strdup_printf ("%d", Difference),
      ((Difference == -1) || (Difference == 0) || (Difference == 1)) ?
      " Byte" : " Bytes",
#ifndef WIN32
      "\n",
      "\n", NewFile ?
      UNKNOWN : get_file_mode (FPROPS(CurrentPage, Stats)),
      "\n", NewFile ?
      UNKNOWN : g_strdup_printf ("%d", FPROPS(CurrentPage, Stats).st_uid),
      "\n", NewFile ?
      UNKNOWN : g_strdup_printf ("%d", FPROPS(CurrentPage, Stats).st_gid),
#endif
      NULL));
  gtk_label_set_justify (GTK_LABEL(FileInfoLabelRight), GTK_JUSTIFY_LEFT);
  gtk_box_pack_start (GTK_BOX(HBox), FileInfoLabelLeft, FALSE, FALSE, 5);
  gtk_box_pack_start (GTK_BOX(HBox), FileInfoLabelRight, FALSE, FALSE, 5);
  gtk_box_pack_start (GTK_BOX(GTK_DIALOG(FileInfoWindow) -> vbox),
		      HBox, FALSE, FALSE, 5);
  Button = gtk_button_new_with_label (" Close ");
  gtk_signal_connect_object (GTK_OBJECT(Button), "clicked",
			     (GtkSignalFunc) gtk_widget_destroy,
			     GTK_OBJECT(FileInfoWindow));
  GTK_WIDGET_SET_FLAGS (Button, GTK_CAN_DEFAULT);
  gtk_box_pack_start (GTK_BOX(GTK_DIALOG(FileInfoWindow) -> action_area),
		      Button, TRUE, TRUE, 0);
  gtk_widget_grab_default (Button);
  gtk_widget_show_all (FileInfoWindow);
  print_msg ("Display File Information window...");
}
示例#9
0
MULTI_FILE *open_multi_file(const char *path)
{
	__int64 len;
	
	MULTI_FILE *r;
	MF_PRIVATE_DATA *prv;
	int fd;

	int i,n;
	char *work;
	void *tmp;

	int mode;
	
	r = (MULTI_FILE *)calloc(1, sizeof(MULTI_FILE));
	if(r == NULL){
		return NULL;
	}

	prv = (MF_PRIVATE_DATA *)calloc(1, sizeof(MF_PRIVATE_DATA));
	if(prv == NULL){
		free(r);
		return NULL;
	}

	fd = _open(path, _O_BINARY|_O_RDONLY|_O_SEQUENTIAL);
	if(fd < 0){
		free(prv);
		free(r);
		return NULL;
	}

	n = strlen(path)+1;
	work = (char *)malloc(n);
	if(work == NULL){
		_close(fd);
		free(prv);
		free(r);
		return NULL;
	}
	memcpy(work, path, n);
	
	prv->info = (MF_FILE_INFO *)malloc(sizeof(MF_FILE_INFO));
	if(prv->info == NULL){
		free(work);
		_close(fd);
		free(prv);
		free(r);
		return NULL;
	}

	mode = get_file_mode();

	while(fd >= 0){
		tmp = realloc(prv->info, sizeof(MF_FILE_INFO)*(prv->count+1));
		if(tmp == NULL){
			_close(fd);
			fd = -1;
			break;
		}
		prv->info = (MF_FILE_INFO *)tmp;

		len = _lseeki64(fd, 0, SEEK_END);
		_lseeki64(fd, 0, SEEK_SET);
		_close(fd);
		
		i = prv->count;

		prv->info[i].length = len;
		prv->info[i].offset = prv->total;
		prv->info[i].fd = -1;
		prv->info[i].path = malloc(n);
		if(prv->info[i].path == NULL){
			break;
		}
		memcpy(prv->info[i].path, work, n);
		
		prv->total += len;

		prv->count += 1;

		if(mode & M2V_CONFIG_MULTI_FILE){
			fd = try_next(work);
		}else{
			fd = -1;
		}
	}

	if(prv->count == 0){
		free(prv->info);
		free(work);
		if(fd >= 0){
			_close(fd);
		}
		free(prv);
		free(r);
		return NULL;
	}

	free(work);

	r->private_data = prv;
	r->close = mf_close;
	if(prv->count == 1){
		r->tell = sf_tell;
		r->seek = sf_seek;
		r->read = sf_read;
		prv->info[0].fd = _open(prv->info[0].path, _O_BINARY|_O_RDONLY|_O_SEQUENTIAL);
	}else{
		r->tell = mf_tell;
		r->seek = mf_seek;
		r->read = mf_read;
	}
	r->count = mf_count;
	r->border = mf_border;
	
	return r;
}
示例#10
0
static void
setup_newroot (bool unshare_pid,
               int privileged_op_socket)
{
  SetupOp *op;

  for (op = ops; op != NULL; op = op->next)
    {
      cleanup_free char *source = NULL;
      cleanup_free char *dest = NULL;
      int source_mode = 0;
      int i;

      if (op->source &&
          op->type != SETUP_MAKE_SYMLINK)
        {
          source = get_oldroot_path (op->source);
          source_mode = get_file_mode (source);
          if (source_mode < 0)
            die_with_error ("Can't get type of source %s", op->source);
        }

      if (op->dest)
        {
          dest = get_newroot_path (op->dest);
          if (mkdir_with_parents (dest, 0755, FALSE) != 0)
            die_with_error ("Can't mkdir parents for %s", op->dest);
        }

      switch (op->type) {
      case SETUP_RO_BIND_MOUNT:
      case SETUP_DEV_BIND_MOUNT:
      case SETUP_BIND_MOUNT:
        if (source_mode == S_IFDIR)
          {
            if (mkdir (dest, 0755) != 0 && errno != EEXIST)
              die_with_error ("Can't mkdir %s", op->dest);
          }
        else
          {
            if (ensure_file (dest, 0666) != 0)
              die_with_error ("Can't create file at %s", op->dest);
          }

        privileged_op (privileged_op_socket,
                       PRIV_SEP_OP_BIND_MOUNT,
                       (op->type == SETUP_RO_BIND_MOUNT ? BIND_READONLY : 0) |
                       (op->type == SETUP_DEV_BIND_MOUNT ? BIND_DEVICES : 0),
                       source, dest);
        break;

      case SETUP_MOUNT_PROC:
        if (mkdir (dest, 0755) != 0 && errno != EEXIST)
          die_with_error ("Can't mkdir %s", op->dest);

        if (unshare_pid)
          {
            /* Our own procfs */
            privileged_op (privileged_op_socket,
                           PRIV_SEP_OP_PROC_MOUNT, 0,
                           dest, NULL);
          }
        else
          {
            /* Use system procfs, as we share pid namespace anyway */
            privileged_op (privileged_op_socket,
                           PRIV_SEP_OP_BIND_MOUNT, 0,
                           "oldroot/proc", dest);
          }

        /* There are a bunch of weird old subdirs of /proc that could potentially be
           problematic (for instance /proc/sysrq-trigger lets you shut down the machine
           if you have write access). We should not have access to these as a non-privileged
           user, but lets cover them anyway just to make sure */
        const char *cover_proc_dirs[] = { "sys", "sysrq-trigger", "irq", "bus" };
        for (i = 0; i < N_ELEMENTS (cover_proc_dirs); i++)
          {
            cleanup_free char *subdir = strconcat3 (dest, "/", cover_proc_dirs[i]);
            privileged_op (privileged_op_socket,
                           PRIV_SEP_OP_BIND_MOUNT, BIND_READONLY,
                           subdir, subdir);
          }

        break;

      case SETUP_MOUNT_DEV:
        if (mkdir (dest, 0755) != 0 && errno != EEXIST)
          die_with_error ("Can't mkdir %s", op->dest);

        privileged_op (privileged_op_socket,
                       PRIV_SEP_OP_TMPFS_MOUNT, 0,
                       dest, NULL);

        static const char *const devnodes[] = { "null", "zero", "full", "random", "urandom", "tty" };
        for (i = 0; i < N_ELEMENTS (devnodes); i++)
          {
            cleanup_free char *node_dest = strconcat3 (dest, "/", devnodes[i]);
            cleanup_free char *node_src = strconcat ("/oldroot/dev/", devnodes[i]);
            if (create_file (node_dest, 0666, NULL) != 0)
              die_with_error ("Can't create file %s/%s", op->dest, devnodes[i]);
            privileged_op (privileged_op_socket,
                           PRIV_SEP_OP_BIND_MOUNT, BIND_DEVICES,
                           node_src, node_dest);
          }

        static const char *const stdionodes[] = { "stdin", "stdout", "stderr" };
        for (i = 0; i < N_ELEMENTS (stdionodes); i++)
          {
            cleanup_free char *target = xasprintf ("/proc/self/fd/%d", i);
            cleanup_free char *node_dest = strconcat3 (dest, "/", stdionodes[i]);
            if (symlink (target, node_dest) < 0)
              die_with_error ("Can't create symlink %s/%s", op->dest, stdionodes[i]);
          }

        {
          cleanup_free char *pts = strconcat (dest, "/pts");
          cleanup_free char *ptmx = strconcat (dest, "/ptmx");
          cleanup_free char *shm = strconcat (dest, "/shm");

          if (mkdir (shm, 0755) == -1)
            die_with_error ("Can't create %s/shm", op->dest);

          if (mkdir (pts, 0755) == -1)
            die_with_error ("Can't create %s/devpts", op->dest);
          privileged_op (privileged_op_socket,
                         PRIV_SEP_OP_DEVPTS_MOUNT, BIND_DEVICES,
                         pts, NULL);

          if (symlink ("pts/ptmx", ptmx) != 0)
            die_with_error ("Can't make symlink at %s/ptmx", op->dest);
        }

        /* If stdout is a tty, that means the sandbox can write to the
           outside-sandbox tty. In that case we also create a /dev/console
           that points to this tty device. This should not cause any more
           access than we already have, and it makes ttyname() work in the
           sandbox. */
        if (host_tty_dev != NULL && *host_tty_dev != 0)
          {
            cleanup_free char *src_tty_dev = strconcat ("/oldroot", host_tty_dev);
            cleanup_free char *dest_console = strconcat (dest, "/console");

            if (create_file (dest_console, 0666, NULL) != 0)
              die_with_error ("creating %s/console", op->dest);

            privileged_op (privileged_op_socket,
                           PRIV_SEP_OP_BIND_MOUNT, BIND_DEVICES,
                           src_tty_dev, dest_console);
          }

        break;

      case SETUP_MOUNT_TMPFS:
        if (mkdir (dest, 0755) != 0 && errno != EEXIST)
          die_with_error ("Can't mkdir %s", op->dest);

        privileged_op (privileged_op_socket,
                       PRIV_SEP_OP_TMPFS_MOUNT, 0,
                       dest, NULL);
        break;
      case SETUP_MOUNT_MQUEUE:
        if (mkdir (dest, 0755) != 0 && errno != EEXIST)
          die_with_error ("Can't mkdir %s", op->dest);

        privileged_op (privileged_op_socket,
                       PRIV_SEP_OP_MQUEUE_MOUNT, 0,
                       dest, NULL);
        break;
      case SETUP_MAKE_DIR:
        if (mkdir (dest, 0755) != 0 && errno != EEXIST)
          die_with_error ("Can't mkdir %s", op->dest);

        break;

      case SETUP_MAKE_FILE:
        {
          cleanup_fd int dest_fd = -1;

          dest_fd = creat (dest, 0666);
          if (dest_fd == -1)
            die_with_error ("Can't create file %s", op->dest);

          if (copy_file_data (op->fd, dest_fd) != 0)
            die_with_error ("Can't write data to file %s", op->dest);

          close (op->fd);
        }
        break;

      case SETUP_MAKE_BIND_FILE:
        {
          cleanup_fd int dest_fd = -1;
          char tempfile[] = "/bindfileXXXXXX";

          dest_fd = mkstemp (tempfile);
          if (dest_fd == -1)
            die_with_error ("Can't create tmpfile for %s", op->dest);

          if (copy_file_data (op->fd, dest_fd) != 0)
            die_with_error ("Can't write data to file %s", op->dest);

          close (op->fd);

          if (ensure_file (dest, 0666) != 0)
            die_with_error ("Can't create file at %s", op->dest);

          privileged_op (privileged_op_socket,
                         PRIV_SEP_OP_BIND_MOUNT,
                         0, tempfile, dest);
        }
        break;

      case SETUP_MAKE_SYMLINK:
        if (symlink (op->source, dest) != 0)
          die_with_error ("Can't make symlink at %s", op->dest);
        break;

      default:
        die ("Unexpected type %d", op->type);
      }
    }
  privileged_op (privileged_op_socket,
                 PRIV_SEP_OP_DONE, 0, NULL, NULL);
}