X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mysql_selector.c;h=eaee16a986d4b33297b571e630fd02ed95dc1198;hp=8148fabe04310739a577b99add1783de94f0f14d;hb=2d8f0c21ac8735fc06d1aa88e7873614392e3042;hpb=471684761a2039bbc89aa1e3c33c62de6bef86cf diff --git a/mysql_selector.c b/mysql_selector.c index 8148fabe..eaee16a9 100644 --- a/mysql_selector.c +++ b/mysql_selector.c @@ -10,23 +10,29 @@ #define MEDIUM_BLOB_SIZE 16777220 /* (2**24 + 4) */ #define BLOB_SIZE 65539 /* (2**16 + 3) */ /** \endcond */ + +#include "para.h" #include "server.cmdline.h" +#include "afh.h" #include "server.h" #include "vss.h" -#include "afs.h" +#include "afs_common.h" #include #include #include #include "error.h" #include "net.h" #include "string.h" +#include "list.h" #include "user_list.h" #include "mysql_selector_command_list.h" +#include "ipc.h" /** pointer to the shared memory area */ extern struct misc_meta_data *mmd; static void *mysql_ptr = NULL; +static int mysql_lock; /** * contains name/replacement pairs used by s_a_r_list() @@ -65,11 +71,11 @@ static const struct para_macro mysql_macro_list[] = { }; /** - * simple search and replace routine + * Simple search and replace routine. * - * \param src source string - * \param macro_name the name of the macro - * \param replacement the replacement format string + * \param src Source String. + * \param macro_name The name of the macro. + * \param replacement The replacement format string. * * In \p src, replace each occurence of \p macro_name(arg) by the string * determined by the \p replacement format string. \p replacement may (but @@ -77,7 +83,7 @@ static const struct para_macro mysql_macro_list[] = { * replaced by \p arg. * * \return A string in which all matches in \p src are replaced, or \p NULL if - * an syntax error was encountered. Caller must free the result. + * an error was encountered. Caller must free the result. * * \sa regcomp(3) */ @@ -93,7 +99,8 @@ __must_check __malloc static char *s_a_r(const char *src, const char* macro_name if (!macro_name || !replacement || !src) return para_strdup(src); - regcomp(&preg, macro_name, 0); + if (regcomp(&preg, macro_name, 0) != 0) + return NULL; while (regexec(&preg, bufptr, nmatch, pmatch, eflags) != REG_NOMATCH) { char *tmp, *arg, *o_bracket, *c_bracket; @@ -152,7 +159,7 @@ __must_check __malloc static char *s_a_r_list(const struct para_macro *macro_lis return ret; } -static int real_query(const char *query) +static int lockless_real_query(const char *query) { if (!mysql_ptr) return -E_NOTCONN; @@ -165,19 +172,32 @@ static int real_query(const char *query) return 1; } +static int real_query(const char *query) +{ + int ret; + + mutex_lock(mysql_lock); + ret = lockless_real_query(query); + mutex_unlock(mysql_lock); + return ret; +} + /* * Use open connection given by mysql_ptr to query server. Returns a * result pointer on succes and NULL on errors */ static struct MYSQL_RES *get_result(const char *query) { - void *result; + void *result = NULL; - if (real_query(query) < 0) - return NULL; + mutex_lock(mysql_lock); + if (lockless_real_query(query) < 0) + goto out; result = mysql_store_result(mysql_ptr); if (!result) PARA_ERROR_LOG("%s", "store_result error\n"); +out: + mutex_unlock(mysql_lock); return result; } /* @@ -246,7 +266,7 @@ static char *escaped_basename(const char *name) /* * new attribute */ -int com_na(__a_unused int fd, int argc, char *argv[]) +int com_na(__a_unused int fd, int argc, char * const * argv) { char *q, *tmp; int ret; @@ -267,7 +287,7 @@ int com_na(__a_unused int fd, int argc, char *argv[]) /* * delete attribute */ -int com_da(__a_unused int fd, int argc, char *argv[]) +int com_da(__a_unused int fd, int argc, char * const * argv) { char *q, *tmp; int ret; @@ -285,7 +305,7 @@ int com_da(__a_unused int fd, int argc, char *argv[]) } /* stradd/pic_add */ -static int com_stradd_picadd(int fd, int argc, char *argv[]) +static int com_stradd_picadd(int fd, int argc, char * const * argv) { char *blob = NULL, *esc_blob = NULL, *q = NULL, *tmp = NULL; const char *fmt, *del_fmt; @@ -341,13 +361,13 @@ out: } /* stradd */ -int com_stradd(int fd, int argc, char *argv[]) +int com_stradd(int fd, int argc, char * const * argv) { return com_stradd_picadd(fd, argc, argv); } /* pic_add */ -int com_picadd(int fd, int argc, char *argv[]) +int com_picadd(int fd, int argc, char * const * argv) { return com_stradd_picadd(fd, argc, argv); } @@ -383,7 +403,7 @@ static int print_results(int fd, void *result, /* * verbatim */ -int com_verb(int fd, int argc, char *argv[]) +int com_verb(int fd, int argc, char * const * argv) { void *result = NULL; int ret; @@ -430,7 +450,7 @@ static void *get_all_attributes(void) /* * list all attributes */ -int com_laa(int fd, int argc, __a_unused char *argv[]) +int com_laa(int fd, int argc, __a_unused char * const * argv) { void *result; int ret; @@ -453,7 +473,7 @@ int com_laa(int fd, int argc, __a_unused char *argv[]) /* * history */ -int com_hist(int fd, int argc, char *argv[]) +int com_hist(int fd, int argc, char * const * argv) { int ret; void *result = NULL; @@ -489,7 +509,7 @@ int com_hist(int fd, int argc, char *argv[]) /* * get last num audio files */ -int com_last(int fd, int argc, char *argv[]) +int com_last(int fd, int argc, char * const * argv) { void *result = NULL; char *q; @@ -514,7 +534,7 @@ int com_last(int fd, int argc, char *argv[]) return ret; } -int com_mbox(int fd, int argc, char *argv[]) +int com_mbox(int fd, int argc, char * const * argv) { void *result; MYSQL_ROW row; @@ -720,7 +740,7 @@ err_out: * If filename is NULL, query will list everything, otherwise only * the score of given file. */ -static char *get_query(char *streamname, char *filename, int with_path) +static char *get_query(const char *streamname, char *filename, int with_path) { char *accept_opts = NULL, *deny_opts = NULL, *score = NULL; char *where_clause, *order, *query; @@ -931,7 +951,7 @@ static void refresh_selector_info(void) } /* list attributes / print database info */ -static int com_la_info(int fd, int argc, char *argv[]) +static int com_la_info(int fd, int argc, char * const * argv) { char *name = NULL, *meta = NULL, *atts = NULL, *dir = NULL; int ret, la = strcmp(argv[0], "info"); @@ -965,13 +985,13 @@ out: } /* list attributes */ -int com_la(int fd, int argc, char *argv[]) +int com_la(int fd, int argc, char * const * argv) { return com_la_info(fd, argc, argv); } /* print database info */ -int com_info(int fd, int argc, char *argv[]) +int com_info(int fd, int argc, char * const * argv) { return com_la_info(fd, argc, argv); } @@ -1071,7 +1091,7 @@ out: /* * remove/add entries */ -static int com_rm_ne(__a_unused int fd, int argc, char *argv[]) +static int com_rm_ne(__a_unused int fd, int argc, char * const * argv) { int ne = !strcmp(argv[0], "ne"); int i, ret; @@ -1093,7 +1113,7 @@ static int com_rm_ne(__a_unused int fd, int argc, char *argv[]) /* * rm */ -int com_rm(int fd, int argc, char *argv[]) +int com_rm(int fd, int argc, char * const * argv) { return com_rm_ne(fd, argc, argv); } @@ -1101,7 +1121,7 @@ int com_rm(int fd, int argc, char *argv[]) /* * ne */ -int com_ne(int fd, int argc, char *argv[]) +int com_ne(int fd, int argc, char * const * argv) { return com_ne(fd, argc, argv); } @@ -1109,7 +1129,7 @@ int com_ne(int fd, int argc, char *argv[]) /* * mv: rename entry */ -int com_mv(__a_unused int fd, int argc, char *argv[]) +int com_mv(__a_unused int fd, int argc, char * const * argv) { char *q, *dn, *ebn1 = NULL, *ebn2 = NULL, *edn = NULL; int ret; @@ -1167,7 +1187,7 @@ out: /* * set field */ -static int com_set(__a_unused int fd, int argc, char *argv[]) +static int com_set(__a_unused int fd, int argc, char * const * argv) { char *q, *ebn; long unsigned id; @@ -1195,7 +1215,7 @@ static int com_set(__a_unused int fd, int argc, char *argv[]) /* * snp: set numplayed */ -int com_picass(int fd, int argc, char *argv[]) +int com_picass(int fd, int argc, char * const * argv) { return com_set(fd, argc, argv); } @@ -1203,7 +1223,7 @@ int com_picass(int fd, int argc, char *argv[]) /* * snp: set numplayed */ -int com_snp(int fd, int argc, char *argv[]) +int com_snp(int fd, int argc, char * const * argv) { int ret = com_set(fd, argc, argv); if (ret >= 0) @@ -1214,7 +1234,7 @@ int com_snp(int fd, int argc, char *argv[]) /* * picch: change entry's name in pics table */ -int com_picch(__a_unused int fd, int argc, char *argv[]) +int com_picch(__a_unused int fd, int argc, char * const * argv) { int ret; long unsigned id; @@ -1237,7 +1257,7 @@ int com_picch(__a_unused int fd, int argc, char *argv[]) /* * piclist: print list of pics in db */ -int com_piclist(__a_unused int fd, int argc, __a_unused char *argv[]) +int com_piclist(__a_unused int fd, int argc, __a_unused char * const * argv) { void *result = NULL; MYSQL_ROW row; @@ -1266,7 +1286,7 @@ out: /* * picdel: delete picture from database */ -int com_picdel(int fd, int argc, char *argv[]) +int com_picdel(int fd, int argc, char * const * argv) { char *q; long unsigned id; @@ -1298,7 +1318,7 @@ int com_picdel(int fd, int argc, char *argv[]) /* * pic: get picture by name or by number */ -int com_pic(int fd, int argc, char *argv[]) +int com_pic(int fd, int argc, char * const * argv) { void *result = NULL; MYSQL_ROW row; @@ -1339,7 +1359,7 @@ out: } /* strdel */ -int com_strdel(__a_unused int fd, int argc, char *argv[]) +int com_strdel(__a_unused int fd, int argc, char * const * argv) { char *q, *tmp; int ret; @@ -1359,7 +1379,7 @@ int com_strdel(__a_unused int fd, int argc, char *argv[]) /* * ls */ -int com_ls(int fd, int argc, char *argv[]) +int com_ls(int fd, int argc, char * const * argv) { char *q; void *result; @@ -1392,7 +1412,7 @@ int com_ls(int fd, int argc, char *argv[]) /* * summary */ -int com_summary(__a_unused int fd, int argc, __a_unused char *argv[]) +int com_summary(__a_unused int fd, int argc, __a_unused char * const * argv) { MYSQL_ROW row; MYSQL_ROW row2; @@ -1458,7 +1478,7 @@ out: return ret; } -static int update_audio_file(char *name) +static int update_audio_file(const char *name) { int ret; const char *fmt1 = "update data set lastplayed = now() where name = '%s'"; @@ -1494,7 +1514,7 @@ static void update_audio_file_server_handler(char *name) update_audio_file(name); } -int com_us(__a_unused int fd, int argc, char *argv[]) +int com_us(__a_unused int fd, int argc, char * const * argv) { char *tmp; int ret; @@ -1512,7 +1532,7 @@ int com_us(__a_unused int fd, int argc, char *argv[]) } /* select previous / next stream */ -static int com_ps_ns(__a_unused int fd, int argc, char *argv[]) +static int com_ps_ns(__a_unused int fd, int argc, char * const * argv) { char *query, *stream = get_current_stream(); void *result = get_result("select name from streams"); @@ -1578,19 +1598,19 @@ out: } /* select previous stream */ -int com_ps(int fd, int argc, char *argv[]) +int com_ps(int fd, int argc, char * const * argv) { return com_ps_ns(fd, argc, argv); } /* select next stream */ -int com_ns(int fd, int argc, char *argv[]) +int com_ns(int fd, int argc, char * const * argv) { return com_ps_ns(fd, argc, argv); } /* streams */ -int com_streams(int fd, int argc, __a_unused char *argv[]) +int com_streams(int fd, int argc, __a_unused char * const * argv) { unsigned int num_rows; int i, ret = -E_NORESULT; @@ -1628,7 +1648,7 @@ out: } /* query stream definition */ -int com_strq(int fd, int argc, char *argv[]) +int com_strq(int fd, int argc, char * const * argv) { MYSQL_ROW row; char *query, *name; @@ -1664,7 +1684,7 @@ out: } /* change stream / change stream and play */ -static int com_cs_csp(int fd, int argc, char *argv[]) +static int com_cs_csp(int fd, int argc, char * const * argv) { int ret, stream_change; char *query, *stream = NULL; @@ -1712,19 +1732,19 @@ out: } /* change stream */ -int com_cs(int fd, int argc, char *argv[]) +int com_cs(int fd, int argc, char * const * argv) { return com_cs_csp(fd, argc, argv); } /* change stream and play */ -int com_csp(int fd, int argc, char *argv[]) +int com_csp(int fd, int argc, char * const * argv) { return com_cs_csp(fd, argc, argv); } /* score list / skip */ -static int com_sl_skip(int fd, int argc, char *argv[]) +static int com_sl_skip(int fd, int argc, char * const * argv) { void *result = NULL; MYSQL_ROW row; @@ -1777,13 +1797,13 @@ out: } /* score list */ -int com_sl(int fd, int argc, char *argv[]) +int com_sl(int fd, int argc, char * const * argv) { return com_sl_skip(fd, argc, argv); } /* skip */ -int com_skip(int fd, int argc, char *argv[]) +int com_skip(int fd, int argc, char * const * argv) { return com_sl_skip(fd, argc, argv); } @@ -1791,7 +1811,7 @@ int com_skip(int fd, int argc, char *argv[]) /* * update attributes of name */ -static int update_atts(int fd, char *name, char *atts) +static int update_atts(int fd, const char *name, char *atts) { int ret; char *ebn, *q, *old, *new = NULL; @@ -1820,7 +1840,7 @@ out: /* * set attributes */ -int com_sa(int fd, int argc, char *argv[]) +int com_sa(int fd, int argc, char * const * argv) { int i, ret; char *atts = NULL, *name; @@ -1829,12 +1849,12 @@ int com_sa(int fd, int argc, char *argv[]) return -E_MYSQL_SYNTAX; for (i = 1; i < argc; i++) { int unset = 0; - char *esc, *tmp, *p =argv[i]; - int len = strlen(p); + char *esc, *tmp, *p; + int len = strlen(argv[i]); if (!len) continue; - switch (p[len - 1]) { + switch (argv[i][len - 1]) { case '+': unset = 0; break; @@ -1844,8 +1864,10 @@ int com_sa(int fd, int argc, char *argv[]) default: goto no_more_atts; } + p = para_strdup(argv[i]); p[len - 1] = '\0'; esc = escape_str(p); + free(p); if (!esc) return -E_ESCAPE; tmp = make_message("%s%s='%s'", atts? "," : "", esc, @@ -1877,7 +1899,7 @@ out: /* * copy attributes */ -int com_cam(int fd, int argc, char *argv[]) +int com_cam(int fd, int argc, char * const * argv) { char *name = NULL, *meta = NULL, *atts = NULL; int i, ret; @@ -1925,7 +1947,7 @@ out: /* * verify / clean */ -static int com_vrfy_clean(int fd, int argc, __a_unused char *argv[]) +static int com_vrfy_clean(int fd, int argc, __a_unused char * const * argv) { char *query; int ret, vrfy_mode = strcmp(argv[0], "clean"); @@ -1947,7 +1969,7 @@ static int com_vrfy_clean(int fd, int argc, __a_unused char *argv[]) goto out; } if (vrfy_mode) { - send_va_buffer(fd, "found %i invalid entr%s\n", num_rows, + send_va_buffer(fd, "found %lli invalid entr%s\n", num_rows, num_rows == 1? "y" : "ies"); ret = print_results(fd, result, top, left, num_rows - 1, right); goto out; @@ -1978,7 +2000,7 @@ out: /* * verify */ -int com_vrfy(int fd, int argc, char **argv) +int com_vrfy(int fd, int argc, char * const * argv) { return com_vrfy_clean(fd, argc, argv); } @@ -1986,7 +2008,7 @@ int com_vrfy(int fd, int argc, char **argv) /* * clean */ -int com_clean(int fd, int argc, char **argv) +int com_clean(int fd, int argc, char * const * argv) { return com_vrfy_clean(fd, argc, argv); } @@ -2006,7 +2028,7 @@ static int mysql_write_tmp_file(const char *dir, const char *name) /* * update database */ -int com_upd(int fd, int argc, __a_unused char *argv[]) +int com_upd(int fd, int argc, __a_unused char * const * argv) { char *tempname = NULL, *query = NULL; int ret, out_fd = -1, num = 0; @@ -2177,7 +2199,7 @@ static void write_msg2mmd(int success) } /* create database */ -int com_cdb(int fd, int argc, char *argv[]) +int com_cdb(int fd, int argc, char * const * argv) { char *query; int ret; @@ -2244,11 +2266,19 @@ out: static void shutdown_connection(void) { + int ret; + if (mysql_ptr) { PARA_NOTICE_LOG("%s", "shutting down mysql connection\n"); mysql_close(mysql_ptr); mysql_ptr = NULL; } + if (mysql_lock) { + ret = mutex_destroy(mysql_lock); + if (ret < 0) + PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); + mysql_lock = 0; + } } /** @@ -2280,6 +2310,10 @@ int mysql_selector_init(struct audio_file_selector *db) db->get_audio_file_list = server_get_audio_file_list; db->update_audio_file = update_audio_file_server_handler; db->shutdown = shutdown_connection; + ret = mutex_new(); + if (ret < 0) + return ret; + mysql_lock = ret; ret = init_mysql_server(); if (ret < 0) PARA_WARNING_LOG("%s\n", PARA_STRERROR(-ret));