1 #include <nm_core.h>
2 #include <nm_form.h>
3 #include <nm_utils.h>
4 #include <nm_string.h>
5 #include <nm_window.h>
6 #include <nm_menu.h>
7 #include <nm_database.h>
8 #include <nm_cfg_file.h>
9 #include <nm_vm_control.h>
10 #include <nm_9p_share.h>
11
12 typedef struct {
13 nm_str_t mode;
14 nm_str_t path;
15 nm_str_t name;
16 } nm_9p_data_t;
17
18 #define NM_INIT_9P_DATA (nm_9p_data_t) { NM_INIT_STR, NM_INIT_STR, NM_INIT_STR }
19
20 static const char NM_9P_SET_MODE_SQL[] =
21 "UPDATE vms SET fs9p_enable='%s' WHERE name='%s'";
22 static const char NM_9P_SET_PATH_SQL[] =
23 "UPDATE vms SET fs9p_path='%s' WHERE name='%s'";
24 static const char NM_9P_SET_NAME_SQL[] =
25 "UPDATE vms SET fs9p_name='%s' WHERE name='%s'";
26
27 static const char NM_LC_9P_FORM_MODE[] = "Enable sharing";
28 static const char NM_LC_9P_FORM_PATH[] = "Path to directory";
29 static const char NM_LC_9P_FORM_NAME[] = "Name of the share";
30
31 static void nm_9p_init_windows(nm_form_t *form);
32 static void nm_9p_fields_setup(const nm_vmctl_data_t *cur);
33 static size_t nm_9p_labels_setup();
34 static int nm_9p_get_data(nm_9p_data_t *data, const nm_vmctl_data_t *cur);
35 static void nm_9p_update_db(const nm_str_t *name, const nm_9p_data_t *data);
36
37 enum {
38 NM_LBL_9PMODE = 0, NM_FLD_9PMODE,
39 NM_LBL_9PPATH, NM_FLD_9PPATH,
40 NM_LBL_9PNAME, NM_FLD_9PNAME,
41 NM_FLD_COUNT
42 };
43
44 static nm_field_t *fields[NM_FLD_COUNT + 1];
45
nm_9p_init_windows(nm_form_t * form)46 static void nm_9p_init_windows(nm_form_t *form)
47 {
48 if (form) {
49 nm_form_window_init();
50 nm_form_data_t *form_data = (nm_form_data_t *)form_userptr(form);
51 if (form_data)
52 form_data->parent_window = action_window;
53 } else {
54 werase(action_window);
55 werase(help_window);
56 }
57
58 nm_init_side();
59 nm_init_action(_(NM_MSG_9P_SHARE));
60 nm_init_help_edit();
61
62 nm_print_vm_menu(NULL);
63 }
64
nm_9p_share(const nm_str_t * name)65 void nm_9p_share(const nm_str_t *name)
66 {
67 nm_form_data_t *form_data = NULL;
68 nm_form_t *form = NULL;
69 nm_vmctl_data_t vm = NM_VMCTL_INIT_DATA;
70 nm_9p_data_t data = NM_INIT_9P_DATA;
71 size_t msg_len;
72
73 nm_9p_init_windows(NULL);
74
75 nm_vmctl_get_data(name, &vm);
76
77 msg_len = nm_9p_labels_setup();
78
79 form_data = nm_form_data_new(
80 action_window, nm_9p_init_windows, msg_len, NM_FLD_COUNT / 2, NM_TRUE);
81
82 if (nm_form_data_update(form_data, 0, 0) != NM_OK)
83 goto out;
84
85 for (size_t n = 0; n < NM_FLD_COUNT; n++) {
86 switch (n) {
87 case NM_FLD_9PMODE:
88 fields[n] = nm_field_enum_new(
89 n / 2, form_data, nm_form_yes_no, false, false);
90 break;
91 case NM_FLD_9PPATH:
92 fields[n] = nm_field_regexp_new(n / 2, form_data, "^/.*");
93 break;
94 case NM_FLD_9PNAME:
95 fields[n] = nm_field_regexp_new(n / 2, form_data, ".*");
96 break;
97 default:
98 fields[n] = nm_field_label_new(n / 2, form_data);
99 break;
100 }
101 }
102 fields[NM_FLD_COUNT] = NULL;
103
104 nm_9p_labels_setup();
105 nm_9p_fields_setup(&vm);
106 nm_fields_unset_status(fields);
107
108 form = nm_form_new(form_data, fields);
109 nm_form_post(form);
110
111 if (nm_form_draw(&form) != NM_OK)
112 goto out;
113
114 if (nm_9p_get_data(&data, &vm) != NM_OK)
115 goto out;
116
117 nm_9p_update_db(name, &data);
118
119 out:
120 NM_FORM_EXIT();
121 nm_str_free(&data.mode);
122 nm_str_free(&data.name);
123 nm_str_free(&data.path);
124 nm_form_free(form);
125 nm_form_data_free(form_data);
126 nm_fields_free(fields);
127 nm_vmctl_free_data(&vm);
128 }
129
nm_9p_fields_setup(const nm_vmctl_data_t * cur)130 static void nm_9p_fields_setup(const nm_vmctl_data_t *cur)
131 {
132 field_opts_off(fields[NM_FLD_9PPATH], O_STATIC);
133 field_opts_off(fields[NM_FLD_9PNAME], O_STATIC);
134
135 set_field_buffer(fields[NM_FLD_9PMODE], 0,
136 (nm_str_cmp_st(nm_vect_str(&cur->main, NM_SQL_9FLG),
137 NM_ENABLE) == NM_OK) ? "yes" : "no");
138 set_field_buffer(fields[NM_FLD_9PPATH], 0, nm_vect_str_ctx(&cur->main, NM_SQL_9PTH));
139 set_field_buffer(fields[NM_FLD_9PNAME], 0, nm_vect_str_ctx(&cur->main, NM_SQL_9ID));
140 }
141
nm_9p_labels_setup()142 static size_t nm_9p_labels_setup()
143 {
144 nm_str_t buf = NM_INIT_STR;
145 size_t max_label_len = 0;
146 size_t msg_len = 0;
147
148 for (size_t n = 0; n < NM_FLD_COUNT; n++) {
149 switch (n) {
150 case NM_LBL_9PMODE:
151 nm_str_format(&buf, "%s", _(NM_LC_9P_FORM_MODE));
152 break;
153 case NM_LBL_9PPATH:
154 nm_str_format(&buf, "%s", _(NM_LC_9P_FORM_PATH));
155 break;
156 case NM_LBL_9PNAME:
157 nm_str_format(&buf, "%s", _(NM_LC_9P_FORM_NAME));
158 break;
159 default:
160 continue;
161 }
162
163 msg_len = mbstowcs(NULL, buf.data, buf.len);
164 if (msg_len > max_label_len)
165 max_label_len = msg_len;
166
167 if (fields[n])
168 set_field_buffer(fields[n], 0, buf.data);
169 }
170
171 nm_str_free(&buf);
172 return max_label_len;
173 }
174
nm_9p_get_data(nm_9p_data_t * data,const nm_vmctl_data_t * cur)175 static int nm_9p_get_data(nm_9p_data_t *data, const nm_vmctl_data_t *cur)
176 {
177 int rc = NM_OK;
178 nm_vect_t err = NM_INIT_VECT;
179
180 nm_get_field_buf(fields[NM_FLD_9PMODE], &data->mode);
181 nm_get_field_buf(fields[NM_FLD_9PPATH], &data->path);
182 nm_get_field_buf(fields[NM_FLD_9PNAME], &data->name);
183
184 if (field_status(fields[NM_FLD_9PMODE])) {
185 if (nm_str_cmp_st(&data->mode, "no") == NM_OK)
186 goto out;
187 }
188 else if (nm_str_cmp_st(nm_vect_str(&cur->main, NM_SQL_9FLG), NM_ENABLE) != NM_OK)
189 goto out;
190
191 nm_form_check_data(_(NM_LC_9P_FORM_PATH), data->path, err);
192 nm_form_check_data(_(NM_LC_9P_FORM_NAME), data->name, err);
193
194 if ((rc = nm_print_empty_fields(&err)) == NM_ERR)
195 nm_vect_free(&err, NULL);
196
197 out:
198 return rc;
199 }
200
nm_9p_update_db(const nm_str_t * name,const nm_9p_data_t * data)201 static void nm_9p_update_db(const nm_str_t *name, const nm_9p_data_t *data)
202 {
203 nm_str_t query = NM_INIT_STR;
204 nm_str_free(&query);
205
206 if (field_status(fields[NM_FLD_9PMODE])) {
207 nm_str_format(&query, NM_9P_SET_MODE_SQL,
208 (nm_str_cmp_st(&data->mode, "yes") == NM_OK) ? "1" : "0", name->data);
209 nm_db_edit(query.data);
210 nm_str_trunc(&query, 0);
211 }
212
213 if (field_status(fields[NM_FLD_9PPATH])) {
214 nm_str_format(&query, NM_9P_SET_PATH_SQL, data->path.data, name->data);
215 nm_db_edit(query.data);
216 nm_str_trunc(&query, 0);
217 }
218
219 if (field_status(fields[NM_FLD_9PNAME])) {
220 nm_str_format(&query, NM_9P_SET_NAME_SQL, data->name.data, name->data);
221 nm_db_edit(query.data);
222 }
223
224 nm_str_free(&query);
225 }
226
227 /* vim:set ts=4 sw=4: */
228