X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mysql_selector.c;h=e2c9562c7aa64bb14e4f5f4830ca0117130aaa63;hp=c5f71cddab03614e699e02ad2c21d941196745c2;hb=e93d64d5f46d62de6fc09c05ef2b47ac1d04f340;hpb=9f07bfb31ea556c41b45cdc3f37b6ccccbc8dca0 diff --git a/mysql_selector.c b/mysql_selector.c index c5f71cdd..e2c9562c 100644 --- a/mysql_selector.c +++ b/mysql_selector.c @@ -38,7 +38,6 @@ extern struct misc_meta_data *mmd; static void *mysql_ptr = NULL; - static int com_cam(int, int, char **); static int com_cdb(int, int, char **); static int com_cs(int, int, char **); @@ -600,7 +599,7 @@ static struct para_macro macro_list[] = { } }; -static int real_query(char *query) +static int real_query(const char *query) { if (!mysql_ptr) return -E_NOTCONN; @@ -617,7 +616,7 @@ static int real_query(char *query) * 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(char *query) +static struct MYSQL_RES *get_result(const char *query) { void *result; @@ -664,7 +663,7 @@ out: return ret; } -static char *escape_blob(char* old, int size) +static char *escape_blob(const char* old, int size) { char *new; @@ -675,7 +674,7 @@ static char *escape_blob(char* old, int size) return new; } -static char *escape_str(char* old) +static char *escape_str(const char* old) { return escape_blob(old, strlen(old)); } @@ -694,15 +693,19 @@ static char *escaped_basename(const char *name) /* * new attribute */ -static int com_na(__unused int fd, int argc, char *argv[]) +static int com_na(__a_unused int fd, int argc, char *argv[]) { - char *q; + char *q, *tmp; int ret; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; + tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; q = make_message("alter table data add %s char(1) " - "not null default 0", argv[1]); + "not null default 0", tmp); + free(tmp); ret = real_query(q); free(q); return ret; @@ -711,14 +714,18 @@ static int com_na(__unused int fd, int argc, char *argv[]) /* * delete attribute */ -static int com_da(__unused int fd, int argc, char *argv[]) +static int com_da(__a_unused int fd, int argc, char *argv[]) { - char *q; + char *q, *tmp; int ret; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; - q = make_message("alter table data drop %s", argv[1]); + tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + q = make_message("alter table data drop %s", tmp); + free(tmp); ret = real_query(q); free(q); return ret; @@ -727,12 +734,12 @@ static int com_da(__unused int fd, int argc, char *argv[]) /* stradd/pic_add */ static int com_stradd_picadd(int fd, int argc, char *argv[]) { - char *blob = NULL, *esc_blob = NULL, *q; + char *blob = NULL, *esc_blob = NULL, *q = NULL, *tmp = NULL; const char *fmt, *del_fmt; int ret, stradd = strcmp(argv[0], "picadd"); size_t size; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; if (strlen(argv[1]) >= MAXLINE - 1) return -E_NAMETOOLONG; @@ -747,7 +754,11 @@ static int com_stradd_picadd(int fd, int argc, char *argv[]) fmt = "insert into pics (name, pic) values ('%s','%s')"; del_fmt="delete from pics where pic='%s'"; } - q = make_message(del_fmt, argv[1]); + tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + q = make_message(del_fmt, tmp); + free(tmp); ret = real_query(q); free(q); if (ret < 0) @@ -756,17 +767,22 @@ static int com_stradd_picadd(int fd, int argc, char *argv[]) return ret; if ((ret = fd2buf(fd, &blob, size)) < 0) return ret; - PARA_DEBUG_LOG("length: %i\n", ret); size = ret; if (stradd) blob[size] = '\0'; - esc_blob = escape_blob(blob, ret); - free(blob); + ret = -E_ESCAPE; + esc_blob = escape_blob(blob, size); if (!esc_blob) - return -E_TOOBIG; - q = make_message(fmt, argv[1], esc_blob); - free(esc_blob); + goto out; + tmp = escape_str(argv[1]); + if (!tmp) + goto out; + q = make_message(fmt, tmp, esc_blob); ret = real_query(q); +out: + free(blob); + free(esc_blob); + free(tmp); free(q); return ret; } @@ -807,10 +823,15 @@ static int com_verb(int fd, int argc, char *argv[]) void *result = NULL; int ret; unsigned int num_rows, num_fields; + char *tmp; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; - result = get_result(argv[1]); + tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + result = get_result(tmp); + free(tmp); if (!result) /* return success, because it's ok to have no results */ return 1; @@ -837,19 +858,19 @@ static void *get_all_attributes(void) mysql_free_result(result); return NULL; } - mysql_data_seek(result, 4); /* skip Lastplayed, Numplayed... */ + mysql_data_seek(result, 4); /* skip Lastplayed, Numplayed... */ return result; } /* * list all attributes */ -static int com_laa(int fd, int argc, __unused char *argv[]) +static int com_laa(int fd, int argc, __a_unused char *argv[]) { void *result; int ret; - if (argc) + if (argc != 1) return -E_MYSQL_SYNTAX; result = get_all_attributes(); if (!result) @@ -865,15 +886,24 @@ static int com_laa(int fd, int argc, __unused char *argv[]) static int com_hist(int fd, int argc, char *argv[]) { int ret; void *result = NULL; - char *q; + char *q, *atts; unsigned int num_rows; + if (argc > 3) + return -E_MYSQL_SYNTAX; + if (argc > 1) { + char *tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + atts = make_message("where %s = '1'", tmp); + free(tmp); + } else + atts = para_strdup(NULL); + q = make_message("select name, to_days(now()) - to_days(lastplayed) from " - "data%s%s%s order by lastplayed", - (argc < 1)? "" : " where ", - (argc < 1)? "" : argv[1], - (argc < 1)? "" : " = '1'"); - result = get_result(q); + "data %s order by lastplayed", atts); + free(atts); + result = get_result(q); free(q); if (!result) return -E_NORESULT; @@ -894,7 +924,7 @@ static int com_last(int fd, int argc, char *argv[]) char *q; int num, ret; - if (argc < 1) + if (argc < 2) num = 10; else num = atoi(argv[1]); @@ -943,15 +973,19 @@ static int com_mbox(int fd, int argc, char *argv[]) "\n\n\n" "') from data" ); - if (argc >= 1) { - char *tmp = make_message("%s where name LIKE '%s'", query, - argv[1]); + if (argc >= 2) { + char *esc = escape_str(argv[1]), *tmp; + ret = -E_ESCAPE; + if (!esc) + goto out; + tmp = make_message("%s where name LIKE '%s'", query, esc); + free(esc); free(query); query = tmp; } mysql_free_result(result); ret = -E_NORESULT; - result = get_result(query); + result = get_result(query); if (!result) goto out; ret = -E_EMPTY_RESULT; @@ -998,7 +1032,7 @@ static char *get_atts(char *name, int verbose) num_fields = mysql_num_fields(result); if (num_fields < 5) goto out; - mysql_data_seek(result2, 4); /* skip Lastplayed, Numplayed... */ + mysql_data_seek(result2, 4); /* skip Lastplayed, Numplayed... */ row = mysql_fetch_row(result); ret = -E_NOROW; if (!row) @@ -1010,11 +1044,11 @@ static char *get_atts(char *name, int verbose) goto out; if (atts && (verbose || is_set)) atts = para_strcat(atts, verbose? "," : " "); - if (is_set || verbose) + if (is_set || verbose) atts = para_strcat(atts, row2[0]); if (verbose) atts = para_strcat(atts, is_set? "=\"1\"" : "=\"0\""); - } + } ret = 1; out: if (result2) @@ -1048,7 +1082,7 @@ static char *get_meta(char *name, int verbose) goto out; q = make_message(verbose? verbose_fmt : fmt, ebn); free(ebn); - result = get_result(q); + result = get_result(q); free(q); if (!result) goto out; @@ -1106,6 +1140,7 @@ err_out: mysql_free_result(result); return para_strdup("(none)"); } + /* * Read stream definition of stream streamname and construct mysql * query. Return NULL on errors. If streamname is NULL, use current @@ -1125,7 +1160,7 @@ static char *get_query(char *streamname, char *filename, int with_path) if (!streamname) tmp = get_current_stream(); else - tmp = para_strdup(streamname); + tmp = escape_str(streamname); if (!strcmp(tmp, "(none)")) { free(tmp); if (filename) { @@ -1207,10 +1242,10 @@ static char *get_query(char *streamname, char *filename, int with_path) goto write_query; } select_clause = para_strdup(with_path? - "select concat(dir.dir, '/', dir.name) from data, dir " - "where dir.name = data.name " - : - "select name from data where name is not NULL"); + "select concat(dir.dir, '/', dir.name) from data, dir " + "where dir.name = data.name " + : + "select name from data where name is not NULL"); order = make_message("order by -(%s)", score); free(score); if (accept_opts && deny_opts) { @@ -1261,7 +1296,7 @@ static char *get_selector_info(char *name) atts = get_atts(name, 0); dir = get_dir(name); /* get score */ - query = get_query(stream, name, 0); + query = get_query(stream, name, 0); /* FIXME: pass stream == NULL instead? */ if (!query) goto write; result = get_result(query); @@ -1307,7 +1342,7 @@ static int com_info(int fd, int argc, char *argv[]) char *name = NULL, *meta = NULL, *atts = NULL, *dir = NULL; int ret, com_la = strcmp(argv[0], "info"); - if (argc < 1) { + if (argc < 2) { ret = -E_GET_AUDIO_FILE; if (!(name = get_current_audio_file())) goto out; @@ -1328,25 +1363,17 @@ static int com_info(int fd, int argc, char *argv[]) ret = send_va_buffer(fd, "dir: %s\n" "%s\n" "attributes: %s\n", dir? dir : "(not contained in table)", meta, atts); out: - if (meta) - free(meta); - if (atts) - free(atts); - if (dir) - free(dir); - if (name) - free(name); + free(meta); + free(atts); + free(dir); + free(name); return ret; } -static int change_stream(char *stream) + +static int change_stream(const char *stream) { char *query; int ret; - /* try to insert if it does not exist (compatibility) */ -// query = make_message("insert into streams (name, def) values " -// "('current_stream', '%s')", stream); -// real_query(query); /* ignore return value */ -// free(query); query = make_message("update streams set def='%s' " "where name = 'current_stream'", stream); ret = real_query(query); @@ -1382,7 +1409,7 @@ static int remove_entry(const char *name) char *q, *ebn = escaped_basename(name); int ret = -E_ESCAPE; - if (!ebn || !*ebn) + if (!ebn) goto out; q = make_message("delete from data where name = '%s'", ebn); real_query(q); /* ignore errors */ @@ -1438,13 +1465,13 @@ out: /* * remove/add entries */ -static int com_rm_ne(__unused int fd, int argc, char *argv[]) +static int com_rm_ne(__a_unused int fd, int argc, char *argv[]) { int ne = !strcmp(argv[0], "ne"); int i, ret; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; - for (i = 1; i <= argc; i++) { + for (i = 1; i < argc; i++) { ret = remove_entry(argv[i]); if (ret < 0) return ret; @@ -1460,69 +1487,75 @@ static int com_rm_ne(__unused int fd, int argc, char *argv[]) /* * mv: rename entry */ -static int com_mv(__unused int fd, int argc, char *argv[]) +static int com_mv(__a_unused int fd, int argc, char *argv[]) { char *q, *dn, *ebn1 = NULL, *ebn2 = NULL, *edn = NULL; int ret; - if (argc != 2) + if (argc != 3) return -E_MYSQL_SYNTAX; + ret = -E_ESCAPE; ebn1 = escaped_basename(argv[1]); ebn2 = escaped_basename(argv[2]); - dn = para_dirname(argv[2]); - edn = escape_str(dn); - free(dn); - ret = -E_ESCAPE; - if (!ebn1 || !ebn2) + if (!ebn1 || !ebn2 | !*ebn1 || !*ebn2) + goto out; + ret = -E_MYSQL_SYNTAX; + if (!strcmp(ebn1, ebn2)) goto out; - remove_entry(ebn2); + remove_entry(argv[2]); /* no need to escape, ignore error */ q = make_message("update data set name = '%s' where name = '%s'", ebn2, ebn1); ret = real_query(q); free(q); if (ret < 0) goto out; + ret = -E_AUDIO_FILE; + if (!mysql_affected_rows(mysql_ptr)) + goto out; q = make_message("update dir set name = '%s' where name = '%s'", ebn2, ebn1); ret = real_query(q); free(q); if (ret < 0) goto out; - /* do not touch table dir, return success if argv[2] is no full path */ ret = 1; - if (!edn || !*edn) + dn = para_dirname(argv[2]); + if (!dn) + goto out; + ret = -E_ESCAPE; + edn = escape_str(dn); + free(dn); + if (!edn) + goto out; + ret = 1; + if (!*edn) goto out; q = make_message("update dir set dir = '%s' where name = '%s'", edn, ebn2); -// PARA_DEBUG_LOG("q: %s\n", q); ret = real_query(q); free(q); out: - if (ebn1) - free(ebn1); - if (ebn2) - free(ebn2); - if (edn) - free(edn); + free(edn); + free(ebn1); + free(ebn2); return ret; - } /* * picass: associate pic to audio file * snp: set numplayed */ -static int com_set(__unused int fd, int argc, char *argv[]) +static int com_set(__a_unused int fd, int argc, char *argv[]) { char *q, *ebn; long unsigned id; int i, ret; - char *field = strcmp(argv[0], "picass")? "numplayed" : "pic_id"; + const char *field = strcmp(argv[0], "picass")? "numplayed" : "pic_id"; - if (argc < 2) + if (argc < 3) return -E_MYSQL_SYNTAX; id = atol(argv[1]); - for (i = 2; i <= argc; i++) { + for (i = 2; i < argc; i++) { ebn = escaped_basename(argv[i]); if (!ebn) return -E_ESCAPE; @@ -1540,18 +1573,21 @@ static int com_set(__unused int fd, int argc, char *argv[]) /* * picch: change entry's name in pics table */ -static int com_picch(__unused int fd, int argc, char *argv[]) +static int com_picch(__a_unused int fd, int argc, char *argv[]) { int ret; long unsigned id; - char *q; + char *q, *tmp; - if (argc != 2) + if (argc != 3) return -E_MYSQL_SYNTAX; id = atol(argv[1]); - if (strlen(argv[2]) > MAXLINE) - return -E_NAMETOOLONG; - q = make_message("update pics set name = '%s' where id = %lu", argv[2], id); + ret = -E_ESCAPE; + tmp = escape_str(argv[2]); + if (!tmp) + return -E_ESCAPE; + q = make_message("update pics set name = '%s' where id = %lu", tmp, id); + free(tmp); ret = real_query(q); free(q); return ret; @@ -1560,14 +1596,14 @@ static int com_picch(__unused int fd, int argc, char *argv[]) /* * piclist: print list of pics in db */ -static int com_piclist(__unused int fd, int argc, __unused char *argv[]) +static int com_piclist(__a_unused int fd, int argc, __a_unused char *argv[]) { void *result = NULL; MYSQL_ROW row; unsigned long *length; int ret; - if (argc) + if (argc != 1) return -E_MYSQL_SYNTAX; result = get_result("select id,name,pic from pics order by id"); if (!result) @@ -1596,9 +1632,9 @@ static int com_picdel(int fd, int argc, char *argv[]) my_ulonglong aff; int i, ret; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; - for (i = 1; i <= argc; i++) { + for (i = 1; i < argc; i++) { id = atol(argv[i]); q = make_message("delete from pics where id = %lu", id); ret = real_query(q); @@ -1629,7 +1665,7 @@ static int com_pic(int fd, int argc, char *argv[]) int ret; char *q, *name = NULL; - if (argc < 1) { + if (argc < 2) { ret = -E_GET_AUDIO_FILE; name = get_current_audio_file(); } else { @@ -1662,22 +1698,20 @@ out: } /* strdel */ -static int com_strdel(__unused int fd, int argc, char *argv[]) +static int com_strdel(__a_unused int fd, int argc, char *argv[]) { - char *tmp; - int ret = -1; + char *q, *tmp; + int ret; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; - tmp = make_message("delete from streams where name='%s'", argv[1]); - ret = real_query(tmp); + tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + q = make_message("delete from streams where name='%s'", tmp); free(tmp); - if (ret < 0) - return ret; - tmp = get_current_stream(); - ret = 1; - if (strcmp(tmp, "(none)") && !strcmp(tmp, argv[1])) - ret = change_stream("(none)"); + ret = real_query(q); + free(q); return ret; } @@ -1691,12 +1725,18 @@ static int com_ls(int fd, int argc, char *argv[]) int ret; unsigned int num_rows; - if (argc > 0) - q = make_message("select name from data where name LIKE '%s'", - argv[1]); - else + if (argc > 2) + return -E_MYSQL_SYNTAX; + if (argc > 1) { + char *tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + q = make_message("select name from data where name like '%s'", + tmp); + free(tmp); + } else q = para_strdup("select name from data"); - result = get_result(q); + result = get_result(q); free(q); if (!result) return -E_NORESULT; @@ -1707,10 +1747,11 @@ static int com_ls(int fd, int argc, char *argv[]) mysql_free_result(result); return ret; } + /* * summary */ -static int com_summary(__unused int fd, int argc, __unused char *argv[]) +static int com_summary(__a_unused int fd, int argc, __a_unused char *argv[]) { MYSQL_ROW row; MYSQL_ROW row2; @@ -1719,7 +1760,7 @@ static int com_summary(__unused int fd, int argc, __unused char *argv[]) const char *fmt = "select count(name) from data where %s='1'"; int ret = -E_NORESULT; - if (argc) + if (argc != 1) return -E_MYSQL_SYNTAX; result = get_all_attributes(); if (!result) @@ -1761,7 +1802,7 @@ static int get_numplayed(char *name) char *buf = make_message(fmt, name); int ret = -E_NORESULT; - result = get_result(buf); + result = get_result(buf); free(buf); if (!result) goto out; @@ -1799,10 +1840,10 @@ static int update_audio_file(char *name) ret = real_query(q); free(q); out: - if (ebn) - free(ebn); + free(ebn); return ret; } + /* If called as child, mmd_lock must be held */ static void update_mmd(char *info) { @@ -1820,11 +1861,19 @@ static void update_audio_file_server_handler(char *name) update_audio_file(name); } -static int com_us(__unused int fd, int argc, char *argv[]) +static int com_us(__a_unused int fd, int argc, char *argv[]) { - if (argc != 1) + char *tmp; + int ret; + + if (argc != 2) return -E_MYSQL_SYNTAX; - return update_audio_file(argv[1]); + tmp = escape_str(argv[1]); + if (!tmp) + return -E_ESCAPE; + ret = update_audio_file(argv[1]); + free(tmp); + return ret; } static void refresh_selector_info(void) @@ -1843,7 +1892,7 @@ static void refresh_selector_info(void) } /* select previous/next stream */ -static int com_ps(__unused int fd, int argc, char *argv[]) +static int com_ps(__a_unused int fd, int argc, char *argv[]) { char *query, *stream = get_current_stream(); void *result = get_result("select name from streams"); @@ -1851,7 +1900,7 @@ static int com_ps(__unused int fd, int argc, char *argv[]) int match = -1, ret, i; unsigned int num_rows; - if (argc) + if (argc != 1) return -E_MYSQL_SYNTAX; ret = -E_NORESULT; if (!result) @@ -1880,7 +1929,7 @@ static int com_ps(__unused int fd, int argc, char *argv[]) else i = match < num_rows - 1? match + 1 : 0; ret = -E_NOROW; - mysql_data_seek(result, i); + mysql_data_seek(result, i); row = mysql_fetch_row(result); if (!row || !row[0]) goto out; @@ -1910,16 +1959,16 @@ out: } /* streams */ -static int com_streams(int fd, int argc, __unused char *argv[]) +static int com_streams(int fd, int argc, __a_unused char *argv[]) { unsigned int num_rows; int i, ret = -E_NORESULT; void *result; MYSQL_ROW row; - if (argc && strcmp(argv[1], "current_stream")) + if (argc > 1 && strcmp(argv[1], "current_stream")) return -E_MYSQL_SYNTAX; - if (argc) { + if (argc > 1) { char *cs = get_current_stream(); ret = send_va_buffer(fd, "%s\n", cs); free(cs); @@ -1955,7 +2004,7 @@ static int com_strq(int fd, int argc, char *argv[]) void *result; int ret; - if (argc < 1) { + if (argc < 2) { ret = -E_GET_STREAM; name = get_current_stream(); } else { @@ -1987,26 +2036,32 @@ out: static int com_cs(int fd, int argc, char *argv[]) { int ret, stream_change; - char *query; + char *query, *stream = NULL; char *old_stream = get_current_stream(); int csp = !strcmp(argv[0], "csp"); - if (!argc) { - ret = -E_MYSQL_SYNTAX; + ret = -E_MYSQL_SYNTAX; + if (argc > 2) + goto out; + if (argc == 1) { if (csp) goto out; ret = send_va_buffer(fd, "%s\n", old_stream); goto out; } ret = -E_GET_QUERY; - query = get_query(argv[1], NULL, 0); /* test if stream is valid */ + /* test if stream is valid, no need to escape argv[1] */ + query = get_query(argv[1], NULL, 0); if (!query) goto out; free(query); /* stream is ok */ - stream_change = strcmp(argv[1], old_stream); + stream = escape_str(argv[1]); + if (!stream) + goto out; + stream_change = strcmp(stream, old_stream); if (stream_change) { - ret = change_stream(argv[1]); + ret = change_stream(stream); if (ret < 0) goto out; refresh_selector_info(); @@ -2021,6 +2076,7 @@ static int com_cs(int fd, int argc, char *argv[]) ret = 1; out: free(old_stream); + free(stream); return ret; } @@ -2035,12 +2091,12 @@ static int com_sl(int fd, int argc, char *argv[]) char *query, *stream, *tmp; unsigned int num_rows, num; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; num = atoi(argv[1]); if (!num) return -E_MYSQL_SYNTAX; - stream = (argc == 1)? get_current_stream() : para_strdup(argv[2]); + stream = (argc == 2)? get_current_stream() : escape_str(argv[2]); tmp = get_query(stream, NULL, 0); query = make_message("%s limit %d", tmp, num); free(tmp); @@ -2109,11 +2165,11 @@ static int com_sa(int fd, int argc, char *argv[]) int i, ret; char *atts = NULL, *name; - if (argc < 1) + if (argc < 2) return -E_MYSQL_SYNTAX; - for (i = 1; i <= argc; i++) { + for (i = 1; i < argc; i++) { int unset = 0; - char *tmp, *p =argv[i]; + char *esc, *tmp, *p =argv[i]; int len = strlen(p); if (!len) @@ -2129,15 +2185,19 @@ static int com_sa(int fd, int argc, char *argv[]) goto no_more_atts; } p[len - 1] = '\0'; - tmp = make_message("%s%s='%s'", atts? "," : "", p, + esc = escape_str(p); + if (!esc) + return -E_ESCAPE; + tmp = make_message("%s%s='%s'", atts? "," : "", esc, unset? "0" : "1"); + free(esc); atts = para_strcat(atts, tmp); free(tmp); } no_more_atts: if (!atts) return -E_NOATTS; - if (i > argc) { /* no name given, use current af */ + if (i >= argc) { /* no name given, use current af */ ret = -E_GET_AUDIO_FILE; if (!(name = get_current_audio_file())) goto out; @@ -2150,6 +2210,7 @@ no_more_atts: } refresh_selector_info(); out: + free(atts); return ret; } @@ -2161,7 +2222,7 @@ static int com_cam(int fd, int argc, char *argv[]) char *name = NULL, *meta = NULL, *atts = NULL; int i, ret; - if (argc < 2) + if (argc < 3) return -E_MYSQL_SYNTAX; if (!(name = escaped_basename(argv[1]))) return -E_ESCAPE; @@ -2171,7 +2232,7 @@ static int com_cam(int fd, int argc, char *argv[]) ret = -E_META; if (!(meta = get_meta(name, 0))) goto out; - for (i = 2; i <= argc; i++) { + for (i = 2; i < argc; i++) { char *ebn, *q; ret = -E_ESCAPE; if (!(ebn = escaped_basename(argv[i]))) @@ -2204,7 +2265,7 @@ out: /* * verify / clean */ -static int com_vrfy(int fd, int argc, __unused char *argv[]) +static int com_vrfy(int fd, int argc, __a_unused char *argv[]) { char *query; int ret, vrfy_mode = strcmp(argv[0], "clean"); @@ -2213,7 +2274,7 @@ static int com_vrfy(int fd, int argc, __unused char *argv[]) MYSQL_ROW row; char *escaped_name; - if (argc) + if (argc != 1) return -E_MYSQL_SYNTAX; ret = -E_NORESULT; result = get_result("select data.name from data left join dir on " @@ -2260,7 +2321,6 @@ static int mysql_write_tmp_file(const char *dir, const char *name) { int ret = -E_TMPFILE; char *msg = make_message("%s\t%s\n", dir, name); - if (fputs(msg, out_file) != EOF) ret = 1; free(msg); @@ -2270,7 +2330,7 @@ static int mysql_write_tmp_file(const char *dir, const char *name) /* * update database */ -static int com_upd(int fd, int argc, __unused char *argv[]) +static int com_upd(int fd, int argc, __a_unused char *argv[]) { char *tempname = NULL, *query = NULL; int ret, out_fd = -1, num = 0; @@ -2278,7 +2338,7 @@ static int com_upd(int fd, int argc, __unused char *argv[]) unsigned int num_rows; MYSQL_ROW row; - if (argc) + if (argc != 1) return -E_MYSQL_SYNTAX; out_file = NULL; tempname = para_strdup("/tmp/mysql.tmp.XXXXXX"); @@ -2305,7 +2365,7 @@ static int com_upd(int fd, int argc, __unused char *argv[]) goto out; if ((ret = real_query("delete from dir")) < 0) goto out; - query = make_message("load data infile '%s' into table dir " + query = make_message("load data infile '%s' ignore into table dir " "fields terminated by '\t' lines terminated by '\n' " "(dir, name)", tempname); ret = real_query(query); @@ -2323,12 +2383,15 @@ static int com_upd(int fd, int argc, __unused char *argv[]) goto out; } while ((row = mysql_fetch_row(result))) { + char *erow; ret = -E_NOROW; if (!row[0]) goto out; send_va_buffer(fd, "new entry: %s\n", row[0]); + erow = escape_str(row[0]); query = make_message("insert into data (name, pic_id) values " - "('%s','%s')", row[0], "1"); + "('%s','%s')", erow, "1"); + free(erow); ret = real_query(query); free(query); if (ret < 0) @@ -2359,9 +2422,8 @@ static char **server_get_audio_file_list(unsigned int num) free(stream); query = make_message("%s limit %d", tmp, num); free(tmp); - if (!query) - goto err_out; result = get_result(query); + free(query); if (!result) goto err_out; num_rows = mysql_num_rows(result); @@ -2383,8 +2445,6 @@ err_out: free(list); list = NULL; success: - if (query) - free(query); if (result) mysql_free_result(result); return list; @@ -2436,17 +2496,9 @@ static void write_msg2mmd(int success) /* create database */ static int com_cdb(int fd, int argc, char *argv[]) { - char *query, *name; + char *query; int ret; - if (argc < 1) - name = "paraslash"; - else { - ret = -E_NAMETOOLONG; - name = argv[1]; - if (strlen(name) > MAXLINE) - goto out; - } if (mysql_ptr) { PARA_INFO_LOG("%s", "closing database\n"); mysql_close(mysql_ptr); @@ -2456,14 +2508,17 @@ static int com_cdb(int fd, int argc, char *argv[]) ret = -E_MYSQL_INIT; if (init_mysql_server() < 0 || !mysql_ptr) goto out; - query = make_message("create database %s", name); + if (argc < 2) + conf.mysql_database_arg = para_strdup("paraslash"); + else + conf.mysql_database_arg = escape_str(argv[1]); + query = make_message("create database %s", conf.mysql_database_arg); ret = real_query(query); free(query); if (ret < 0) goto out; /* reconnect with database just created */ mysql_close(mysql_ptr); - conf.mysql_database_arg = para_strdup(name); ret = -E_MYSQL_INIT; if (init_mysql_server() < 0 || !mysql_ptr) goto out; @@ -2494,7 +2549,8 @@ static int com_cdb(int fd, int argc, char *argv[]) if (real_query("insert into streams (name, def) values " "('current_stream', '(none)')") < 0) goto out; - ret = send_va_buffer(fd, "successfully created database %s\n", name); + ret = send_va_buffer(fd, "successfully created database %s\n", + conf.mysql_database_arg); out: return ret; }