コード例 #1
0
ファイル: gvfsbackendtest.c プロジェクト: GNOME/gvfs
static void
do_query_info_on_read (GVfsBackend *backend,
		       GVfsJobQueryInfoRead *job,
		       GVfsBackendHandle handle,
		       GFileInfo *info,
		       GFileAttributeMatcher *attribute_matcher)
{
  int fd, res;
  struct stat statbuf;
    
  fd = GPOINTER_TO_INT (handle);

  res = fstat (fd, &statbuf);

  if (res == -1)
    {
      int errsv = errno;

      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
			g_io_error_from_errno (errsv),
			"Error querying info in file: %s",
			g_strerror (errsv));
    }
  else
    {
      g_file_info_set_size (info, statbuf.st_size);
      g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE,
					statbuf.st_dev);
      g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED, statbuf.st_mtime);
      g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS, statbuf.st_atime);
      g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED, statbuf.st_ctime);

      g_vfs_job_succeeded (G_VFS_JOB (job));
    }
}
コード例 #2
0
ファイル: ostree-core.c プロジェクト: aperezdc/ostree
gboolean
ostree_zlib_file_header_parse (GVariant         *metadata,
                               GFileInfo       **out_file_info,
                               GVariant        **out_xattrs,
                               GError          **error)
{
  gboolean ret = FALSE;
  guint64 size;
  guint32 uid, gid, mode, rdev;
  const char *symlink_target;
  ot_lobj GFileInfo *ret_file_info = NULL;
  ot_lvariant GVariant *ret_xattrs = NULL;

  g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size,
                 &uid, &gid, &mode, &rdev,
                 &symlink_target, &ret_xattrs);

  size = GUINT64_FROM_BE (size);
  uid = GUINT32_FROM_BE (uid);
  gid = GUINT32_FROM_BE (gid);
  mode = GUINT32_FROM_BE (mode);
  rdev = GUINT32_FROM_BE (rdev);

  ret_file_info = g_file_info_new ();
  g_file_info_set_size (ret_file_info, size);
  g_file_info_set_attribute_uint32 (ret_file_info, "standard::type", ot_gfile_type_for_mode (mode));
  g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", S_ISLNK (mode));
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", uid);
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", gid);
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::mode", mode);

  if (S_ISREG (mode))
    {
      ;
    }
  else if (S_ISLNK (mode))
    {
      g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", symlink_target);
    }
  else if (S_ISCHR (mode) || S_ISBLK (mode))
    {
      g_file_info_set_attribute_uint32 (ret_file_info, "unix::rdev", rdev);
    }
  else if (S_ISFIFO (mode))
    {
      ;
    }
  else
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Corrupted archive file; invalid mode %u", mode);
      goto out;
    }

  ret = TRUE;
  ot_transfer_out_value(out_file_info, &ret_file_info);
  ot_transfer_out_value(out_xattrs, &ret_xattrs);
 out:
  return ret;
}
コード例 #3
0
static void
list_photos_ready_cb (GObject      *source_object,
		      GAsyncResult *result,
		      gpointer      user_data)
{
	DialogData *data = user_data;
	GError     *error = NULL;
	GList      *list;
	GList      *scan;

	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);

	_g_object_list_unref (data->photos);
	data->photos = flickr_service_list_photos_finish (data->service, result, &error);
	if (error != NULL) {
		if (data->service != NULL)
			gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the photo list"), error);
		g_clear_error (&error);
		gtk_widget_destroy (data->dialog);
		return;
	}

	list = NULL;
	for (scan = data->photos; scan; scan = scan->next) {
		FlickrPhoto *photo = scan->data;
		GthFileData *file_data;

		if (photo->url[FLICKR_URL_O] == NULL)
			continue;

		file_data = gth_file_data_new_for_uri (photo->url[FLICKR_URL_O], (photo->mime_type != NULL) ? photo->mime_type : "image/jpeg");
		g_file_info_set_file_type (file_data->info, G_FILE_TYPE_REGULAR);
		g_file_info_set_size (file_data->info, FAKE_SIZE); /* set a fake size to make the progress dialog work correctly */
		g_file_info_set_attribute_object (file_data->info, "flickr::object", G_OBJECT (photo));

		list = g_list_prepend (list, file_data);
	}
	gth_file_list_set_files (GTH_FILE_LIST (data->file_list), list);
	update_selection_status (data);
	gtk_widget_set_sensitive (GET_WIDGET ("download_button"), list != NULL);

	_g_object_list_unref (list);
}
コード例 #4
0
static void
list_photos_ready_cb (GObject      *source_object,
		      GAsyncResult *result,
		      gpointer      user_data)
{
	DialogData *data = user_data;
	GError     *error = NULL;
	GList      *list;
	GList      *scan;

	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);

	_g_object_list_unref (data->photos);
	data->photos = facebook_service_list_photos_finish (data->service, result, &error);
	if (error != NULL) {
		if (data->service != NULL)
			gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the photo list"), error);
		g_clear_error (&error);
		gtk_widget_destroy (data->dialog);
		return;
	}

	list = NULL;
	for (scan = data->photos; scan; scan = scan->next) {
		FacebookPhoto *photo = scan->data;
		GthFileData   *file_data;

		file_data = gth_file_data_new_for_uri (facebook_photo_get_original_url (photo), "image/jpeg");
		g_file_info_set_file_type (file_data->info, G_FILE_TYPE_REGULAR);
		g_file_info_set_size (file_data->info, FAKE_SIZE); /* set a fake size to make the progress dialog work correctly */
		g_file_info_set_attribute_object (file_data->info, "facebook::object", G_OBJECT (photo));

		list = g_list_prepend (list, file_data);
	}
	gth_file_list_set_files (GTH_FILE_LIST (data->file_list), list);
	update_selection_status (data);
	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, list != NULL);

	_g_object_list_unref (list);
}
コード例 #5
0
static void
list_photos_ready_cb (GObject      *source_object,
		      GAsyncResult *result,
		      gpointer      user_data)
{
	DialogData       *data = user_data;
	PicasaWebService *picasaweb = PICASA_WEB_SERVICE (source_object);
	GError           *error = NULL;
	GList            *list;
	GList            *scan;

	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
	_g_object_list_unref (data->photos);
	data->photos = picasa_web_service_list_albums_finish (picasaweb, result, &error);
	if (error != NULL) {
		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the photo list"), error);
		g_clear_error (&error);
		gtk_widget_destroy (data->dialog);
		return;
	}

	list = NULL;
	for (scan = data->photos; scan; scan = scan->next) {
		PicasaWebPhoto *photo = scan->data;
		GthFileData    *file_data;

		file_data = gth_file_data_new_for_uri (photo->uri, photo->mime_type);
		g_file_info_set_file_type (file_data->info, G_FILE_TYPE_REGULAR);
		g_file_info_set_size (file_data->info, photo->size);
		g_file_info_set_attribute_object (file_data->info, "gphoto::object", G_OBJECT (photo));

		list = g_list_prepend (list, file_data);
	}
	gth_file_list_set_files (GTH_FILE_LIST (data->file_list), list);
	update_selection_status (data);
	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, TRUE);

	_g_object_list_unref (list);
}
コード例 #6
0
ファイル: gresourcefile.c プロジェクト: adesurya/gst-mobile
static GFileInfo *
g_resource_file_query_info (GFile                *file,
			    const char           *attributes,
			    GFileQueryInfoFlags   flags,
			    GCancellable         *cancellable,
			    GError              **error)
{
  GResourceFile *resource = G_RESOURCE_FILE (file);
  GError *my_error = NULL;
  GFileInfo *info;
  GFileAttributeMatcher *matcher;
  gboolean res;
  gsize size;
  guint32 resource_flags;
  char **children;
  gboolean is_dir;
  char *base;

  is_dir = FALSE;
  children = g_resources_enumerate_children (resource->path, 0, NULL);
  if (children != NULL)
    {
      g_strfreev (children);
      is_dir = TRUE;
    }

  /* root is always there */
  if (strcmp ("/", resource->path) == 0)
    is_dir = TRUE;

  if (!is_dir)
    {
      res = g_resources_get_info (resource->path, 0, &size, &resource_flags, &my_error);
      if (!res)
	{
	  if (g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND))
	    {
	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
			   _("The resource at '%s' does not exist"),
			   resource->path);
	    }
	  else
	    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                 my_error->message);
	  g_clear_error (&my_error);
	  return FALSE;
	}
    }

  matcher = g_file_attribute_matcher_new (attributes);

  info = g_file_info_new ();
  base = g_resource_file_get_basename (file);
  g_file_info_set_name (info, base);

  _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_READ, TRUE);
  _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_WRITE, FALSE);
  _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_EXECUTE, FALSE);
  _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME, FALSE);
  _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE, FALSE);
  _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH, FALSE);

  if (is_dir)
    {
      g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
    }
  else
    {
      GBytes *bytes;
      char *content_type;

      g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR);
      g_file_info_set_size (info, size);

      if ((_g_file_attribute_matcher_matches_id (matcher, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE) ||
           ((~resource_flags & G_RESOURCE_FLAGS_COMPRESSED) && 
            _g_file_attribute_matcher_matches_id (matcher, G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE))) &&
          (bytes = g_resources_lookup_data (resource->path, 0, NULL)))
        {
          const guchar *data;
          gsize data_size;

          data = g_bytes_get_data (bytes, &data_size);
          content_type = g_content_type_guess (base, data, data_size, NULL);

          g_bytes_unref (bytes);
        }
      else
        content_type = NULL;

      if (content_type)
        {
          _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE, content_type);
          _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE, content_type);

          g_free (content_type);
        }
    }

  g_free (base);
  g_file_attribute_matcher_unref (matcher);

  return info;
}
コード例 #7
0
ファイル: gvfsbackendhttp.c プロジェクト: GNOME/gvfs
static void
file_info_from_message (SoupMessage *msg,
                        GFileInfo *info,
                        GFileAttributeMatcher *matcher)
{
  const char *text;
  GHashTable *params;
  char       *basename;
  char       *ed_name;

  basename = ed_name = NULL;

  /* prefer the filename from the Content-Disposition (rfc2183) header
     if one if present. See bug 551298. */
  if (soup_message_headers_get_content_disposition (msg->response_headers,
                                                    NULL, &params))
    {
      const char *name = g_hash_table_lookup (params, "filename");

      if (name)
        basename = g_strdup (name);

      g_hash_table_destroy (params);
    }

  if (basename == NULL)
    {
      const SoupURI *uri;

      uri = soup_message_get_uri (msg);
      basename = http_uri_get_basename (uri->path);
    }

  g_debug ("basename:%s\n", basename);

  /* read http/1.1 rfc, until then we copy the local files
   * behaviour */
  if (basename != NULL &&
      (g_file_attribute_matcher_matches (matcher,
                                         G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME) ||
       g_file_attribute_matcher_matches (matcher,
                                         G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME)))
    ed_name = gvfs_file_info_populate_names_as_local (info, basename);

  g_free (basename);
  g_free (ed_name);

  if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_CONTENT_LENGTH)
    {
      goffset start, end, length;
      gboolean ret;

      ret = soup_message_headers_get_content_range (msg->response_headers,
                                                    &start, &end, &length);
      if (ret && length != -1)
        {
          g_file_info_set_size (info, length);
        }
      else if (!ret)
        {
          length = soup_message_headers_get_content_length (msg->response_headers);
          g_file_info_set_size (info, length);
        }
    }

  g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR);

  text = soup_message_headers_get_content_type (msg->response_headers, NULL);
  if (text)
    {
      GIcon *icon;

      g_file_info_set_content_type (info, text);
      g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, text);

      icon = g_content_type_get_icon (text);
      g_file_info_set_icon (info, icon);
      g_object_unref (icon);

      icon = g_content_type_get_symbolic_icon (text);
      g_file_info_set_symbolic_icon (info, icon);
      g_object_unref (icon);
    }


  text = soup_message_headers_get_one (msg->response_headers,
                                       "Last-Modified");
  if (text)
    {
      SoupDate *sd;
      GTimeVal tv;

      sd = soup_date_new_from_string(text);
      if (sd)
        {
          soup_date_to_timeval (sd, &tv);
	  g_file_info_set_modification_time (info, &tv);
          soup_date_free (sd);
        }
    }


  text = soup_message_headers_get_one (msg->response_headers,
                                       "ETag");
  if (text)
    {
      g_file_info_set_attribute_string (info,
                                        G_FILE_ATTRIBUTE_ETAG_VALUE,
                                        text);
    }
}
コード例 #8
0
static gboolean
dispatch_open_splice_and_close (OstreeRepo                 *repo,
                                StaticDeltaExecutionState  *state,
                                GCancellable               *cancellable,  
                                GError                    **error)
{
  gboolean ret = FALSE;

  if (!open_output_target (state, cancellable, error))
    goto out;

  if (OSTREE_OBJECT_TYPE_IS_META (state->output_objtype))
    {
      g_autoptr(GVariant) metadata = NULL;
      guint64 offset;
      guint64 length;

      if (!read_varuint64 (state, &length, error))
        goto out;
      if (!read_varuint64 (state, &offset, error))
        goto out;
      if (!validate_ofs (state, offset, length, error))
        goto out;

      if (state->stats_only)
        {
          ret = TRUE;
          goto out;
        }
      
      metadata = g_variant_new_from_data (ostree_metadata_variant_type (state->output_objtype),
                                          state->payload_data + offset, length, TRUE, NULL, NULL);

      {
        g_autofree guchar *actual_csum = NULL;

        if (!ostree_repo_write_metadata (state->repo, state->output_objtype,
                                         state->checksum,
                                         metadata, &actual_csum,
                                         cancellable,
                                         error))
          goto out;
      }
    }
  else
    {
      guint64 content_offset;
      guint64 objlen;
      g_autoptr(GInputStream) object_input = NULL;
      g_autoptr(GInputStream) memin = NULL;
      
      if (!do_content_open_generic (repo, state, cancellable, error))
        goto out;

      if (!read_varuint64 (state, &state->content_size, error))
        goto out;
      if (!read_varuint64 (state, &content_offset, error))
        goto out;
      if (!validate_ofs (state, content_offset, state->content_size, error))
        goto out;
      
      if (state->stats_only)
        {
          ret = TRUE;
          goto out;
        }

      /* Fast path for regular files to bare repositories */
      if (S_ISREG (state->mode) && 
          (repo->mode == OSTREE_REPO_MODE_BARE ||
           repo->mode == OSTREE_REPO_MODE_BARE_USER))
        {
          if (!_ostree_repo_open_content_bare (repo, state->checksum,
                                               state->content_size,
                                               &state->barecommitstate,
                                               &state->content_out,
                                               &state->have_obj,
                                               cancellable, error))
            goto out;

          if (!state->have_obj)
            {
              if (!handle_untrusted_content_checksum (repo, state, cancellable, error))
                goto out;

              if (!content_out_write (repo, state,
                                      state->payload_data + content_offset,
                                      state->content_size,
                                      cancellable, error))
                goto out;
            }
        }
      else
        {
          /* Slower path, for symlinks and unpacking deltas into archive-z2 */
          g_autoptr(GFileInfo) finfo = NULL;
      
          finfo = _ostree_header_gfile_info_new (state->mode, state->uid, state->gid);

          if (S_ISLNK (state->mode))
            {
              g_autofree char *nulterminated_target =
                g_strndup ((char*)state->payload_data + content_offset, state->content_size);
              g_file_info_set_symlink_target (finfo, nulterminated_target);
            }
          else
            {
              g_assert (S_ISREG (state->mode));
              g_file_info_set_size (finfo, state->content_size);
              memin = g_memory_input_stream_new_from_data (state->payload_data + content_offset, state->content_size, NULL);
            }

          if (!ostree_raw_file_to_content_stream (memin, finfo, state->xattrs,
                                                  &object_input, &objlen,
                                                  cancellable, error))
            goto out;

          {
            g_autofree guchar *actual_csum = NULL;
            if (!ostree_repo_write_content (state->repo,
                                            state->checksum,
                                            object_input,
                                            objlen,
                                            &actual_csum,
                                            cancellable,
                                            error))
              goto out;
          }
        }
    }

  if (!dispatch_close (repo, state, cancellable, error))
    goto out;

  ret = TRUE;
 out:
  if (state->stats_only)
    (void) dispatch_close (repo, state, cancellable, NULL);
  if (!ret)
    g_prefix_error (error, "opcode open-splice-and-close: ");
  return ret;
}
コード例 #9
0
static gboolean
fl_parser_fill_file_info (GFileInfo *info, const char **attr)
{
	gint i;
	
	for (i = 0; attr[i]; ++i) {
		const gchar *name;
		const gchar *value;

		name  = attr[i];
		value = attr[++i];
		
		if (strcmp (name, "name") == 0) {
			char *display_name;
			/* Apparently someone decided it was a good idea
			 * to send name="" mem-type="MMC" 
			 */
			if (!value || strcmp (value, "") == 0) {
				return FALSE;
			}

			g_file_info_set_name (info, value);
			display_name = g_filename_display_name (value);
			g_file_info_set_display_name (info, display_name);
			d(g_print ("Name: '%s'\n", display_name));
			g_free (display_name);
		}
		else if (strcmp (name, "size") == 0) {
			g_file_info_set_size (info, strtoll (value, NULL, 10));
			d(g_print ("Size: '%"G_GINT64_FORMAT"'\n", g_file_info_get_size (info)));
		}
		else if (strcmp (name, "modified") == 0) {
			GTimeVal time;

			if (g_time_val_from_iso8601 (value, &time) == FALSE)
				continue;
			g_file_info_set_modification_time (info, &time);
			d(g_print ("Modified: '%s' = '%d'\n", 
				   value, (int)time.tv_sec));
		}
		else if (strcmp (name, "created") == 0) {
			GTimeVal time;

			if (g_time_val_from_iso8601 (value, &time) == FALSE)
				continue;
			g_file_info_set_attribute_uint64 (info,
							  G_FILE_ATTRIBUTE_TIME_CREATED,
							  time.tv_sec);
			g_file_info_set_attribute_uint32 (info,
							  G_FILE_ATTRIBUTE_TIME_CREATED_USEC,
							  time.tv_usec);
			d(g_print ("Created: '%s' = '%d'\n", 
				   value, (int)time.tv_sec));
		}
		else if (strcmp (name, "accessed") == 0) {
			GTimeVal time;

			if (g_time_val_from_iso8601 (value, &time) == FALSE)
				continue;
			g_file_info_set_attribute_uint64 (info,
							  G_FILE_ATTRIBUTE_TIME_ACCESS,
							  time.tv_sec);
			g_file_info_set_attribute_uint32 (info,
							  G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
							  time.tv_usec);
			d(g_print ("Accessed: '%s' = '%d'\n", 
				   value, (int)time.tv_sec));
		}
		else if (strcmp (name, "user-perm") == 0) {
			/* The permissions don't map well to unix semantics,
			 * since the user is most likely not the same on both
			 * sides. We map the user permissions to "other" on the
			 * local side. D is treated as write, otherwise files
			 * can't be deleted through the module, even if it
			 * should be possible.
			 */
			if (strstr (value, "R")) {
				g_file_info_set_attribute_boolean (info,
								   G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
								   TRUE);
			}
			if (strstr (value, "W") || strstr (value, "D")) {
				g_file_info_set_attribute_boolean (info,
								   G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
								   TRUE);
			}
		}
		else if (strcmp (name, "group-perm") == 0) {
			/* Ignore for now */
			d(g_print ("Group permissions: '%s'\n", value));
		}
		else if (strcmp (name, "other-perm") == 0) {
			/* Ignore for now */
			d(g_print ("Other permissions: '%s'\n", value));
		}
		else if (strcmp (name, "owner") == 0) {
			/* Ignore for now */
			d(g_print ("Owner: '%s'\n", value));
		}
		else if (strcmp (name, "group") == 0) {
			/* Ignore for now */
			d(g_print ("Group: '%s'\n", value));
		}
		else if (strcmp (name, "type") == 0) {
			g_file_info_set_content_type (info, value);
			d(g_print ("Mime-Type: '%s'\n", value));
		}
		else if (strcmp (name, "xml:lang") == 0) {
			d(g_print ("Lang: '%s'\n", value));
		}
		else if (strcmp (name, "mem-type") == 0) {
			guint device;

			if (value == NULL || value[0] == '\0')
				continue;

			device = om_mem_type_id_from_string (value);
			g_file_info_set_attribute_uint32 (info,
							 G_FILE_ATTRIBUTE_UNIX_RDEV,
							 device);
			d(g_print ("Mem-Type: '%s' (%d)\n",
				   value, device));
		}
		else {
			d(g_print ("Unknown Attribute: %s = %s\n",
				   name, value));
		}
	}

	if (g_file_info_get_name (info) == NULL) { /* Required attribute */
		/* Set error */
		return FALSE;
	}
	
	return TRUE;
}
コード例 #10
0
ファイル: ostree-core.c プロジェクト: aperezdc/ostree
gboolean
ostree_content_stream_parse (gboolean                compressed,
                             GInputStream           *input,
                             guint64                 input_length,
                             gboolean                trusted,
                             GInputStream          **out_input,
                             GFileInfo             **out_file_info,
                             GVariant              **out_xattrs,
                             GCancellable           *cancellable,
                             GError                **error)
{
  gboolean ret = FALSE;
  guint32 archive_header_size;
  guchar dummy[4];
  gsize bytes_read;
  ot_lobj GInputStream *ret_input = NULL;
  ot_lobj GFileInfo *content_file_info = NULL;
  ot_lobj GFileInfo *ret_file_info = NULL;
  ot_lvariant GVariant *ret_xattrs = NULL;
  ot_lvariant GVariant *file_header = NULL;
  ot_lfree guchar *buf = NULL;

  if (!g_input_stream_read_all (input,
                                &archive_header_size, 4, &bytes_read,
                                cancellable, error))
    goto out;
  archive_header_size = GUINT32_FROM_BE (archive_header_size);
  if (archive_header_size > input_length)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "File header size %u exceeds size %" G_GUINT64_FORMAT,
                   (guint)archive_header_size, input_length);
      goto out;
    }
  if (archive_header_size == 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "File header size is zero");
      goto out;
    }

  /* Skip over padding */
  if (!g_input_stream_read_all (input,
                                dummy, 4, &bytes_read,
                                cancellable, error))
    goto out;

  buf = g_malloc (archive_header_size);
  if (!g_input_stream_read_all (input, buf, archive_header_size, &bytes_read,
                                cancellable, error))
    goto out;
  file_header = g_variant_new_from_data (compressed ? OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT : OSTREE_FILE_HEADER_GVARIANT_FORMAT,
                                         buf, archive_header_size, trusted,
                                         g_free, buf);
  buf = NULL;

  if (compressed)
    {
      if (!ostree_zlib_file_header_parse (file_header,
                                          out_file_info ? &ret_file_info : NULL,
                                          out_xattrs ? &ret_xattrs : NULL,
                                          error))
        goto out;
    }
  else
    {
      if (!ostree_file_header_parse (file_header,
                                     out_file_info ? &ret_file_info : NULL,
                                     out_xattrs ? &ret_xattrs : NULL,
                                     error))
        goto out;
      if (ret_file_info)
        g_file_info_set_size (ret_file_info, input_length - archive_header_size - 8);
    }
  
  if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR
      && out_input)
    {
      /* Give the input stream at its current position as return value;
       * assuming the caller doesn't seek, this should be fine.  We might
       * want to wrap it though in a non-seekable stream.
       **/
      if (compressed)
        {
          ot_lobj GConverter *zlib_decomp = (GConverter*)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW);
          ret_input = g_converter_input_stream_new (input, zlib_decomp);
        }
      else
        ret_input = g_object_ref (input);
    }

  ret = TRUE;
  ot_transfer_out_value (out_input, &ret_input);
  ot_transfer_out_value (out_file_info, &ret_file_info);
  ot_transfer_out_value (out_xattrs, &ret_xattrs);
 out:
  return ret;
}
コード例 #11
0
ファイル: gvfsftpdircache.c プロジェクト: BATYakhkhkh/gvfs
static gboolean
g_vfs_ftp_dir_cache_funcs_process (GInputStream *        stream,
                                   int                   debug_id,
                                   const GVfsFtpFile *   dir,
                                   GVfsFtpDirCacheEntry *entry,
                                   gboolean              is_unix,
                                   GCancellable *        cancellable,
                                   GError **             error)
{
  struct list_state state = { NULL, };
  GDataInputStream *data;
  GFileInfo *info;
  int type;
  GVfsFtpFile *file;
  char *line, *s;
  gsize length;

  /* protect against code reorg - in current code, error never is NULL */
  g_assert (error != NULL);
  g_assert (*error == NULL);

  data = g_data_input_stream_new (stream);
  /* we use LF only, because the mozilla code can handle lines ending in CR */
  g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_LF);
  while ((line = g_data_input_stream_read_line (data, &length, cancellable, error)))
    {
      struct list_result result = { 0, };
      GFileType file_type = G_FILE_TYPE_UNKNOWN;
      GTimeVal tv = { 0, 0 };

      /* strip trailing \r - ParseFTPList only removes it if the line ends in \r\n,
       * but we stripped the \n already.
       */
      if (length > 0 && line[length - 1] == '\r')
        line[--length] = '\0';

      g_debug ("<<%2d <<  %s\n", debug_id, line);
      type = ParseFTPList (line, &state, &result);
      if (type != 'd' && type != 'f' && type != 'l')
        {
          g_free (line);
          continue;
        }

      /* don't list . and .. directories
       * Let's hope they're not important files on some ftp servers
       */
      if (result.fe_fnlen == 1 &&
          result.fe_fname[0] == '.')
        {
          g_free (line);
          continue;
        }
      if (result.fe_fnlen == 2 &&
          result.fe_fname[0] == '.' &&
          result.fe_fname[1] == '.')
        {
          g_free (line);
          continue;
        }

      s = g_strndup (result.fe_fname, result.fe_fnlen);
      file = g_vfs_ftp_file_new_child  (dir, s, NULL);
      g_free (s);
      if (file == NULL)
        {
          g_debug ("# invalid filename, skipping");
          g_free (line);
          continue;
        }

      info = g_file_info_new ();

      s = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, s);
      g_free (s);

      if (type == 'l')
        {
          char *link;

          link = g_strndup (result.fe_lname, result.fe_lnlen);
          g_file_info_set_symlink_target (info, link);
          g_file_info_set_is_symlink (info, TRUE);
          g_free (link);
        }

      g_file_info_set_size (info, g_ascii_strtoull (result.fe_size, NULL, 10));

      /* If unix format then parse the attributes */
      if (state.lstyle == 'U')
        {
          char file_mode[10], uid[64], gid[64];
          guint32 mode;

          /* POSIX ls -l form: mode, links, owner, group */
          if (sscanf(line, "%10c %*u %63s %63s", file_mode, uid, gid) == 3)
            {
              if (g_vfs_ftp_parse_mode (file_mode, &mode, &file_type))
                {
                  g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, mode);
                  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER, uid);
                  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP, gid);
                }
            }
          else
            g_debug ("# unknown listing format\n");
        }

      if (file_type == G_FILE_TYPE_UNKNOWN)
        {
          file_type = type == 'f' ? G_FILE_TYPE_REGULAR :
                      type == 'l' ? G_FILE_TYPE_SYMBOLIC_LINK :
                      G_FILE_TYPE_DIRECTORY;
        }

      gvfs_file_info_populate_default (info,
                                       g_vfs_ftp_file_get_gvfs_path (file),
                                       file_type);

      if (is_unix)
        g_file_info_set_is_hidden (info, result.fe_fnlen > 0 &&
                                         result.fe_fname[0] == '.');

      /* Workaround:
       * result.fetime.tm_year contains actual year instead of offset-from-1900,
       * which mktime expects.
       */
      if (result.fe_time.tm_year >= 1900)
              result.fe_time.tm_year -= 1900;

      tv.tv_sec = mktime (&result.fe_time);
      if (tv.tv_sec != -1)
        g_file_info_set_modification_time (info, &tv);

      g_vfs_ftp_dir_cache_entry_add (entry, file, info);
      g_free (line);
    }

  g_object_unref (data);
  return *error != NULL;
}
コード例 #12
0
ファイル: gvfsftpdircache.c プロジェクト: BATYakhkhkh/gvfs
static GFileInfo *
g_vfs_ftp_dir_cache_funcs_lookup_uncached (GVfsFtpTask *      task,
                                           const GVfsFtpFile *file)
{
  GFileInfo *info;
  char **reply;

  if (g_vfs_ftp_file_is_root (file))
    return create_root_file_info (task->backend);

  /* the directory cache fails when the parent directory of the file is not readable.
   * This cannot happen on Unix, but it can happen on FTP.
   * In this case we try to figure out as much as possible about the file (does it even exist?)
   * using standard ftp commands.
   */
  if (g_vfs_ftp_task_send (task, 0, "CWD %s", g_vfs_ftp_file_get_ftp_path (file)))
    {
      char *tmp;

      info = g_file_info_new ();

      tmp = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, tmp);
      g_free (tmp);

      gvfs_file_info_populate_default (info, g_vfs_ftp_file_get_gvfs_path (file), G_FILE_TYPE_DIRECTORY);

      g_file_info_set_is_hidden (info, TRUE);
      
      return info;
    }
  
  g_vfs_ftp_task_clear_error (task);
  if (g_vfs_ftp_task_send_and_check (task, 0, NULL, NULL, &reply, "SIZE %s", g_vfs_ftp_file_get_ftp_path (file)))
    {
      char *tmp;

      info = g_file_info_new ();

      tmp = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, tmp);
      g_free (tmp);

      gvfs_file_info_populate_default (info, g_vfs_ftp_file_get_gvfs_path (file), G_FILE_TYPE_REGULAR);

      g_file_info_set_size (info, g_ascii_strtoull (reply[0] + 4, NULL, 0));
      g_strfreev (reply);

      g_file_info_set_is_hidden (info, TRUE);
      return info;
    }
      
  g_vfs_ftp_task_clear_error (task);

  /* note that there might still be a file/directory, we just have
   * no way to figure this out (in particular on ftp servers that
   * don't support SIZE.
   * If you have ways to improve file detection, patches are welcome. */

  return NULL;
}