nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* profile.c
2 * Dialog box for profiles editing
3 * Stig Bjorlykke <stig@bjorlykke.org>, 2008
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23  
24 #include "config.h"
25  
26 #include <string.h>
27 #include <errno.h>
28  
29 #include <glib.h>
30  
31 #include <wsutil/filesystem.h>
32  
33 #include "profile.h"
34  
35 #include "ui/simple_dialog.h"
36  
37 #include <wsutil/file_util.h>
38  
39 static GList *current_profiles = NULL;
40 static GList *edited_profiles = NULL;
41  
42 #define PROF_OPERATION_NEW 1
43 #define PROF_OPERATION_EDIT 2
44  
45 GList * current_profile_list(void) {
46 return g_list_first(current_profiles);
47 }
48  
49 GList * edited_profile_list(void) {
50 return g_list_first(edited_profiles);
51 }
52  
53 static GList *
54 add_profile_entry(GList *fl, const char *profilename, const char *reference, int status,
55 gboolean is_global, gboolean from_global)
56 {
57 profile_def *profile;
58  
59 profile = (profile_def *) g_malloc0(sizeof(profile_def));
60 profile->name = g_strdup(profilename);
61 profile->reference = g_strdup(reference);
62 profile->status = status;
63 profile->is_global = is_global;
64 profile->from_global = from_global;
65 return g_list_append(fl, profile);
66 }
67  
68 static GList *
69 remove_profile_entry(GList *fl, GList *fl_entry)
70 {
71 profile_def *profile;
72  
73 profile = (profile_def *) fl_entry->data;
74 g_free(profile->name);
75 g_free(profile->reference);
76 g_free(profile);
77 return g_list_remove_link(fl, fl_entry);
78 }
79  
80 const gchar *
81 get_profile_parent (const gchar *profilename)
82 {
83 GList *fl_entry = g_list_first(edited_profiles);
84 guint no_edited = g_list_length(edited_profiles);
85 profile_def *profile;
86 guint i;
87  
88 if (fl_entry) {
89 /* We have edited profiles, find parent */
90 for (i = 0; i < no_edited; i++) {
91 while (fl_entry) {
92 profile = (profile_def *) fl_entry->data;
93 if (strcmp (profile->name, profilename) == 0) {
94 if ((profile->status == PROF_STAT_NEW) ||
95 (profile->reference == NULL)) {
96 /* Copy from a new profile */
97 return NULL;
98 } else {
99 /* Found a parent, use this */
100 profilename = profile->reference;
101 }
102 }
103 fl_entry = g_list_next(fl_entry);
104 }
105 fl_entry = g_list_first(edited_profiles);
106 }
107 }
108  
109 return profilename;
110 }
111  
112 const gchar *apply_profile_changes(void) {
113 char *pf_dir_path, *pf_dir_path2, *pf_filename;
114 GList *fl1, *fl2;
115 profile_def *profile1, *profile2;
116 gboolean found;
117 const gchar *err_msg;
118  
119 /* First validate all profile names */
120 fl1 = edited_profile_list();
121 while (fl1) {
122 profile1 = (profile_def *) fl1->data;
123 g_strstrip(profile1->name);
124 if ((err_msg = profile_name_is_valid(profile1->name)) != NULL) {
125 return err_msg;
126 }
127 fl1 = g_list_next(fl1);
128 }
129  
130 /* Then do all copy profiles */
131 fl1 = edited_profile_list();
132 while (fl1) {
133 profile1 = (profile_def *) fl1->data;
134 g_strstrip(profile1->name);
135 if (profile1->status == PROF_STAT_COPY) {
136 if (create_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
137 err_msg = g_strdup_printf("Can't create directory\n\"%s\":\n%s.",
138 pf_dir_path, g_strerror(errno));
139  
140 g_free(pf_dir_path);
141 return err_msg;
142 }
143 profile1->status = PROF_STAT_EXISTS;
144  
145 if (profile1->reference) {
146 if (copy_persconffile_profile(profile1->name, profile1->reference, profile1->from_global,
147 &pf_filename, &pf_dir_path, &pf_dir_path2) == -1) {
148 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
149 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
150 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
151  
152 g_free(pf_filename);
153 g_free(pf_dir_path);
154 g_free(pf_dir_path2);
155 }
156 }
157  
158 g_free (profile1->reference);
159 profile1->reference = g_strdup(profile1->name);
160 }
161 fl1 = g_list_next(fl1);
162 }
163  
164  
165 /* Then create new and rename changed */
166 fl1 = edited_profile_list();
167 while (fl1) {
168 profile1 = (profile_def *) fl1->data;
169 g_strstrip(profile1->name);
170 if (profile1->status == PROF_STAT_NEW) {
171 /* We do not create a directory for the default profile */
172 if (strcmp(profile1->name, DEFAULT_PROFILE)!=0) {
173 if (create_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
174 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
175 "Can't create directory\n\"%s\":\n%s.",
176 pf_dir_path, g_strerror(errno));
177  
178 g_free(pf_dir_path);
179 }
180 profile1->status = PROF_STAT_EXISTS;
181  
182 g_free (profile1->reference);
183 profile1->reference = g_strdup(profile1->name);
184 }
185 } else if (profile1->status == PROF_STAT_CHANGED) {
186 if (strcmp(profile1->reference, profile1->name)!=0) {
187 /* Rename old profile directory to new */
188 if (rename_persconffile_profile(profile1->reference, profile1->name,
189 &pf_dir_path, &pf_dir_path2) == -1) {
190 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
191 "Can't rename directory\n\"%s\" to\n\"%s\":\n%s.",
192 pf_dir_path, pf_dir_path2, g_strerror(errno));
193  
194 g_free(pf_dir_path);
195 g_free(pf_dir_path2);
196 }
197 profile1->status = PROF_STAT_EXISTS;
198 g_free (profile1->reference);
199 profile1->reference = g_strdup(profile1->name);
200 }
201 }
202 fl1 = g_list_next(fl1);
203 }
204  
205 /* Last remove deleted */
206 fl1 = current_profile_list();
207 while (fl1) {
208 found = FALSE;
209 profile1 = (profile_def *) fl1->data;
210 fl2 = edited_profile_list();
211 while (fl2) {
212 profile2 = (profile_def *) fl2->data;
213 if (!profile2->is_global) {
214 if (strcmp(profile1->name, profile2->name)==0) {
215 /* Profile exists in both lists */
216 found = TRUE;
217 } else if (strcmp(profile1->name, profile2->reference)==0) {
218 /* Profile has been renamed */
219 found = TRUE;
220 }
221 }
222 fl2 = g_list_next(fl2);
223 }
224 if (!found) {
225 /* Exists in existing list and not in edited, this is a deleted profile */
226 if (delete_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
227 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
228 "Can't delete profile directory\n\"%s\":\n%s.",
229 pf_dir_path, g_strerror(errno));
230  
231 g_free(pf_dir_path);
232 }
233 }
234 fl1 = g_list_next(fl1);
235 }
236  
237 copy_profile_list();
238 return NULL;
239 }
240  
241 GList *
242 add_to_profile_list(const char *name, const char *expression, int status,
243 gboolean is_global, gboolean from_global)
244 {
245 edited_profiles = add_profile_entry(edited_profiles, name, expression, status,
246 is_global, from_global);
247  
248 return g_list_last(edited_profiles);
249 }
250  
251 void
252 remove_from_profile_list(GList *fl_entry)
253 {
254 edited_profiles = remove_profile_entry(edited_profiles, fl_entry);
255 }
256  
257 void
258 empty_profile_list(gboolean edit_list)
259 {
260 GList **flpp;
261  
262 if (edit_list) {
263 flpp = &edited_profiles;
264  
265 while(*flpp) {
266 *flpp = remove_profile_entry(*flpp, g_list_first(*flpp));
267 }
268  
269 g_assert(g_list_length(*flpp) == 0);
270 }
271  
272 flpp = &current_profiles;
273  
274 while(*flpp) {
275 *flpp = remove_profile_entry(*flpp, g_list_first(*flpp));
276 }
277  
278 g_assert(g_list_length(*flpp) == 0);
279 }
280  
281 void
282 copy_profile_list(void)
283 {
284 GList *flp_src;
285 profile_def *profile;
286  
287 flp_src = edited_profiles;
288  
289 /* throw away the "old" destination list - a NULL list is ok here */
290 empty_profile_list(FALSE);
291  
292 /* copy the list entries */
293 while(flp_src) {
294 profile = (profile_def *)(flp_src)->data;
295  
296 current_profiles = add_profile_entry(current_profiles, profile->name,
297 profile->reference, profile->status,
298 profile->is_global, profile->from_global);
299 flp_src = g_list_next(flp_src);
300 }
301 }
302  
303 void
304 init_profile_list(void)
305 {
306 WS_DIR *dir; /* scanned directory */
307 WS_DIRENT *file; /* current file */
308 const gchar *profiles_dir, *name;
309 gchar *filename;
310  
311 empty_profile_list(TRUE);
312  
313 /* Default entry */
314 add_to_profile_list(DEFAULT_PROFILE, DEFAULT_PROFILE, PROF_STAT_DEFAULT, FALSE, FALSE);
315  
316 /* Local (user) profiles */
317 profiles_dir = get_profiles_dir();
318 if ((dir = ws_dir_open(profiles_dir, 0, NULL)) != NULL) {
319 while ((file = ws_dir_read_name(dir)) != NULL) {
320 name = ws_dir_get_name(file);
321 filename = g_strdup_printf ("%s%s%s", profiles_dir, G_DIR_SEPARATOR_S, name);
322  
323 if (test_for_directory(filename) == EISDIR) {
324 /*fl_entry =*/ add_to_profile_list(name, name, PROF_STAT_EXISTS, FALSE, FALSE);
325 }
326 g_free (filename);
327 }
328 ws_dir_close (dir);
329 }
330  
331 /* Global profiles */
332 profiles_dir = get_global_profiles_dir();
333 if ((dir = ws_dir_open(profiles_dir, 0, NULL)) != NULL) {
334 while ((file = ws_dir_read_name(dir)) != NULL) {
335 name = ws_dir_get_name(file);
336 filename = g_strdup_printf ("%s%s%s", profiles_dir, G_DIR_SEPARATOR_S, name);
337  
338 if (test_for_directory(filename) == EISDIR) {
339 /*fl_entry =*/ add_to_profile_list(name, name, PROF_STAT_EXISTS, TRUE, TRUE);
340 /*profile = (profile_def *) fl_entry->data;*/
341 }
342 g_free (filename);
343 }
344 ws_dir_close (dir);
345 }
346  
347 /* Make the current list and the edited list equal */
348 copy_profile_list ();
349 }
350  
351 gchar *
352 profile_name_is_valid(const gchar *name)
353 {
354 gchar *reason = NULL;
355 gchar *message;
356  
357 #ifdef _WIN32
358 char *invalid_dir_char = "\\/:*?\"<>|";
359 gboolean invalid = FALSE;
360 int i;
361  
362 for (i = 0; i < 9; i++) {
363 if (strchr(name, invalid_dir_char[i])) {
364 /* Invalid character in directory */
365 invalid = TRUE;
366 }
367 }
368 if (name[0] == '.' || name[strlen(name)-1] == '.') {
369 /* Profile name cannot start or end with period */
370 invalid = TRUE;
371 }
372 if (invalid) {
373 reason = g_strdup_printf("start or end with period (.), or contain any of the following characters:\n"
374 " \\ / : * ? \" &lt; &gt; |");
375 }
376 #else
377 if (strchr(name, '/')) {
378 /* Invalid character in directory */
379 reason = g_strdup_printf("contain the '/' character.");
380 }
381 #endif
382  
383 if (reason) {
384 message = g_strdup_printf("A profile name cannot %s\nProfiles unchanged.", reason);
385 g_free(reason);
386 return message;
387 }
388  
389 return NULL;
390 }
391  
392 gboolean delete_current_profile(void) {
393 const gchar *name = get_profile_name();
394 char *pf_dir_path;
395  
396 if (profile_exists(name, FALSE) && strcmp (name, DEFAULT_PROFILE) != 0) {
397 if (delete_persconffile_profile(name, &pf_dir_path) == -1) {
398 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
399 "Can't delete profile directory\n\"%s\":\n%s.",
400 pf_dir_path, g_strerror(errno));
401  
402 g_free(pf_dir_path);
403 } else {
404 return TRUE;
405 }
406 }
407 return FALSE;
408 }
409  
410 /*
411 * Editor modelines
412 *
413 * Local Variables:
414 * c-basic-offset: 4
415 * tab-width: 8
416 * indent-tabs-mode: nil
417 * End:
418 *
419 * ex: set shiftwidth=4 tabstop=8 expandtab:
420 * :indentSize=4:tabSize=8:noTabs=true:
421 */