summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Walleij <triad@df.lth.se>2008-09-23 23:04:16 +0000
committerLinus Walleij <triad@df.lth.se>2008-09-23 23:04:16 +0000
commit8d8c43518dc46f9914bd920da89e7a8fd5e39e28 (patch)
treea8c6a92cc33ad22bb550fb1d6fd2c63e57104cb4
parent4d9165fe4cab6bd547fa18f4fa875b22baae09cf (diff)
downloadlibmtp-8d8c43518dc46f9914bd920da89e7a8fd5e39e28.tar.gz
Florent Mertens file rename functions patch.
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog9
-rw-r--r--src/libmtp.c257
-rw-r--r--src/libmtp.h.in5
-rw-r--r--src/libmtp.sym5
-rw-r--r--src/playlist-spl.c10
-rw-r--r--src/playlist-spl.h2
7 files changed, 238 insertions, 51 deletions
diff --git a/AUTHORS b/AUTHORS
index f6761f1..9c58627 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -33,3 +33,4 @@ Johannes Huber <johub1180@gmx.at>
Alistair Boyle <alistair.js.boyle@gmail.com>
Chris Bagwell <chris@cnpbagwell.com>
Joseph Nahmias <joe@nahmias.net>
+Florent Mertens <flomertens@gmail.com>
diff --git a/ChangeLog b/ChangeLog
index 7da2fc7..900b75c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-09-24 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.h.in: add new filename setting functions, patch
+ from Florent Mertens <flomertens@gmail.com>.
+ * src/libmtp.c: implementation.
+ * src/playlist-spl.c: consequental changes.
+ * src/libmtp.sym: consequental changes.
+ * Note to self: remember to bump soname to .so.8.1.0.
+
2008-09-23 Richard Low <richard@wentnet.com>
* src/libmtp.c: check for NULL storage
diff --git a/src/libmtp.c b/src/libmtp.c
index b226a9d..973870a 100644
--- a/src/libmtp.c
+++ b/src/libmtp.c
@@ -151,6 +151,10 @@ static int update_abstract_list(LIBMTP_mtpdevice_t *device,
uint32_t const no_tracks);
static void add_object_to_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id);
static void update_metadata_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id);
+static int set_object_filename(LIBMTP_mtpdevice_t *device,
+ uint32_t object_id,
+ uint16_t ptp_type,
+ const char **newname);
/**
* Create a new file mapping entry
@@ -4899,57 +4903,37 @@ int LIBMTP_Delete_Object(LIBMTP_mtpdevice_t *device,
}
/**
- * This function renames a single file, track, playlist, folder or
- * any other object on the MTP device, identified by an object ID.
- * This simply means that the PTP_OPC_ObjectFileName property
- * is updated, if this is supported by the device.
- *
- * @param device a pointer to the device that contains the the file,
- * track, foler, playlist or other object to set the filename for.
- * @param object_id the ID of the object to rename.
- * @param newname the new filename for this object. You MUST assume that
- * this string can be modified by the call to this function, since
- * some devices have restrictions as to which filenames may be
- * used on them.
- * @return 0 on success, any other value means failure.
+ * Internal function to update an object filename property.
*/
-int LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *device,
- uint32_t object_id, char *newname)
+static int set_object_filename(LIBMTP_mtpdevice_t *device,
+ uint32_t object_id, uint16_t ptp_type,
+ const char **newname_ptr)
{
PTPParams *params = (PTPParams *) device->params;
PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
- LIBMTP_file_t *file;
- uint16_t ptp_type;
PTPObjectPropDesc opd;
uint16_t ret;
-
- // Get metadata for this object.
- file = LIBMTP_Get_Filemetadata(device, object_id);
- if (file == NULL) {
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): "
- "could not get file metadata for target object.");
- return -1;
- }
- ptp_type = map_libmtp_type_to_ptp_type(file->filetype);
- LIBMTP_destroy_file_t(file);
+ char *newname;
// See if we can modify the filename on this kind of files.
ret = ptp_mtp_getobjectpropdesc(params, PTP_OPC_ObjectFileName, ptp_type, &opd);
if (ret != PTP_RC_OK) {
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): "
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): "
"could not get property description.");
return -1;
}
if (!opd.GetSet) {
ptp_free_objectpropdesc(&opd);
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): "
- "property is not settable.");
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): "
+ " property is not settable.");
// TODO: we COULD actually upload/download the object here, if we feel
// like wasting time for the user.
return -1;
}
+ newname = strdup(*newname_ptr);
+
if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
strip_7bit_from_utf8(newname);
}
@@ -4959,47 +4943,223 @@ int LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *device,
MTPProperties *props = NULL;
MTPProperties *prop = NULL;
int nrofprops = 0;
-
+
prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
- prop->ObjectHandle = object_id;
+ prop->ObjectHandle = object_id;
prop->property = PTP_OPC_ObjectFileName;
prop->datatype = PTP_DTC_STR;
- prop->propval.str = strdup(newname);
-
+ prop->propval.str = newname;
+
ret = ptp_mtp_setobjectproplist(params, props, nrofprops);
-
+
ptp_destroy_object_prop_list(props, nrofprops);
-
+
if (ret != PTP_RC_OK) {
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Oject_Filename(): "
- "could not set object property list.");
- ptp_free_objectpropdesc(&opd);
- return -1;
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): "
+ " could not set object property list.");
+ ptp_free_objectpropdesc(&opd);
+ return -1;
}
} else if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjectPropValue)) {
ret = set_object_string(device, object_id, PTP_OPC_ObjectFileName, newname);
if (ret != 0) {
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Oject_Filename(): "
- "could not set object filename.");
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): "
+ " could not set object filename.");
ptp_free_objectpropdesc(&opd);
return -1;
}
} else {
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Oject_Filename(): "
- "Your device doesn't seem to support any known way of setting metadata.");
+ free(newname);
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): "
+ " your device doesn't seem to support any known way of setting metadata.");
ptp_free_objectpropdesc(&opd);
return -1;
}
-
+
ptp_free_objectpropdesc(&opd);
-
+
// update cached object properties if metadata cache exists
update_metadata_cache(device, object_id);
-
+
return 0;
}
/**
+ * This function renames a single file.
+ * This simply means that the PTP_OPC_ObjectFileName property
+ * is updated, if this is supported by the device.
+ *
+ * @param device a pointer to the device that contains the file.
+ * @param file the file metadata of the file to rename.
+ * On success, the filename member is updated. Be aware, that
+ * this name can be different than newname depending of device restrictions.
+ * @param newname the new filename for this object.
+ * @return 0 on success, any other value means failure.
+ */
+int LIBMTP_Set_File_Name(LIBMTP_mtpdevice_t *device,
+ LIBMTP_file_t *file, const char *newname)
+{
+ int ret;
+
+ ret = set_object_filename(device, file->item_id,
+ map_libmtp_type_to_ptp_type(file->filetype),
+ &newname);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ free(file->filename);
+ file->filename = strdup(newname);
+ return ret;
+}
+
+/**
+ * This function renames a single folder.
+ * This simply means that the PTP_OPC_ObjectFileName property
+ * is updated, if this is supported by the device.
+ *
+ * @param device a pointer to the device that contains the file.
+ * @param folder the folder metadata of the folder to rename.
+ * On success, the name member is updated. Be aware, that
+ * this name can be different than newname depending of device restrictions.
+ * @param newname the new name for this object.
+ * @return 0 on success, any other value means failure.
+ */
+int LIBMTP_Set_Folder_Name(LIBMTP_mtpdevice_t *device,
+ LIBMTP_folder_t *folder, const char* newname)
+{
+ int ret;
+
+ ret = set_object_filename(device, folder->folder_id,
+ LIBMTP_FILETYPE_UNKNOWN,
+ &newname);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ free(folder->name);
+ folder->name = strdup(newname);
+ return ret;
+}
+
+/**
+ * This function renames a single track.
+ * This simply means that the PTP_OPC_ObjectFileName property
+ * is updated, if this is supported by the device.
+ *
+ * @param device a pointer to the device that contains the file.
+ * @param track the track metadata of the track to rename.
+ * On success, the filename member is updated. Be aware, that
+ * this name can be different than newname depending of device restrictions.
+ * @param newname the new filename for this object.
+ * @return 0 on success, any other value means failure.
+ */
+int LIBMTP_Set_Track_Name(LIBMTP_mtpdevice_t *device,
+ LIBMTP_track_t *track, const char* newname)
+{
+ int ret;
+
+ ret = set_object_filename(device, track->item_id,
+ map_libmtp_type_to_ptp_type(track->filetype),
+ &newname);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ free(track->filename);
+ track->filename = strdup(newname);
+ return ret;
+}
+
+/**
+ * This function renames a single playlist.
+ * This simply means that the PTP_OPC_ObjectFileName property
+ * is updated, if this is supported by the device.
+ *
+ * @param device a pointer to the device that contains the file.
+ * @param playlist the playlist metadata of the playlist to rename.
+ * On success, the name member is updated. Be aware, that
+ * this name can be different than newname depending of device restrictions.
+ * @param newname the new name for this object.
+ * @return 0 on success, any other value means failure.
+ */
+int LIBMTP_Set_Playlist_Name(LIBMTP_mtpdevice_t *device,
+ LIBMTP_playlist_t *playlist, const char* newname)
+{
+ int ret;
+
+ ret = set_object_filename(device, playlist->playlist_id,
+ PTP_OFC_MTP_AbstractAudioVideoPlaylist,
+ &newname);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ free(playlist->name);
+ playlist->name = strdup(newname);
+ return ret;
+}
+
+/**
+ * This function renames a single album.
+ * This simply means that the PTP_OPC_ObjectFileName property
+ * is updated, if this is supported by the device.
+ *
+ * @param device a pointer to the device that contains the file.
+ * @param album the album metadata of the album to rename.
+ * On success, the name member is updated. Be aware, that
+ * this name can be different than newname depending of device restrictions.
+ * @param newname the new name for this object.
+ * @return 0 on success, any other value means failure.
+ */
+int LIBMTP_Set_Album_Name(LIBMTP_mtpdevice_t *device,
+ LIBMTP_album_t *album, const char* newname)
+{
+ int ret;
+
+ ret = set_object_filename(device, album->album_id,
+ PTP_OFC_MTP_AbstractAudioAlbum,
+ &newname);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ free(album->name);
+ album->name = strdup(newname);
+ return ret;
+}
+
+/**
+ * THIS FUNCTION IS DEPRECATED. PLEASE UPDATE YOUR CODE IN ORDER
+ * NOT TO USE IT.
+ *
+ * @see LIBMTP_Set_File_Name()
+ * @see LIBMTP_Set_Track_Name()
+ * @see LIBMTP_Set_Folder_Name()
+ * @see LIBMTP_Set_Playlist_Name()
+ * @see LIBMTP_Set_Album_Name()
+ */
+int LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *device,
+ uint32_t object_id, char* newname)
+{
+ int ret;
+ LIBMTP_file_t *file;
+
+ file = LIBMTP_Get_Filemetadata(device, object_id);
+
+ ret = set_object_filename(device, object_id, file->filetype, (const char **) &newname);
+
+ free(file);
+
+ return ret;
+}
+
+/**
* Helper function. This indicates if a track exists on the device
* @param device a pointer to the device to get the track from.
* @param id the track ID of the track to retrieve.
@@ -5370,7 +5530,8 @@ LIBMTP_playlist_t *LIBMTP_Get_Playlist_List(LIBMTP_mtpdevice_t *device)
// Then get the track listing for this playlist
ret = ptp_mtp_getobjectreferences(params, pl->playlist_id, &pl->tracks, &pl->no_tracks);
if (ret != PTP_RC_OK) {
- add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Playlist: Could not get object references.");
+ add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Playlist_List(): "
+ "could not get object references.");
pl->tracks = NULL;
pl->no_tracks = 0;
}
diff --git a/src/libmtp.h.in b/src/libmtp.h.in
index e5ba9d9..087bc11 100644
--- a/src/libmtp.h.in
+++ b/src/libmtp.h.in
@@ -514,6 +514,7 @@ int LIBMTP_Send_File_From_File(LIBMTP_mtpdevice_t *, char const * const,
int LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *, int const,
LIBMTP_file_t * const, LIBMTP_progressfunc_t const,
void const * const);
+int LIBMTP_Set_File_Name(LIBMTP_mtpdevice_t *, LIBMTP_file_t *, const char *);
LIBMTP_filesampledata_t *LIBMTP_new_filesampledata_t(void);
void LIBMTP_destroy_filesampledata_t(LIBMTP_filesampledata_t *);
int LIBMTP_Get_Representative_Sample_Format(LIBMTP_mtpdevice_t *,
@@ -550,6 +551,7 @@ int LIBMTP_Send_Track_From_File_Descriptor(LIBMTP_mtpdevice_t *,
int LIBMTP_Update_Track_Metadata(LIBMTP_mtpdevice_t *,
LIBMTP_track_t const * const);
int LIBMTP_Track_Exists(LIBMTP_mtpdevice_t *, uint32_t);
+int LIBMTP_Set_Track_Name(LIBMTP_mtpdevice_t *, LIBMTP_track_t *, const char *);
/** @} */
/**
@@ -562,6 +564,7 @@ void LIBMTP_destroy_folder_t(LIBMTP_folder_t*);
LIBMTP_folder_t *LIBMTP_Get_Folder_List(LIBMTP_mtpdevice_t*);
LIBMTP_folder_t *LIBMTP_Find_Folder(LIBMTP_folder_t*, uint32_t const);
uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t*, char *, uint32_t, uint32_t);
+int LIBMTP_Set_Folder_Name(LIBMTP_mtpdevice_t *, LIBMTP_folder_t *, const char *);
/** @} */
@@ -576,6 +579,7 @@ LIBMTP_playlist_t *LIBMTP_Get_Playlist_List(LIBMTP_mtpdevice_t *);
LIBMTP_playlist_t *LIBMTP_Get_Playlist(LIBMTP_mtpdevice_t *, uint32_t const);
int LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t * const);
int LIBMTP_Update_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t const * const);
+int LIBMTP_Set_Playlist_Name(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t *, const char *);
/**
* @}
@@ -588,6 +592,7 @@ LIBMTP_album_t *LIBMTP_Get_Album_List(LIBMTP_mtpdevice_t *);
LIBMTP_album_t *LIBMTP_Get_Album(LIBMTP_mtpdevice_t *, uint32_t const);
int LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t * const);
int LIBMTP_Update_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t const * const);
+int LIBMTP_Set_Album_Name(LIBMTP_mtpdevice_t *, LIBMTP_album_t *, const char *);
/**
* @}
diff --git a/src/libmtp.sym b/src/libmtp.sym
index 62fe11d..8a649a8 100644
--- a/src/libmtp.sym
+++ b/src/libmtp.sym
@@ -70,4 +70,9 @@ LIBMTP_Get_Album
LIBMTP_Create_New_Album
LIBMTP_Update_Album
LIBMTP_Delete_Object
+LIBMTP_Set_File_Name
+LIBMTP_Set_Folder_Name
+LIBMTP_Set_Track_Name
+LIBMTP_Set_Playlist_Name
+LIBMTP_Set_Album_Name
LIBMTP_Set_Object_Filename
diff --git a/src/playlist-spl.c b/src/playlist-spl.c
index 0bf5eb1..1006073 100644
--- a/src/playlist-spl.c
+++ b/src/playlist-spl.c
@@ -276,6 +276,12 @@ int update_spl_playlist(LIBMTP_mtpdevice_t *device,
printf("name is changing too -> %s\n",new->name);
}
+ // FIXME: this call is NOT SAFE, LIBMTP_Create_New_Playlist()
+ // changes the object_id of new here, and the user callee
+ // (calling application) expects LIBMTP_Update_Playlist()
+ // NOT to change this metadata. Make a copy of the metadata
+ // that you send in here instead, and hope the app finds out
+ // about the object_id change some other way.
return LIBMTP_Create_New_Playlist(device, new);
}
@@ -287,7 +293,7 @@ int update_spl_playlist(LIBMTP_mtpdevice_t *device,
char* s = malloc(sizeof(char)*(strlen(new->name)+5));
strcpy(s, new->name);
strcat(s,".spl"); // FIXME check for success
- int ret = LIBMTP_Set_Object_Filename(device, new->playlist_id, s);
+ int ret = LIBMTP_Set_Playlist_Name(device, new, s);
free(s);
return ret;
}
@@ -396,7 +402,7 @@ static text_t* read_into_spl_text_t(LIBMTP_mtpdevice_t *device, const int fd)
// we are dropping all the processed bytes for this line and
// proceeding on as if everything is okay, probably losing a track
// from the playlist
- printf("ERROR %s:%u:%s(): buffer overflow! .spl line too long @ %luB\n",
+ printf("ERROR %s:%u:%s(): buffer overflow! .spl line too long @ %uB\n",
__FILE__, __LINE__, __func__, WSIZE);
iw = w; // reset buffer
}
diff --git a/src/playlist-spl.h b/src/playlist-spl.h
index ced5794..2a44dfa 100644
--- a/src/playlist-spl.h
+++ b/src/playlist-spl.h
@@ -30,6 +30,6 @@ void spl_to_playlist_t(LIBMTP_mtpdevice_t* device, PTPObjectInfo *oi,
int playlist_t_to_spl(LIBMTP_mtpdevice_t *device,
LIBMTP_playlist_t * const metadata);
int update_spl_playlist(LIBMTP_mtpdevice_t *device,
- LIBMTP_playlist_t const * const metadata);
+ LIBMTP_playlist_t const * const new);
#endif //__MTP__PLAYLIST_SPL__H