1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
5 * Portable frontend to MediaDatabase
8 * gcc main.c -lmysqlclient -o mdb_cui [-DOPENBSD]
11 * Nedko Arnaudov <nedko@users.sourceforge.net>
14 * GNU GENERAL PUBLIC LICENSE version 2
16 *****************************************************************************/
21 #include <sys/types.h>
31 extern char **environ
;
33 #include "../libdb/libdb.h"
34 #include "../libdb/memory.h"
40 #define MAX_TITLE_SIZE 128 /* in db */
41 #define MAX_PASS_SIZE 1024
42 #define DEFAULT_MYSQL_USER "mediadatabase"
43 #define DEFAULT_MYSQL_PASS ""
44 #define DEFAULT_MYSQL_HOST "localhost"
45 #define DEFAULT_MYSQL_DB "mediadatabase"
47 #define DEFAULT_MOUNT_CMD "sudo /sbin/mount /cdrom"
48 #define DEFAULT_UNMOUNT_CMD "sudo /sbin/umount /cdrom"
50 #define DEFAULT_MOUNT_CMD "/bin/mount /cdrom"
51 #define DEFAULT_UNMOUNT_CMD "/bin/umount /cdrom"
53 #define DEFAULT_MOUNTDIR "/cdrom"
54 #define MAX_PATH_DEPTH 65535
56 #define CONF_FILE ".mediadatabase"
57 #define CFL_SECTION_GLOBAL NULL
58 #define CFL_SECTION_CUI "cui"
59 #define CFL_SECTION_MYSQL "MySQL"
60 #define CFL_SECTION_SQLITE "SQLite"
61 #define CFL_VALUE_MYSQL_HOST "host"
62 #define CFL_VALUE_MYSQL_USER "user"
63 #define CFL_VALUE_MYSQL_PASS "pass"
64 #define CFL_VALUE_MYSQL_DB "db"
65 #define CFL_VALUE_MOUNT "mount"
66 #define CFL_VALUE_UNMOUNT "unmount"
67 #define CFL_VALUE_MOUNTDIR "mountdir"
69 //#define PRINT_FILENAMES
71 char strTitle
[MAX_TITLE_SIZE
+2]; /* + newline + null */
72 char strPass
[MAX_PASS_SIZE
];
73 char *pszPathBuffer
= NULL
;
74 size_t nPathBufferSize
= 0;
75 size_t nMountPrefixLength
;
76 unsigned long nTotalFiles
;
77 unsigned long long nTotalSize
;
78 mediadb_uint nMediaID
= 0ULL;
79 mediadb hDB
= MEDIADB_INVALID_VALUE
;
80 int blnMediaMounted
= 0;
86 char *pszMountMediaCommand
= NULL
;
87 char *pszUnmountMediaCommand
= NULL
;
88 char *pszMountDir
= NULL
;
89 char *pszTitle
= NULL
;
91 #define MODE_LIST_MEDIA 0
92 #define MODE_ADD_MEDIA 1
93 #define MODE_UPDATE_MEDIA 2
94 unsigned int nMode
= MODE_LIST_MEDIA
;
97 ExecuteCommand(const char *pszCommand
);
102 printf("--> Mounting media ...\n");
103 ExecuteCommand(pszMountMediaCommand
);
104 printf("--> Media mounted.\n");
111 printf("--> Unmounting media ...\n");
112 ExecuteCommand(pszUnmountMediaCommand
);
113 printf("--> Media unmounted.\n");
127 if (hDB
!= MEDIADB_INVALID_VALUE
)
129 r
= mediadb_close(hDB
);
147 if (pszMountMediaCommand
!= NULL
)
148 free(pszMountMediaCommand
);
150 if (pszUnmountMediaCommand
!= NULL
)
151 free(pszUnmountMediaCommand
);
153 if (pszMountDir
!= NULL
)
156 if (pszTitle
!= NULL
)
163 ExecuteCommand(const char *pszCommand
)
167 nRet
= system(pszCommand
);
171 "Cannot execute command \"%s\". "
172 "system() returned -1, error is %d (%s)\n",
181 if (WEXITSTATUS(nRet
) != 0)
184 "Cannot execute command \"%s\". "
185 "Command returned %d\n",
187 (int)WEXITSTATUS(nRet
));
191 else if (WIFSIGNALED(nRet
))
194 "Cannot execute command \"%s\". "
195 "Cammand was terminated because of signal %d\n",
197 (int)WTERMSIG(nRet
));
203 "Cannot execute command \"%s\". "
204 "system() returned %d\n",
212 ReadTitleExitOnEmpty()
217 if (fgets(strTitle
, sizeof(strTitle
), stdin
) == NULL
)
226 fprintf(stderr
, "Error occured while reading standard input.\n");
229 else if (strTitle
[0] == '\n')
234 if ((pch
= strchr(strTitle
, '\n')) == NULL
)
236 fprintf(stderr
, "input line too long.\n");
247 char strMediaID
[100];
249 printf("Media ID: ");
250 if (fgets(strMediaID
, sizeof(strMediaID
), stdin
) == NULL
)
259 fprintf(stderr
, "Error occured while reading standard input.\n");
262 else if (strMediaID
[0] == '\n')
267 if ((pch
= strchr(strMediaID
, '\n')) == NULL
)
269 fprintf(stderr
, "input line too long.\n");
275 nMediaID
= strtoull(strMediaID
, NULL
, 10);
283 ReadTitleIgnoreOnEmpty()
288 if (fgets(strTitle
, sizeof(strTitle
), stdin
) == NULL
)
294 strcpy(strTitle
, pszTitle
);
298 fprintf(stderr
, "Error occured while reading standard input.\n");
301 else if (strTitle
[0] == '\n')
303 strcpy(strTitle
, pszTitle
);
307 if ((pch
= strchr(strTitle
, '\n')) == NULL
)
309 fprintf(stderr
, "input line too long.\n");
321 pszPass
= getpass("MySQL password: ");
323 strcpy(strPass
, pszPass
);
327 MaybeEnlargeBuffer(char ** ppBuffer
,
328 size_t *pnBufferSize
,
329 size_t nSizeRequired
)
333 r
= maybe_enlarge_buffer(
337 if (MEDIADB_IS_ERROR(r
))
340 "Cannot enlarge buffer.\n");
346 ScanDir(unsigned long nDepth
)
351 size_t nCurrentPathLength
;
355 if (nDepth
>= MAX_PATH_DEPTH
)
358 "Max path depth of reached \"%u\"\n",
359 (unsigned int)MAX_PATH_DEPTH
);
363 nCurrentPathLength
= strlen(pszPathBuffer
);
365 pDir
= opendir(pszPathBuffer
);
368 fprintf(stderr
, "Cannot open \"%s\"\n", pszPathBuffer
);
374 while ((pDE
= readdir(pDir
)) != NULL
)
376 if (strcmp(pDE
->d_name
, ".") == 0)
379 if (strcmp(pDE
->d_name
, "..") == 0)
383 sizeName
= pDE
->d_namlen
;
385 sizeName
= strlen(pDE
->d_name
);
388 MaybeEnlargeBuffer(&pszPathBuffer
,
390 nCurrentPathLength
+ sizeName
+ 1);
392 memcpy(pszPathBuffer
+ nCurrentPathLength
, pDE
->d_name
, sizeName
);
393 pszPathBuffer
[nCurrentPathLength
+ sizeName
] = 0;
395 if (lstat(pszPathBuffer
, &st
) != 0)
398 "Cannot stat() %s. Error is %d (%s)\n",
404 pszPathBuffer
[nCurrentPathLength
] = 0;
406 r
= mediadb_file_add_new(
409 (S_ISDIR(st
.st_mode
))?MEDIADB_FILETYPE_DIR
:MEDIADB_FILETYPE_FILE
,
410 pszPathBuffer
+ nMountPrefixLength
,
412 ((S_ISDIR(st
.st_mode
))?0:st
.st_size
),
414 if (MEDIADB_IS_ERROR(r
))
417 "Failed to add new file to database. Error is %d (%s)\n",
419 mediadb_get_error_message(hDB
));
422 memcpy(pszPathBuffer
+ nCurrentPathLength
, pDE
->d_name
, sizeName
);
423 pszPathBuffer
[nCurrentPathLength
+ sizeName
] = 0;
425 #ifdef PRINT_FILENAMES
426 printf("%s", pszPathBuffer
+ nMountPrefixLength
);
431 if (S_ISDIR(st
.st_mode
))
433 #ifdef PRINT_FILENAMES
439 memcpy(pszPathBuffer
+ nCurrentPathLength
+ sizeName
, "/", 2);
444 nTotalSize
+= st
.st_size
;
445 #ifdef PRINT_FILENAMES
463 pszHost
= strdup(DEFAULT_MYSQL_HOST
);
474 pszUser
= strdup(DEFAULT_MYSQL_USER
);
485 pszPass
= strdup(DEFAULT_MYSQL_PASS
);
496 pszDB
= strdup(DEFAULT_MYSQL_DB
);
505 if (pszMountMediaCommand
== NULL
)
507 pszMountMediaCommand
= strdup(DEFAULT_MOUNT_CMD
);
508 if (pszMountMediaCommand
== NULL
)
516 if (pszUnmountMediaCommand
== NULL
)
518 pszUnmountMediaCommand
= strdup(DEFAULT_UNMOUNT_CMD
);
519 if (pszUnmountMediaCommand
== NULL
)
527 if (pszMountDir
== NULL
)
529 pszMountDir
= strdup(DEFAULT_MOUNTDIR
);
530 if (pszMountDir
== NULL
)
544 pszExecutable
= strrchr(arg0
, '/');
546 if (pszExecutable
== NULL
)
548 pszExecutable
= arg0
;
557 printf("==============================\n");
558 printf("Offline media content database\n");
559 printf("==============================\n");
561 printf("[<path_to>]%s [options]\n", pszExecutable
);
562 printf(" Options can be:\n");
563 printf(" -? - This help\n");
564 printf(" -L - List media mode\n");
565 printf(" -A - Add media mode\n");
566 printf(" -U - Update media mode\n");
567 printf(" -m <mount_cmd> - command to mount media, default is \"%s\"\n", pszMountMediaCommand
);
568 printf(" -n <unmount_cmd> - command to unmount, default is \"%s\"\n", pszUnmountMediaCommand
);
569 printf(" -d <mount_dir> - where media is mounted, default is \"%s\"\n", pszMountDir
);
570 printf(" -h <mysql_host> - MySQL server host, default is \"%s\"\n", pszHost
);
571 printf(" -u <mysql_user> - MySQL user, default is \"%s\"\n", pszUser
);
572 printf(" -p [mysql_pass] - MySQL password, default is \"%s\"\n", pszPass
);
573 printf(" -b <mysql_database> - MySQL database, default is \"%s\"\n", pszDB
);
583 printf("NOTE: Currently audio media is not supported.\n");
586 memcpy(pszPathBuffer
+ nMountPrefixLength
, "/", 2);
588 printf("--> Please insert media and enter title.\n");
590 ReadTitleExitOnEmpty();
594 printf("--> Processing media ...\n");
596 r
= mediadb_media_add_new(
603 if (MEDIADB_IS_ERROR(r
))
606 "Failed to add new media to database. Error is %d (%s)\n",
608 mediadb_get_error_message(hDB
));
616 timeAdded
= time(NULL
);
618 r
= mediadb_media_update_properties(
625 if (MEDIADB_IS_ERROR(r
))
628 "Failed to update new media to database. Error is %d (%s)\n",
630 mediadb_get_error_message(hDB
));
636 printf("--> SUCCESS - Media added.\n");
637 printf("Media title: %s\n", strTitle
);
638 printf("Media ID: %u\n", (unsigned int)nMediaID
);
639 printf("Added: %s", ctime(&timeAdded
));
640 printf("Total files: %u\n", (unsigned int)nTotalFiles
);
641 printf("Total size: %u\n", (unsigned int)nTotalSize
);
651 mediadb_uint nTimeAdded
;
652 mediadb_uint nTotalFiles
;
653 mediadb_uint nTotalSize
;
655 printf("NOTE: Currently audio media is not supported.\n");
658 printf("--> Please enter Media ID.\n");
662 memcpy(pszPathBuffer
+ nMountPrefixLength
, "/", 2);
664 r
= mediadb_media_get_properties(
671 if (MEDIADB_IS_ERROR(r
))
674 "Failed to get media properties. Error is %d (%s)\n",
676 mediadb_get_error_message(hDB
));
680 if (strlen(pszTitle
) + 1 > MAX_TITLE_SIZE
)
687 timeAdded
= (time_t)nTimeAdded
;
689 printf("Media title: %s\n", pszTitle
);
690 printf("Added: %s", ctime(&timeAdded
));
691 printf("Total files: %u\n", (unsigned int)nTotalFiles
);
692 printf("Total size: %u\n", (unsigned int)nTotalSize
);
694 printf("--> Please insert media and enter title (Just press return to keep current title).\n");
696 ReadTitleIgnoreOnEmpty();
700 printf("--> Processing media ...\n");
702 if (strcmp(pszTitle
, strTitle
) != 0)
704 r
= mediadb_media_update_name(
708 if (MEDIADB_IS_ERROR(r
))
711 "Cannot update media title. Error is %d (%s)\n",
713 mediadb_get_error_message(hDB
));
718 r
= mediadb_delete_media_files(
722 if (MEDIADB_IS_ERROR(r
))
725 "Failed to delete media files in database. Error is %d (%s)\n",
727 mediadb_get_error_message(hDB
));
735 //timeAdded = time(NULL);
737 r
= mediadb_media_update_properties(
744 if (MEDIADB_IS_ERROR(r
))
747 "Failed to update new media to database. Error is %d (%s)\n",
749 mediadb_get_error_message(hDB
));
755 printf("--> SUCCESS - Media added.\n");
756 printf("Media title: %s\n", strTitle
);
757 printf("Media ID: %u\n", (unsigned int)nMediaID
);
758 printf("Added: %s", ctime(&timeAdded
));
759 printf("Total files: %u\n", (unsigned int)nTotalFiles
);
760 printf("Total size: %u\n", (unsigned int)nTotalSize
);
768 printf("List media mode not implemented yet.\n");
787 cfl_value_type_t CFLValueType
;
790 pszExecutable
= strrchr(argv
[0], '/');
792 if (pszExecutable
== NULL
)
794 pszExecutable
= argv
[0];
801 if (strcmp(pszExecutable
, "mdb_add") == 0)
803 nMode
= MODE_ADD_MEDIA
;
805 else if (strcmp(pszExecutable
, "mdb_update") == 0)
807 nMode
= MODE_UPDATE_MEDIA
;
811 nMode
= MODE_LIST_MEDIA
;
814 /* Find HOME environment variable */
819 if (strncasecmp(*ppsz
, "HOME=", 5) == 0)
830 "Please set the HOME encironment variable.\n");
834 /* Look into configuration file */
836 s
= strlen(pszHOME
) + 1 + strlen(CONF_FILE
) + 1;
837 pszConf
= (char *)malloc(s
);
838 sprintf(pszConf
, "%s/%s", pszHOME
, CONF_FILE
);
840 hFile
= fopen(pszConf
, "r");
851 nRet
= cfl_init_from_file(
854 CFL_FILE_TYPE_DEFAULT
);
857 printf("cfl_init_from_file() failed. (%s)\n", cfl_errcode_to_message(nRet
));
860 pszCFLValue
= cfl_value_get_by_name(
866 if (pszCFLValue
!= NULL
&&
867 CFLValueType
== CFL_TYPE_STRING
)
869 pszMountMediaCommand
= strdup(pszCFLValue
);
870 if (pszMountMediaCommand
== NULL
)
878 pszCFLValue
= cfl_value_get_by_name(
884 if (pszCFLValue
!= NULL
&&
885 CFLValueType
== CFL_TYPE_STRING
)
887 pszUnmountMediaCommand
= strdup(pszCFLValue
);
888 if (pszUnmountMediaCommand
== NULL
)
896 pszCFLValue
= cfl_value_get_by_name(
902 if (pszCFLValue
!= NULL
&&
903 CFLValueType
== CFL_TYPE_STRING
)
905 pszMountDir
= strdup(pszCFLValue
);
906 if (pszMountDir
== NULL
)
914 pszCFLValue
= cfl_value_get_by_name(
917 CFL_VALUE_MYSQL_HOST
,
920 if (pszCFLValue
!= NULL
&&
921 CFLValueType
== CFL_TYPE_STRING
)
923 pszHost
= strdup(pszCFLValue
);
932 pszCFLValue
= cfl_value_get_by_name(
938 if (pszCFLValue
!= NULL
&&
939 CFLValueType
== CFL_TYPE_STRING
)
941 pszDB
= strdup(pszCFLValue
);
950 pszCFLValue
= cfl_value_get_by_name(
953 CFL_VALUE_MYSQL_USER
,
956 if (pszCFLValue
!= NULL
&&
957 CFLValueType
== CFL_TYPE_STRING
)
959 pszUser
= strdup(pszCFLValue
);
968 pszCFLValue
= cfl_value_get_by_name(
971 CFL_VALUE_MYSQL_PASS
,
974 if (pszCFLValue
!= NULL
&&
975 CFLValueType
== CFL_TYPE_STRING
)
977 pszPass
= strdup(pszCFLValue
);
991 /* Process options from command line */
993 for (i
= 1; i
< argc
; i
++)
995 if (strcmp(argv
[i
],"-L") == 0)
997 nMode
= MODE_LIST_MEDIA
;
999 else if (strcmp(argv
[i
],"-A") == 0)
1001 nMode
= MODE_ADD_MEDIA
;
1003 else if (strcmp(argv
[i
],"-U") == 0)
1005 nMode
= MODE_UPDATE_MEDIA
;
1007 else if (strcmp(argv
[i
],"-h") == 0)
1012 if (pszHost
!= NULL
)
1014 pszHost
= strdup(argv
[i
]);
1015 if (pszHost
== NULL
)
1018 "Out of memory.\n");
1025 "Missing parameter of -h option\n");
1029 else if (strcmp(argv
[i
],"-u") == 0)
1034 if (pszUser
!= NULL
)
1036 pszUser
= strdup(argv
[i
]);
1037 if (pszUser
== NULL
)
1040 "Out of memory.\n");
1047 "Missing parameter of -u option\n");
1051 else if (strcmp(argv
[i
],"-p") == 0)
1053 if (i
+1 < argc
&& argv
[i
+1][0] != '-')
1056 if (pszPass
!= NULL
)
1058 pszPass
= strdup(argv
[i
]);
1059 if (pszPass
== NULL
)
1062 "Out of memory.\n");
1069 if (pszPass
!= NULL
)
1071 pszPass
= strdup(strPass
);
1072 if (pszPass
== NULL
)
1075 "Out of memory.\n");
1080 else if (strcmp(argv
[i
],"-b") == 0)
1087 pszDB
= strdup(argv
[i
]);
1091 "Out of memory.\n");
1098 "Missing parameter of -b option\n");
1102 else if (strcmp(argv
[i
],"-m") == 0)
1107 if (pszMountMediaCommand
!= NULL
)
1108 free(pszMountMediaCommand
);
1109 pszMountMediaCommand
= strdup(argv
[i
]);
1110 if (pszMountMediaCommand
== NULL
)
1113 "Out of memory.\n");
1120 "Missing parameter of -m option\n");
1124 else if (strcmp(argv
[i
],"-n") == 0)
1129 if (pszUnmountMediaCommand
!= NULL
)
1130 free(pszUnmountMediaCommand
);
1131 pszUnmountMediaCommand
= strdup(argv
[i
]);
1132 if (pszUnmountMediaCommand
== NULL
)
1135 "Out of memory.\n");
1142 "Missing parameter of -n option\n");
1146 else if (strcmp(argv
[i
],"-d") == 0)
1151 if (pszMountDir
!= NULL
)
1153 pszMountDir
= strdup(argv
[i
]);
1154 if (pszMountDir
== NULL
)
1157 "Out of memory.\n");
1164 "Missing parameter of -d option\n");
1168 else if (strcmp(argv
[i
],"-?") == 0)
1175 "Unknown option \"%s\"\n",
1184 MEDIADB_DBTYPE_MYSQL
,
1190 if (MEDIADB_IS_ERROR(r
))
1192 fprintf(stderr
, "Failed to connect to database.\n");
1196 nMountPrefixLength
= strlen(pszMountDir
);
1198 MaybeEnlargeBuffer(&pszPathBuffer
,
1200 nMountPrefixLength
+ 2);
1202 memcpy(pszPathBuffer
, pszMountDir
, nMountPrefixLength
);
1204 if (nMode
== MODE_ADD_MEDIA
)
1206 printf("=========================\n");
1207 printf("Add media mode\n");
1208 printf("=========================\n");
1211 else if (nMode
== MODE_UPDATE_MEDIA
)
1213 printf("=========================\n");
1214 printf("Update media mode\n");
1215 printf("=========================\n");
1218 else if (nMode
== MODE_LIST_MEDIA
)
1220 printf("=========================\n");
1221 printf("List media mode\n");
1222 printf("=========================\n");