compress.c: fix serious typo
[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 *f;
60         char **ret = NULL, *buf;
61
62         if (fd < 0)
63                 return NULL;
64         f = fdopen(fd, "r");
65         if (!f) {
66                 close(fd);
67                 return NULL;
68         }
69         *num_atts = 0;
70         buf = para_malloc(MAXLINE * sizeof(char));
71         while (fgets(buf, MAXLINE - 1, f) && *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         int fds[3] = {0, 0, 0};
154         pid_t pid;
155
156         for (i = 0; i < n_choices; ++i) {
157                 strcat(buf, item_name(my_items[i]));
158                 if (item_value(my_items[i])) {
159         //              printf("%s\n", item_name(my_items[i]));
160                         strcat(buf, "+ ");
161                 } else
162                         strcat(buf, "- ");
163         }
164         strcat(buf, filename);
165         //printf("old atts: %s\n", atts);
166         //printf("%s\n", buf);
167         return para_exec_cmdline_pid(&pid, buf, fds);
168 }
169
170 static char *get_current_filename(void)
171 {
172         char *bn = NULL, *buf = para_malloc(MAXLINE * sizeof(char));
173         int ret, fd;
174
175         fd = client_cmd("sc 1");
176         if (fd < 0)
177                 return NULL;
178         ret = read(fd, buf, MAXLINE - 1);
179         if (ret <= 0)
180                 goto out;
181         buf[ret] = '\0';
182         bn = para_basename(buf);
183         free(buf);
184 out:
185         close(fd);
186         return bn;
187 }
188
189 static void print_filename(char *filename)
190 {
191         char *tmp = strdup(filename);
192         int maxlen = att_win_cols - 2;
193
194         wattron(att_win, COLOR_PAIR(COLOR_FILENAME));
195         if (strlen(filename) > maxlen)
196                 tmp[maxlen] = '\0';
197         wmove(att_win, 1, 1);
198         clrtoeol();
199         mvwprintw(att_win, 1, 1, "%s", tmp);
200         wattron(att_win, COLOR_PAIR(COLOR_FRAME));
201         mvwaddch(att_win, 2, att_win_cols - 1, ACS_RTEE);
202         free(tmp);
203 }
204
205 static int com_refresh_file(char *filename) {
206
207
208         filename = get_current_filename();
209         if (!filename)
210                 return -1;
211         atts = get_atts(filename);
212         if (!atts)
213                 return -1;
214         print_filename(filename);
215         return 1;
216 }
217
218 static int init_curses(void)
219 {
220         /* Initialize curses */
221         initscr();
222
223         if (LINES <= OFFSET + 4)
224                 return -1;
225
226         att_format_cols = (COLS - 2 * OFFSET - 3) / (choice_len + 1);
227                 if (att_format_cols < 1)
228                         return -1;
229         att_format_lines = (n_choices - 1) / att_format_cols + 1;
230         if (att_format_lines + OFFSET + 4 > LINES)
231                 att_format_lines = LINES - OFFSET - 4;
232
233         att_win_lines = att_format_lines + 4;
234         att_win_cols = (choice_len + 1) * att_format_cols + 1;
235         if (att_win_lines + OFFSET > LINES)
236                 att_win_lines = LINES - OFFSET - 1;
237         if (att_win_cols + 2 * OFFSET > COLS)
238                 att_win_cols = COLS - 2 * OFFSET + 1;
239         //printf ("%i:%i, %i:%i\n", att_format_lines, att_format_cols, att_win_lines, att_win_cols); fflush(stdout); sleep(2);
240
241         cbreak();
242         noecho();
243         keypad(stdscr, TRUE);
244         init_colors();
245         return 1;
246 }
247
248 int main(int argc, char *argv[])
249 {
250         int c, i, ret = EXIT_FAILURE;
251         MENU *my_menu = NULL;
252         char *filename;
253
254         choices = get_all_atts(&n_choices);
255         if (!choices ||  n_choices <= 0)
256                 exit(EXIT_FAILURE);
257         if (argc < 2) {
258                 filename = get_current_filename();
259                 if (!filename)
260                         exit(EXIT_FAILURE);
261         } else
262                 filename = strdup(argv[1]);
263         atts = get_atts(filename);
264         if (!atts)
265                 goto out;
266         if (init_curses() < 0)
267                 goto out;
268
269         /* Initialize items */
270         my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
271         for (i = 0; i < n_choices; ++i)
272                 my_items[i] = new_item(choices[i], "");
273
274         my_menu = new_menu(my_items);
275         set_item_init(my_menu, _item_init);
276         /* Make the menu multi valued */
277         menu_opts_off(my_menu, O_ONEVALUE);
278         /* Set menu option not to show the description */
279         menu_opts_off(my_menu, O_SHOWDESC);
280
281         /* Create the window to be associated with the menu */
282         att_win = newwin(att_win_lines, att_win_cols, OFFSET, OFFSET);
283         keypad(att_win, TRUE);
284         /* Set main window and sub window */
285         set_menu_win(my_menu, att_win);
286         set_menu_sub(my_menu, derwin(att_win, att_win_lines - 4,
287                 att_win_cols - 2, 3, 1));
288         set_menu_format(my_menu, att_format_lines, att_format_cols);
289         //set_menu_format(my_menu, 5, 1);
290         set_menu_mark(my_menu, "");
291
292         /* Print a border around the main window and print a title */
293         wattron(att_win, COLOR_PAIR(COLOR_FRAME));
294         box(att_win, 0, 0);
295         mvwhline(att_win, 2, 1, ACS_HLINE , att_win_cols - 2);
296         mvwaddch(att_win, 2, 0, ACS_LTEE);
297         print_filename(filename);
298         set_menu_fore(my_menu, COLOR_PAIR(COLOR_ACTIVE_ITEM) | A_REVERSE);
299         set_menu_back(my_menu, COLOR_PAIR(COLOR_INACTIVE_ITEM));
300         refresh();
301         post_menu(my_menu);
302
303 repeat:
304         wrefresh(att_win);
305         c = getch();
306         switch(c) {
307                 case KEY_DOWN:
308                         menu_driver(my_menu, REQ_DOWN_ITEM);
309                         goto repeat;
310                 case KEY_UP:
311                         menu_driver(my_menu, REQ_UP_ITEM);
312                         goto repeat;
313                 case KEY_LEFT:
314                         menu_driver(my_menu, REQ_LEFT_ITEM);
315                         goto repeat;
316                 case KEY_RIGHT:
317                         menu_driver(my_menu, REQ_RIGHT_ITEM);
318                         goto repeat;
319
320                 case 'q':
321                         ret = EXIT_SUCCESS;
322                         goto out;
323                 case 'r':
324                         com_refresh_file(filename);
325                         refresh_file = 1;
326                         _item_init(NULL);
327                         goto repeat;
328
329                 case ' ':
330                         menu_driver(my_menu, REQ_TOGGLE_ITEM);
331                         atts_modified = 1;
332                         goto repeat;
333                 /* Enter */
334                 case 10:
335                         if (atts_modified)
336                                 commit_changes(filename);
337                         goto out;
338                 default:
339                         goto repeat;
340         }
341 out:
342         if (my_items) {
343                 free_item(my_items[0]);
344                 free_item(my_items[1]);
345         }
346         for (i = 0; i < n_choices; i++)
347                 free(choices[i]);
348         free(choices);
349         if (my_menu)
350                 free_menu(my_menu);
351         if (atts)
352                 free(atts);
353         if (filename)
354                 free(filename);
355         endwin();
356         exit(ret);
357 }
358