Don't require a configured inet interface when resolving names
[libmpd.git] / src / libmpd-database.c
blob2545cd9f37f9d063d603ccaa26d412a7fb066fde
1 /* libmpd (high level libmpdclient library)
2 * Copyright (C) 2004-2009 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpcwiki.sarine.nl/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <stdio.h>
21 #include <stdlib.h>
22 #define __USE_GNU
24 #include <string.h>
25 #include <stdarg.h>
26 #include <config.h>
27 #include "debug_printf.h"
28 #include "libmpd.h"
29 #include "libmpd-internal.h"
31 int mpd_database_update_dir(MpdObj *mi,const char *path)
33 if(path == NULL)
35 debug_printf(DEBUG_ERROR, "path != NULL failed");
36 return MPD_ARGS_ERROR;
38 if(!mpd_check_connected(mi))
40 debug_printf(DEBUG_WARNING,"not connected\n");
41 return MPD_NOT_CONNECTED;
43 if(mpd_lock_conn(mi))
45 debug_printf(DEBUG_ERROR,"lock failed\n");
46 return MPD_LOCK_FAILED;
49 mpd_sendUpdateCommand(mi->connection,path);
50 mpd_finishCommand(mi->connection);
51 /* I have no idea why do this ?? it even makes gmpc very very unhappy.
52 * Because it doesnt trigger an signal anymore when updating starts
53 * mi->CurrentState.updatingDb = mpd_getUpdateId(mi->connection);
56 /* unlock */
57 mpd_unlock_conn(mi);
58 /* What I think you should do is to force a direct status updated
60 mpd_status_update(mi);
61 return MPD_OK;
64 MpdData * mpd_database_get_artists(MpdObj *mi)
66 char *string = NULL;
67 MpdData *data = NULL;
68 if(!mpd_check_connected(mi))
70 debug_printf(DEBUG_WARNING,"not connected\n");
71 return NULL;
73 if(mpd_lock_conn(mi))
75 debug_printf(DEBUG_ERROR,"lock failed\n");
76 return NULL;
79 mpd_sendListCommand(mi->connection,MPD_TABLE_ARTIST,NULL);
80 while (( string = mpd_getNextArtist(mi->connection)) != NULL)
82 data = mpd_new_data_struct_append(data);
83 data->type = MPD_DATA_TYPE_TAG;
84 data->tag_type = MPD_TAG_ITEM_ARTIST;
85 data->tag = string;
87 mpd_finishCommand(mi->connection);
89 /* unlock */
90 mpd_unlock_conn(mi);
91 if(data == NULL)
93 return NULL;
95 /* data = mpd_misc_sort_tag_list(data);*/
96 return mpd_data_get_first(data);
99 MpdData * mpd_database_get_albums(MpdObj *mi,const char *artist)
101 char *string = NULL;
102 MpdData *data = NULL;
103 if(!mpd_check_connected(mi))
105 debug_printf(DEBUG_WARNING,"not connected\n");
106 return NULL;
108 if(mpd_lock_conn(mi))
110 debug_printf(DEBUG_ERROR,"lock failed\n");
111 return NULL;
114 mpd_sendListCommand(mi->connection,MPD_TABLE_ALBUM,artist);
115 while (( string = mpd_getNextAlbum(mi->connection)) != NULL)
117 data = mpd_new_data_struct_append(data);
118 data->type = MPD_DATA_TYPE_TAG;
119 data->tag_type = MPD_TAG_ITEM_ALBUM;
120 data->tag = string;
122 mpd_finishCommand(mi->connection);
124 /* unlock */
125 mpd_unlock_conn(mi);
126 if(data == NULL)
128 return NULL;
130 return mpd_data_get_first(data);
133 MpdData * mpd_database_get_complete(MpdObj *mi)
135 MpdData *data = NULL;
136 mpd_InfoEntity *ent = NULL;
137 if(!mpd_check_connected(mi))
139 debug_printf(DEBUG_WARNING,"not connected\n");
140 return NULL;
142 if(mpd_lock_conn(mi))
144 debug_printf(DEBUG_ERROR,"lock failed\n");
145 return NULL;
147 mpd_sendListallInfoCommand(mi->connection, "/");
148 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
151 if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
153 data = mpd_new_data_struct_append(data);
154 data->type = MPD_DATA_TYPE_SONG;
155 data->song = ent->info.song;
156 ent->info.song = NULL;
158 mpd_freeInfoEntity(ent);
160 mpd_finishCommand(mi->connection);
162 /* unlock */
163 mpd_unlock_conn(mi);
164 if(data == NULL)
166 return NULL;
168 return mpd_data_get_first(data);
171 int mpd_database_delete_playlist(MpdObj *mi,const char *path)
173 if(path == NULL)
175 debug_printf(DEBUG_WARNING, "path == NULL");
176 return MPD_ARGS_ERROR;
178 if(!mpd_check_connected(mi))
180 debug_printf(DEBUG_WARNING,"not connected\n");
181 return MPD_NOT_CONNECTED;
183 if(mpd_lock_conn(mi))
185 debug_printf(DEBUG_ERROR,"lock failed\n");
186 return MPD_LOCK_FAILED;
189 mpd_sendRmCommand(mi->connection,path);
190 mpd_finishCommand(mi->connection);
192 /* unlock */
193 mpd_unlock_conn(mi);
194 return MPD_OK;
197 int mpd_database_save_playlist(MpdObj *mi,const char *name)
199 if(name == NULL || !strlen(name))
201 debug_printf(DEBUG_WARNING, "mpd_playlist_save: name != NULL and strlen(name) > 0 failed");
202 return MPD_ARGS_ERROR;
204 if(!mpd_check_connected(mi))
206 debug_printf(DEBUG_WARNING,"mpd_playlist_save: not connected\n");
207 return MPD_NOT_CONNECTED;
209 if(mpd_lock_conn(mi))
211 debug_printf(DEBUG_ERROR,"mpd_playlist_save: lock failed\n");
212 return MPD_LOCK_FAILED;
215 mpd_sendSaveCommand(mi->connection,name);
216 mpd_finishCommand(mi->connection);
217 if(mi->connection->error == MPD_ERROR_ACK && mi->connection->errorCode == MPD_ACK_ERROR_EXIST)
219 mpd_clearError(mi->connection);
220 mpd_unlock_conn(mi);
221 return MPD_DATABASE_PLAYLIST_EXIST;
224 /* unlock */
225 mpd_unlock_conn(mi);
226 return MPD_OK;
229 /* "hack" to keep the compiler happy */
230 typedef int (* QsortCompare)(const void *a, const void *b);
232 static int compa(char **a,const char **b)
234 char *c =*a;
235 char *d =(char*)*b;
236 #ifndef NO_SMART_SORT
237 if(!strncasecmp(c, "The ",4) && strlen(c) > 4)
239 c = &c[4];
241 if(!strncasecmp(d, "The ",4) && strlen(d) > 4)
243 d = &d[4];
245 #endif
247 return strcasecmp(c,d);
250 MpdData *mpd_misc_sort_tag_list(MpdData *data)
252 char **array;
253 MpdData *test;
254 int i=0;
255 int length=0;
256 test = data = mpd_data_get_first(data);
259 length++;
260 test = mpd_data_get_next_real(test, FALSE);
261 }while(test != NULL);
262 array = malloc(length*sizeof(char*));
263 test = data;
267 array[i] = test->tag;
268 test = mpd_data_get_next_real(test, FALSE);
269 i++;
270 }while(test != NULL);
272 qsort(array,length,sizeof(char *),(QsortCompare)compa);
274 /* reset list */
275 test = mpd_data_get_first(data);
276 i=0;
279 test->tag = array[i];
280 test = mpd_data_get_next_real(test, FALSE);
281 i++;
282 }while(test != NULL);
283 free(array);
284 return mpd_data_get_first(data);
287 /* should be called mpd_database_find */
288 MpdData * mpd_database_find(MpdObj *mi, int table,const char *string, int exact)
290 MpdData *data = NULL;
291 /* MpdData *artist = NULL;
292 MpdData *album = NULL;
293 */ mpd_InfoEntity *ent = NULL;
294 if(!mpd_check_connected(mi))
296 debug_printf(DEBUG_WARNING,"not connected\n");
297 return NULL;
299 if(mpd_lock_conn(mi))
301 debug_printf(DEBUG_WARNING,"lock failed\n");
302 return NULL;
304 if(exact)
306 mpd_sendFindCommand(mi->connection,table,string);
308 else
310 mpd_sendSearchCommand(mi->connection, table,string);
312 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
314 data = mpd_new_data_struct_append(data);
315 /* mpd_sendSearch|Find only returns songs */
317 if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
319 data->type = MPD_DATA_TYPE_DIRECTORY;
320 data->directory = ent->info.directory->path;
321 ent->info.directory->path = NULL;
323 else*/ if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
325 data->type = MPD_DATA_TYPE_SONG;
326 data->song = ent->info.song;
327 ent->info.song = NULL;
328 /* This is something the client can and should do */
329 /* if(data->song->artist != NULL)
331 int found = FALSE;
332 if(artist != NULL)
334 MpdData *fartist = mpd_data_get_first(artist);
336 if( (fartist->type == MPD_DATA_TYPE_TAG) && (fartist->tag_type == MPD_TAG_ITEM_ARTIST))
338 if(fartist->tag == NULL)
340 printf("crap this should'nt be \n");
342 if(!strcmp(fartist->tag, data->song->artist))
344 found = TRUE;
347 fartist = mpd_data_get_next_real(fartist, FALSE);
348 }while(fartist && !found);
350 if(!found)
352 artist= mpd_new_data_struct_append(artist);
353 artist->type = MPD_DATA_TYPE_TAG;
354 artist->tag_type = MPD_TAG_ITEM_ARTIST;
355 artist->tag = strdup(data->song->artist);
358 if(data->song->album != NULL)
360 int found = FALSE;
361 if(album != NULL)
363 MpdData *falbum = mpd_data_get_first(album);
365 if( (falbum->type == MPD_DATA_TYPE_TAG) && (falbum->tag_type == MPD_TAG_ITEM_ALBUM))
367 if(falbum->tag == NULL)
369 printf("crap this should'nt be \n");
371 if(!strcmp(falbum->tag, data->song->album))
373 found = TRUE;
376 falbum = mpd_data_get_next_real(falbum, FALSE);
377 }while(falbum && !found);
379 if(!found)
381 album = mpd_new_data_struct_append(album);
382 album->type = MPD_DATA_TYPE_TAG;
383 album->tag_type = MPD_TAG_ITEM_ALBUM;
384 album->tag = strdup(data->song->album);
390 else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
392 data->type = MPD_DATA_TYPE_PLAYLIST;
393 data->playlist = ent->info.playlistFile->path;
394 ent->info.playlistFile->path = NULL;
398 mpd_freeInfoEntity(ent);
400 mpd_finishCommand(mi->connection);
402 /* unlock */
403 mpd_unlock_conn(mi);
404 if(data == NULL)
406 return NULL;
408 data = mpd_data_get_first(data);
409 /* prepend the album then artists*/
410 /* if(album != NULL)
412 if(data){
413 data = mpd_data_concatenate( album, data);
414 }else{
415 data = album;
418 if(artist != NULL)
420 if(data) {
421 album = mpd_data_concatenate( artist, data );
422 }else{
423 data = artist;
427 return mpd_data_get_first(data);
430 MpdData * mpd_database_get_directory(MpdObj *mi,const char *path)
432 MpdData *data = NULL;
433 mpd_InfoEntity *ent = NULL;
434 if(!mpd_check_connected(mi))
436 debug_printf(DEBUG_WARNING,"not connected\n");
437 return NULL;
439 if(path == NULL)
441 path = "/";
443 if(mpd_lock_conn(mi))
445 debug_printf(DEBUG_WARNING,"lock failed\n");
446 return NULL;
449 mpd_sendLsInfoCommand(mi->connection,path);
450 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
452 data = mpd_new_data_struct_append(data);
453 if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
455 data->type = MPD_DATA_TYPE_DIRECTORY;
456 data->directory = ent->info.directory->path;
457 ent->info.directory->path = NULL;
459 else if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
461 data->type = MPD_DATA_TYPE_SONG;
462 data->song = ent->info.song;
463 ent->info.song = NULL;
465 else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
467 data->type = MPD_DATA_TYPE_PLAYLIST;
468 data->playlist = ent->info.playlistFile;
469 ent->info.playlistFile= NULL;
472 mpd_freeInfoEntity(ent);
474 mpd_finishCommand(mi->connection);
476 /* unlock */
477 mpd_unlock_conn(mi);
478 if(data == NULL)
480 return NULL;
482 return mpd_data_get_first(data);
485 MpdData *mpd_database_get_playlist_content(MpdObj *mi,const char *playlist)
487 int i=0;
488 MpdData *data = NULL;
489 mpd_InfoEntity *ent = NULL;
490 if(!mpd_check_connected(mi))
492 debug_printf(DEBUG_WARNING,"not connected\n");
493 return NULL;
495 if(!mpd_server_check_version(mi, 0,12,0))
497 debug_printf(DEBUG_WARNING, "only works with mpd higher then 0.12.0");
498 return NULL;
500 if(mpd_server_check_command_allowed(mi, "listplaylistinfo") != MPD_SERVER_COMMAND_ALLOWED)
502 debug_printf(DEBUG_WARNING, "Listing playlist content not supported or allowed");
503 return NULL;
505 if(mpd_lock_conn(mi))
507 debug_printf(DEBUG_WARNING,"lock failed\n");
508 return NULL;
510 mpd_sendListPlaylistInfoCommand(mi->connection, playlist);
511 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
513 if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
515 data = mpd_new_data_struct_append( data );
516 data->type = MPD_DATA_TYPE_SONG;
517 data->song = ent->info.song;
518 data->song->pos = i;
519 ent->info.song = NULL;
520 i++;
522 mpd_freeInfoEntity(ent);
524 mpd_finishCommand(mi->connection);
526 if(mi->connection->error == MPD_ERROR_ACK && mi->connection->errorCode == MPD_ACK_ERROR_NO_EXIST)
528 mpd_clearError(mi->connection);
530 /* unlock */
531 mpd_unlock_conn(mi);
532 if(data == NULL)
534 return NULL;
536 return mpd_data_get_first(data);
539 * @param mi A #MpdObj
540 * @param path an Path to a file
542 * Grabs the song info for a single file. Make sure you pass an url to a song
543 * and not a directory, that might result in strange behauviour.
545 * @returns a #mpd_Song
547 mpd_Song * mpd_database_get_fileinfo(MpdObj *mi,const char *path)
549 mpd_Song *song = NULL;
550 mpd_InfoEntity *ent = NULL;
552 * Check path for availibility and length
554 if(path == NULL || path[0] == '\0')
556 debug_printf(DEBUG_ERROR, "path == NULL || strlen(path) == 0");
557 return NULL;
559 if(!mpd_check_connected(mi))
561 debug_printf(DEBUG_ERROR, "Not Connected\n");
562 return NULL;
564 /* lock, so we can work on mi->connection */
565 if(mpd_lock_conn(mi) != MPD_OK)
567 debug_printf(DEBUG_ERROR, "Failed to lock connection");
568 return NULL;
570 /* send the request */
571 mpd_sendListallInfoCommand(mi->connection, path);
572 /* get the first (and only) result */
573 ent = mpd_getNextInfoEntity(mi->connection);
574 /* finish and clean up libmpdclient */
575 mpd_finishCommand(mi->connection);
576 /* unlock again */
577 if(mpd_unlock_conn(mi))
579 if(ent) mpd_freeInfoEntity(ent);
580 debug_printf(DEBUG_ERROR, "Failed to unlock");
581 return NULL;
584 if(ent == NULL)
586 debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n");
587 return NULL;
590 if(ent->type != MPD_INFO_ENTITY_TYPE_SONG)
592 mpd_freeInfoEntity(ent);
593 debug_printf(DEBUG_ERROR, "Failed to grab correct song type from mpd, path might not be a file\n");
594 return NULL;
596 /* get the song */
597 song = ent->info.song;
598 /* remove reference to song from the entity */
599 ent->info.song = NULL;
600 /* free the entity */
601 mpd_freeInfoEntity(ent);
603 return song;
607 void mpd_database_search_field_start(MpdObj *mi, mpd_TagItems field)
610 * Check argument
612 if(mi == NULL || field >= MPD_TAG_NUM_OF_ITEM_TYPES || field < 0)
614 debug_printf(DEBUG_ERROR, "Argument error");
615 return ;
617 if(!mpd_check_connected(mi))
619 debug_printf(DEBUG_ERROR, "Not Connected\n");
620 return ;
622 if(!mpd_server_check_version(mi, 0,12,0))
624 debug_printf(DEBUG_ERROR, "Advanced field list requires mpd 0.12.0 or higher");
625 return ;
627 /* lock, so we can work on mi->connection */
628 if(mpd_lock_conn(mi) != MPD_OK)
630 debug_printf(DEBUG_ERROR, "Failed to lock connection");
631 return ;
633 mpd_startFieldSearch(mi->connection, field);
634 /* Set search type */
635 mi->search_type = MPD_SEARCH_TYPE_LIST;
636 mi->search_field = field;
637 /* unlock, let the error handler handle any possible error.
639 mpd_unlock_conn(mi);
640 return;
650 * @param mi A #MpdObj
651 * @param exact a boolean indicating if the search is fuzzy or exact
653 * Starts a search, you can add "constraints" by calling mpd_database_search_add_constraint
655 * This function requires mpd 0.12.0 or higher
658 void mpd_database_search_start(MpdObj *mi, int exact)
661 * Check argument
663 if(mi == NULL || exact > 1 || exact < 0)
665 debug_printf(DEBUG_ERROR, "Argument error");
666 return ;
668 if(!mpd_check_connected(mi))
670 debug_printf(DEBUG_ERROR, "Not Connected\n");
671 return ;
673 if(!mpd_server_check_version(mi, 0,12,0))
675 debug_printf(DEBUG_ERROR, "Advanced search requires mpd 0.12.0 or higher");
676 return ;
678 /* lock, so we can work on mi->connection */
679 if(mpd_lock_conn(mi) != MPD_OK)
681 debug_printf(DEBUG_ERROR, "Failed to lock connection");
682 return ;
684 mpd_startSearch(mi->connection, exact);
685 /* Set search type */
686 mi->search_type = (exact)? MPD_SEARCH_TYPE_FIND:MPD_SEARCH_TYPE_SEARCH;
687 /* unlock, let the error handler handle any possible error.
689 mpd_unlock_conn(mi);
690 return;
693 * @param mi A #MpdObj
694 * @param field A #mpd_TagItems
696 * Adds a constraint to the search
698 void mpd_database_search_add_constraint(MpdObj *mi, mpd_TagItems field, const char *value)
700 if(mi == NULL )
702 debug_printf(DEBUG_ERROR,"Failed to parse arguments");
703 return;
705 if(mi->search_type == MPD_SEARCH_TYPE_NONE)
707 debug_printf(DEBUG_ERROR, "No search to constraint");
708 return;
710 if(!mpd_check_connected(mi))
712 debug_printf(DEBUG_ERROR, "Not Connected\n");
713 return ;
715 if(!mpd_server_check_version(mi, 0,12,0))
717 debug_printf(DEBUG_ERROR, "Advanced search requires mpd 0.12.0 or higher");
718 return ;
720 /* lock, so we can work on mi->connection */
721 if(mpd_lock_conn(mi) != MPD_OK)
723 debug_printf(DEBUG_ERROR, "Failed to lock connection");
724 return ;
726 mpd_addConstraintSearch(mi->connection, field, (value)?value:"");
727 /* unlock, let the error handler handle any possible error.
729 mpd_unlock_conn(mi);
730 return;
733 MpdData * mpd_database_search_commit(MpdObj *mi)
735 mpd_InfoEntity *ent = NULL;
736 MpdData *data = NULL;
737 if(!mpd_check_connected(mi))
739 debug_printf(DEBUG_WARNING,"not connected\n");
740 return NULL;
742 if(mi->search_type == MPD_SEARCH_TYPE_NONE)
744 debug_printf(DEBUG_ERROR, "no search in progress to commit");
745 return NULL;
747 if(mpd_lock_conn(mi))
749 debug_printf(DEBUG_ERROR,"lock failed\n");
750 return NULL;
752 mpd_commitSearch(mi->connection);
753 if(mi->search_type == MPD_SEARCH_TYPE_LIST)
755 char *string = NULL;
756 while((string = mpd_getNextTag(mi->connection, mi->search_field)))
758 data = mpd_new_data_struct_append(data);
759 data->type = MPD_DATA_TYPE_TAG;
760 data->tag_type = mi->search_field;
761 data->tag = string;
764 else
766 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
768 if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
770 data = mpd_new_data_struct_append(data);
771 data->type = MPD_DATA_TYPE_SONG;
772 data->song = ent->info.song;
773 ent->info.song = NULL;
775 mpd_freeInfoEntity(ent);
778 mpd_finishCommand(mi->connection);
780 * reset search type
782 mi->search_type = MPD_SEARCH_TYPE_NONE;
783 mi->search_field = MPD_TAG_ITEM_ARTIST;
784 /* unlock */
785 if(mpd_unlock_conn(mi))
787 debug_printf(DEBUG_ERROR, "Failed to unlock connection");
788 if(data)mpd_data_free(data);
789 return NULL;
791 if(data == NULL)
793 return NULL;
795 return mpd_data_get_first(data);
799 * @param mi A #MpdObj
801 * Starts a search, you can add "constraints" by calling mpd_database_search_add_constraint
802 * to get the result call mpd_database_search_stats_commit
804 * This function requires mpd 0.13.0 or higher
807 void mpd_database_search_stats_start(MpdObj *mi)
810 * Check argument
812 if(mi == NULL)
814 debug_printf(DEBUG_ERROR, "Argument error");
815 return ;
817 if(!mpd_check_connected(mi))
819 debug_printf(DEBUG_ERROR, "Not Connected\n");
820 return ;
822 if(!mpd_server_check_version(mi, 0,13,0))
824 debug_printf(DEBUG_ERROR, "Advanced search requires mpd 0.13.0 or higher");
825 return ;
827 /* lock, so we can work on mi->connection */
828 if(mpd_lock_conn(mi) != MPD_OK)
830 debug_printf(DEBUG_ERROR, "Failed to lock connection");
831 return ;
833 mpd_startStatsSearch(mi->connection);
834 /* Set search type */
835 mi->search_type = MPD_SEARCH_TYPE_STATS;
836 /* unlock, let the error handler handle any possible error.
838 mpd_unlock_conn(mi);
839 return;
842 MpdDBStats * mpd_database_search_stats_commit(MpdObj *mi)
844 MpdDBStats *data = NULL;
845 if(!mpd_check_connected(mi))
847 debug_printf(DEBUG_WARNING,"not connected\n");
848 return NULL;
850 if(mi->search_type != MPD_SEARCH_TYPE_STATS)
852 debug_printf(DEBUG_ERROR, "no/wrong search in progress to commit");
853 return NULL;
855 if(mpd_lock_conn(mi))
857 debug_printf(DEBUG_ERROR,"lock failed\n");
858 return NULL;
860 mpd_commitSearch(mi->connection);
862 data = (MpdDBStats *) mpd_getSearchStats(mi->connection);
863 /* unlock */
864 if(mpd_unlock_conn(mi))
866 debug_printf(DEBUG_ERROR, "Failed to unlock connection");
867 if(data)mpd_freeSearchStats((mpd_SearchStats *)data);
868 return NULL;
870 if(data == NULL)
872 return NULL;
874 return data;
877 void mpd_database_search_free_stats(MpdDBStats *data)
879 mpd_freeSearchStats(data);
882 void mpd_database_playlist_clear(MpdObj *mi, const char *path)
884 if(!path )
885 return;
886 if (!mpd_check_connected(mi)) {
887 debug_printf(DEBUG_WARNING, "not connected\n");
888 return;
890 if (mpd_status_check(mi) != MPD_OK) {
891 debug_printf(DEBUG_WARNING, "Failed to get status\n");
892 return;
894 if(mpd_lock_conn(mi))
896 return ;
899 mpd_sendPlaylistClearCommand(mi->connection, (char *)path);
900 mpd_finishCommand(mi->connection);
902 mpd_unlock_conn(mi);
910 void mpd_database_playlist_list_delete(MpdObj *mi, const char *path, int pos)
912 if(!path )
913 return;
914 if (!mpd_check_connected(mi)) {
915 debug_printf(DEBUG_WARNING, "not connected\n");
916 return;
918 if (mpd_status_check(mi) != MPD_OK) {
919 debug_printf(DEBUG_WARNING, "Failed to get status\n");
920 return;
922 if(mpd_lock_conn(mi))
924 return ;
927 mpd_sendPlaylistDeleteCommand(mi->connection, (char *)path,pos);
928 mpd_finishCommand(mi->connection);
930 mpd_unlock_conn(mi);
932 void mpd_database_playlist_list_add(MpdObj *mi, const char *path, const char *file)
934 if(!path )
935 return;
936 if (!mpd_check_connected(mi)) {
937 debug_printf(DEBUG_WARNING, "not connected\n");
938 return;
940 if (mpd_status_check(mi) != MPD_OK) {
941 debug_printf(DEBUG_WARNING, "Failed to get status\n");
942 return;
944 if(mpd_lock_conn(mi))
946 return ;
949 mpd_sendPlaylistAddCommand(mi->connection, (char *)path,(char *)file);
950 mpd_finishCommand(mi->connection);
952 mpd_unlock_conn(mi);
955 MpdData * mpd_database_get_directory_recursive(MpdObj *mi, const char *path)
957 MpdData *data = NULL;
958 mpd_InfoEntity *ent = NULL;
959 if(!mpd_check_connected(mi))
961 debug_printf(DEBUG_WARNING,"not connected\n");
962 return NULL;
964 if(path == '\0' || path[0] == '\0')
966 debug_printf(DEBUG_ERROR, "argumant invalid\n");
967 return NULL;
969 if(mpd_lock_conn(mi))
971 debug_printf(DEBUG_ERROR,"lock failed\n");
972 return NULL;
974 mpd_sendListallInfoCommand(mi->connection,path);
975 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
978 if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
980 data = mpd_new_data_struct_append(data);
981 data->type = MPD_DATA_TYPE_SONG;
982 data->song = ent->info.song;
983 ent->info.song = NULL;
985 mpd_freeInfoEntity(ent);
987 mpd_finishCommand(mi->connection);
989 /* unlock */
990 mpd_unlock_conn(mi);
991 if(data == NULL)
993 return NULL;
995 return mpd_data_get_first(data);
997 void mpd_database_playlist_rename(MpdObj *mi, const char *old_name, const char *new_name)
999 if(!new_name || !old_name)
1001 debug_printf(DEBUG_ERROR, "old != NULL && new != NULL failed");
1002 return;
1004 if (!mpd_check_connected(mi)) {
1005 debug_printf(DEBUG_WARNING, "not connected\n");
1006 return;
1008 if (mpd_status_check(mi) != MPD_OK) {
1009 debug_printf(DEBUG_WARNING, "Failed to get status\n");
1010 return;
1012 if(mpd_lock_conn(mi))
1014 return ;
1017 mpd_sendRenameCommand(mi->connection, (char *)old_name,(char *)new_name);
1018 mpd_finishCommand(mi->connection);
1020 mpd_unlock_conn(mi);
1023 int mpd_database_playlist_move(MpdObj *mi, const char *playlist, int old_pos, int new_pos)
1025 if(!mpd_check_connected(mi))
1027 debug_printf(DEBUG_WARNING,"not connected\n");
1028 return MPD_NOT_CONNECTED;
1030 if(mpd_lock_conn(mi))
1032 debug_printf(DEBUG_ERROR,"lock failed\n");
1033 return MPD_LOCK_FAILED;
1036 mpd_sendPlaylistMoveCommand(mi->connection,(char *)playlist,old_pos, new_pos);
1037 mpd_finishCommand(mi->connection);
1039 /* unlock */
1040 mpd_unlock_conn(mi);
1041 return MPD_OK;
1045 MpdData * mpd_database_playlist_list(MpdObj *mi)
1047 MpdData *data = NULL;
1048 mpd_InfoEntity *ent = NULL;
1049 if(!mpd_check_connected(mi))
1051 debug_printf(DEBUG_WARNING,"not connected\n");
1052 return NULL;
1054 if(mpd_lock_conn(mi))
1056 debug_printf(DEBUG_ERROR,"lock failed\n");
1057 return NULL;
1059 if(mpd_server_check_command_allowed(mi, "listplaylists") == MPD_SERVER_COMMAND_ALLOWED)
1061 mpd_sendListPlaylistsCommand(mi->connection);
1063 else
1065 mpd_sendLsInfoCommand (mi->connection ,"/");
1067 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
1070 if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
1072 data = mpd_new_data_struct_append(data);
1073 data->type = MPD_DATA_TYPE_PLAYLIST;
1074 data->playlist= ent->info.playlistFile;
1075 ent->info.playlistFile = NULL;
1077 mpd_freeInfoEntity(ent);
1079 mpd_finishCommand(mi->connection);
1081 /* unlock */
1082 mpd_unlock_conn(mi);
1083 if(data == NULL)
1085 return NULL;
1087 return mpd_data_get_first(data);