Rename struct audio format to audio_format_handler
[paraslash.git] / dbadm.c
1 /*
2 * Copyright (C) 2004-2006 Andre Noll <maan@systemlinux.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
17 */
18
19 /** \file dbadm.c simple attribute setting utility for the mysql selector */
20
21 #include "para.h"
22 #include <menu.h>
23 #include "string.h"
24
25 //#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
26 #define MAXLINE 255
27
28 #define OFFSET 4
29 static int att_win_lines, att_win_cols;
30 static int att_format_lines, att_format_cols;
31 static int atts_modified, refresh_file = 1;
32 static int n_choices, choice_len;
33 static char *atts;
34 ITEM **my_items;
35 WINDOW *att_win;
36
37 static char **choices;
38
39 /* no looging */
40 void para_log(__a_unused int ll, __a_unused const char *fmt,...)
41 {
42 }
43
44 static int client_cmd(const char *cmd)
45 {
46 pid_t pid;
47 int ret, fds[3] = {0, 1, 0};
48 char *cmdline = make_message(BINDIR "/para_client %s", cmd);
49 ret = para_exec_cmdline_pid(&pid, cmdline, fds);
50 free(cmdline);
51 if (ret < 0)
52 return -1;
53 return fds[1];
54 }
55
56 static char **get_all_atts(int *num_atts)
57 {
58 int fd = client_cmd("laa");
59 FILE *pipe;
60 char **ret = NULL, *buf;
61
62 if (fd < 0)
63 return NULL;
64 pipe = fdopen(fd, "r");
65 if (!pipe) {
66 close(fd);
67 return NULL;
68 }
69 *num_atts = 0;
70 buf = para_malloc(MAXLINE * sizeof(char));
71 while (fgets(buf, MAXLINE - 1, pipe) && *buf) {
72 size_t n = strlen(buf);
73 buf[n - 1] = '\0';
74 if (choice_len < n - 1)
75 choice_len = n - 1;
76 ret = para_realloc(ret, (*num_atts + 1) * sizeof(char*));
77 ret[*num_atts] = para_strdup(buf);
78 *num_atts += 1;
79 }
80 free(buf);
81 return ret;
82 }
83
84 static char *get_atts(char *filename)
85 {
86 int n, fd, bufsize = (n_choices * (choice_len + 1) + 10) * sizeof(char);
87 char *cmd = make_message("la %s", filename), *buf;
88
89 fd = client_cmd(cmd);
90 free(cmd);
91 if (fd < 0)
92 return NULL;
93 buf = para_malloc(bufsize * sizeof(char));
94 n = read(fd, buf, bufsize - 1);
95 if (n <= 0 ||strstr(buf, "Not contained in database")) {
96 free(buf);
97 return NULL;
98 };
99 return buf;
100 }
101
102 static void _item_init(__a_unused MENU* menu)
103 {
104 // static int subsequent_run;
105 int i, n;
106 char *p = atts;
107 char att[MAXLINE];
108
109 if (!refresh_file)
110 return;
111 refresh_file = 0;
112 for (i = 0; i < n_choices; i++)
113 set_item_value(my_items[i], FALSE);
114 while (sscanf(p, "%s%n", att, &n) > 0) {
115 //mvprintw(LINES - 4, 0, "aaaitem.");
116 p += n + 1;
117 for (i = 0; i < n_choices; i++) {
118 if (!strcmp(item_name(my_items[i]), att)) {
119 set_item_value(my_items[i], TRUE);
120 break;
121 }
122 }
123 }
124 }
125
126 struct color_pair {
127 int bg;
128 int fg;
129 };
130
131 enum {
132 COLOR_DUMMY,
133 COLOR_FRAME,
134 COLOR_FILENAME,
135 COLOR_ACTIVE_ITEM,
136 COLOR_INACTIVE_ITEM
137 };
138
139 static void init_colors(void)
140 {
141 start_color();
142 init_pair(COLOR_FRAME, COLOR_BLUE, COLOR_BLACK);
143 init_pair(COLOR_FILENAME, COLOR_MAGENTA, COLOR_BLACK);
144 init_pair(COLOR_ACTIVE_ITEM, COLOR_RED, COLOR_WHITE);
145 init_pair(COLOR_INACTIVE_ITEM, COLOR_WHITE, COLOR_BLACK);
146 }
147
148 static int commit_changes(char *filename)
149 {
150 // ITEM **items;
151 int i;
152 char buf[MAXLINE] = "para_client sa ";
153
154 for (i = 0; i < n_choices; ++i) {
155 strcat(buf, item_name(my_items[i]));
156 if (item_value(my_items[i])) {
157 // printf("%s\n", item_name(my_items[i]));
158 strcat(buf, "+ ");
159 } else
160 strcat(buf, "- ");
161 }
162 strcat(buf, filename);
163 //printf("old atts: %s\n", atts);
164 //printf("%s\n", buf);
165 return system(buf);
166 }
167
168 static char *get_current_filename(void)
169 {
170 char *bn = NULL, *buf = para_malloc(MAXLINE * sizeof(char));
171 int ret, fd;
172
173 fd = client_cmd("sc 1");
174 if (fd < 0)
175 return NULL;
176 ret = read(fd, buf, MAXLINE - 1);
177 if (ret <= 0)
178 goto out;
179 buf[ret] = '\0';
180 bn = para_basename(buf);
181 free(buf);
182 out:
183 close(fd);
184 return bn;
185 }
186
187 static void print_filename(char *filename)
188 {
189 char *tmp = strdup(filename);
190 int maxlen = att_win_cols - 2;
191
192 wattron(att_win, COLOR_PAIR(COLOR_FILENAME));
193 if (strlen(filename) > maxlen)
194 tmp[maxlen] = '\0';
195 wmove(att_win, 1, 1);
196 clrtoeol();
197 mvwprintw(att_win, 1, 1, "%s", tmp);
198 wattron(att_win, COLOR_PAIR(COLOR_FRAME));
199 mvwaddch(att_win, 2, att_win_cols - 1, ACS_RTEE);
200 free(tmp);
201 }
202
203 static int com_refresh_file(char *filename) {
204
205
206 filename = get_current_filename();
207 if (!filename)
208 return -1;
209 atts = get_atts(filename);
210 if (!atts)
211 return -1;
212 print_filename(filename);
213 return 1;
214 }
215
216 static int init_curses(void)
217 {
218 /* Initialize curses */
219 initscr();
220
221 if (LINES <= OFFSET + 4)
222 return -1;
223
224 att_format_cols = (COLS - 2 * OFFSET - 3) / (choice_len + 1);
225 if (att_format_cols < 1)
226 return -1;
227 att_format_lines = (n_choices - 1) / att_format_cols + 1;
228 if (att_format_lines + OFFSET + 4 > LINES)
229 att_format_lines = LINES - OFFSET - 4;
230
231 att_win_lines = att_format_lines + 4;
232 att_win_cols = (choice_len + 1) * att_format_cols + 1;
233 if (att_win_lines + OFFSET > LINES)
234 att_win_lines = LINES - OFFSET - 1;
235 if (att_win_cols + 2 * OFFSET > COLS)
236 att_win_cols = COLS - 2 * OFFSET + 1;
237 //printf ("%i:%i, %i:%i\n", att_format_lines, att_format_cols, att_win_lines, att_win_cols); fflush(stdout); sleep(2);
238
239 cbreak();
240 noecho();
241 keypad(stdscr, TRUE);
242 init_colors();
243 return 1;
244 }
245
246 int main(int argc, char *argv[])
247 {
248 int c, i, ret = EXIT_FAILURE;
249 MENU *my_menu = NULL;
250 char *filename;
251
252 choices = get_all_atts(&n_choices);
253 if (!choices || n_choices <= 0)
254 exit(EXIT_FAILURE);
255 if (argc < 2) {
256 filename = get_current_filename();
257 if (!filename)
258 exit(EXIT_FAILURE);
259 } else
260 filename = strdup(argv[1]);
261 atts = get_atts(filename);
262 if (!atts)
263 goto out;
264 if (init_curses() < 0)
265 goto out;
266
267 /* Initialize items */
268 my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
269 for (i = 0; i < n_choices; ++i)
270 my_items[i] = new_item(choices[i], "");
271
272 my_menu = new_menu(my_items);
273 set_item_init(my_menu, _item_init);
274 /* Make the menu multi valued */
275 menu_opts_off(my_menu, O_ONEVALUE);
276 /* Set menu option not to show the description */
277 menu_opts_off(my_menu, O_SHOWDESC);
278
279 /* Create the window to be associated with the menu */
280 att_win = newwin(att_win_lines, att_win_cols, OFFSET, OFFSET);
281 keypad(att_win, TRUE);
282 /* Set main window and sub window */
283 set_menu_win(my_menu, att_win);
284 set_menu_sub(my_menu, derwin(att_win, att_win_lines - 4,
285 att_win_cols - 2, 3, 1));
286 set_menu_format(my_menu, att_format_lines, att_format_cols);
287 //set_menu_format(my_menu, 5, 1);
288 set_menu_mark(my_menu, "");
289
290 /* Print a border around the main window and print a title */
291 wattron(att_win, COLOR_PAIR(COLOR_FRAME));
292 box(att_win, 0, 0);
293 mvwhline(att_win, 2, 1, ACS_HLINE , att_win_cols - 2);
294 mvwaddch(att_win, 2, 0, ACS_LTEE);
295 print_filename(filename);
296 set_menu_fore(my_menu, COLOR_PAIR(COLOR_ACTIVE_ITEM) | A_REVERSE);
297 set_menu_back(my_menu, COLOR_PAIR(COLOR_INACTIVE_ITEM));
298 refresh();
299 post_menu(my_menu);
300
301 repeat:
302 wrefresh(att_win);
303 c = getch();
304 switch(c) {
305 case KEY_DOWN:
306 menu_driver(my_menu, REQ_DOWN_ITEM);
307 goto repeat;
308 case KEY_UP:
309 menu_driver(my_menu, REQ_UP_ITEM);
310 goto repeat;
311 case KEY_LEFT:
312 menu_driver(my_menu, REQ_LEFT_ITEM);
313 goto repeat;
314 case KEY_RIGHT:
315 menu_driver(my_menu, REQ_RIGHT_ITEM);
316 goto repeat;
317
318 case 'q':
319 ret = EXIT_SUCCESS;
320 goto out;
321 case 'r':
322 com_refresh_file(filename);
323 refresh_file = 1;
324 _item_init(NULL);
325 goto repeat;
326
327 case ' ':
328 menu_driver(my_menu, REQ_TOGGLE_ITEM);
329 atts_modified = 1;
330 goto repeat;
331 /* Enter */
332 case 10:
333 endwin();
334 if (atts_modified)
335 commit_changes(filename);
336 else
337 printf("Attributes unchanged\n");
338 goto out;
339 default:
340 goto repeat;
341 }
342 out:
343 if (my_items) {
344 free_item(my_items[0]);
345 free_item(my_items[1]);
346 }
347 for (i = 0; i < n_choices; i++)
348 free(choices[i]);
349 free(choices);
350 if (my_menu)
351 free_menu(my_menu);
352 if (atts)
353 free(atts);
354 if (filename)
355 free(filename);
356 endwin();
357 exit(ret);
358 }
359