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, ¶ms)) { 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); } }
/* Function implementations */ static void fl_parser_start_node_cb (void *user_data, const char *node_name, const char **attr) { ParserData *data; GFileInfo *info; data = (ParserData *) user_data; data->depth++; d(g_print ("%d: %s\n", data->depth, node_name)); if (data->depth > 2) { g_set_error (data->error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Don't expect node '%s' as child of 'file', 'folder' or 'parent-folder'", node_name); return; } else if (data->depth == 1) { if (strcmp (node_name, "folder-listing") != 0) { g_set_error (data->error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Expected 'folder-listing', got '%s'", node_name); return; } return; } if (strcmp (node_name, "parent-folder") == 0) { /* Just ignore parent-folder items */ return; } info = g_file_info_new (); if (strcmp (node_name, "file") == 0) { g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR); } else if (strcmp (node_name, "folder") == 0) { GIcon *icon; g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY); g_file_info_set_content_type (info, "inode/directory"); icon = g_themed_icon_new ("folder"); g_file_info_set_icon (info, icon); g_object_unref (icon); icon = g_themed_icon_new ("folder-symbolic"); g_file_info_set_symbolic_icon (info, icon); g_object_unref (icon); } else { g_set_error (data->error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, "Unknown element '%s'", node_name); return; } if (!fl_parser_fill_file_info (info, attr)) { d(g_print ("Failed to fill GnomeVFSFileInfo from node '%s'\n", node_name)); g_object_unref (info); return; } if (g_file_info_get_content_type (info) == NULL) { char *mime_type; mime_type = g_content_type_guess (g_file_info_get_name (info), NULL, 0, NULL); g_file_info_set_content_type (info, mime_type); g_free (mime_type); } if (g_file_info_get_content_type (info) == NULL) { g_file_info_set_content_type (info, "application/octet-stream"); } if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR) { GIcon *icon; const char *content_type; content_type = g_file_info_get_content_type (info); icon = g_content_type_get_icon (content_type); if (icon != NULL) { if (G_IS_THEMED_ICON (icon)) g_themed_icon_append_name (G_THEMED_ICON (icon), "text-x-generic"); g_file_info_set_icon (info, icon); g_object_unref (icon); } icon = g_content_type_get_symbolic_icon (content_type); if (icon != NULL) { if (G_IS_THEMED_ICON (icon)) g_themed_icon_append_name (G_THEMED_ICON (icon), "text-x-generic-symbolic"); g_file_info_set_symbolic_icon (info, icon); g_object_unref (icon); } } /* Permissions on folders in OBEX has different semantics than POSIX. * In POSIX, if a folder is not writable, it means that it's content * can't be removed, whereas in OBEX, it just means that the folder * itself can't be removed. Therefore we must set all folders to RWD and * handle the error when it happens. */ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE); g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE); } data->elements = g_list_prepend (data->elements, info); }