packet-ldap: fix regression for SASL handling
[wireshark-sm.git] / epan / disabled_protos.c
bloba558aaf48d388c3818c1a0d148df5d6bdd94c4de
1 /* disabled_protos.c
2 * Declarations of routines for reading and writing protocols file that determine
3 * enabling and disabling of protocols.
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <stdio.h>
15 #include <string.h>
16 #include <errno.h>
18 #include <glib.h>
20 #include <wsutil/filesystem.h>
21 #include <epan/proto.h>
22 #include <epan/packet.h>
24 #include "disabled_protos.h"
25 #include <wsutil/file_util.h>
26 #include <wsutil/report_message.h>
28 #define ENABLED_PROTOCOLS_FILE_NAME "enabled_protos"
29 #define DISABLED_PROTOCOLS_FILE_NAME "disabled_protos"
30 #define HEURISTICS_FILE_NAME "heuristic_protos"
33 * Item in a list of disabled protocols.
35 typedef struct {
36 char *name; /* protocol name */
37 } protocol_def;
40 * Item in a list of heuristic dissectors and their enabled state.
42 typedef struct {
43 char *name; /* heuristic short name */
44 gboolean enabled; /* heuristc enabled */
45 } heur_protocol_def;
48 * List of disabled protocols
50 static GList *global_disabled_protos = NULL;
51 static GList *disabled_protos = NULL;
53 * List of enabled protocols (that are disabled by default)
55 static GList *global_enabled_protos = NULL;
56 static GList *enabled_protos = NULL;
58 * List of disabled heuristics
60 static GList *global_disabled_heuristics = NULL;
61 static GList *disabled_heuristics = NULL;
63 #define INIT_BUF_SIZE 128
65 static void
66 discard_existing_list (GList **flp)
68 GList *fl_ent;
69 protocol_def *prot;
71 if (*flp != NULL) {
72 fl_ent = g_list_first(*flp);
73 while (fl_ent != NULL) {
74 prot = (protocol_def *) fl_ent->data;
75 g_free(prot->name);
76 g_free(prot);
77 fl_ent = fl_ent->next;
79 g_list_free(*flp);
80 *flp = NULL;
84 static void
85 heur_discard_existing_list (GList **flp)
87 GList *fl_ent;
88 heur_protocol_def *prot;
90 if (*flp != NULL) {
91 fl_ent = g_list_first(*flp);
92 while (fl_ent != NULL) {
93 prot = (heur_protocol_def *) fl_ent->data;
94 g_free(prot->name);
95 g_free(prot);
96 fl_ent = fl_ent->next;
98 g_list_free(*flp);
99 *flp = NULL;
104 * Enable/Disable protocols as per the stored configuration
106 static void
107 set_protos_list(GList *protos_list, GList *global_protos_list, gboolean enable)
109 gint i;
110 GList *fl_ent;
111 protocol_def *prot;
114 * Assume no protocols disabled by default wants to be enabled
116 if (protos_list == NULL)
117 goto skip;
119 fl_ent = g_list_first(protos_list);
121 while (fl_ent != NULL) {
122 prot = (protocol_def *) fl_ent->data;
123 i = proto_get_id_by_filter_name(prot->name);
124 if (i == -1) {
125 /* XXX - complain here? */
126 } else {
127 if (proto_can_toggle_protocol(i))
128 proto_set_decoding(i, enable);
131 fl_ent = fl_ent->next;
134 skip:
135 if (global_protos_list == NULL)
136 return;
138 fl_ent = g_list_first(global_protos_list);
140 while (fl_ent != NULL) {
141 prot = (protocol_def *) fl_ent->data;
142 i = proto_get_id_by_filter_name(prot->name);
143 if (i == -1) {
144 /* XXX - complain here? */
145 } else {
146 if (proto_can_toggle_protocol(i)) {
147 proto_set_decoding(i, enable);
148 proto_set_cant_toggle(i);
152 fl_ent = fl_ent->next;
157 * Write out a list of protocols based on condition
159 * On success, "*pref_path_return" is set to NULL.
160 * On error, "*pref_path_return" is set to point to the pathname of
161 * the file we tried to read - it should be freed by our caller -
162 * and "*errno_return" is set to the error.
164 static void
165 save_protos_list(char **pref_path_return, int *errno_return, const char* filename,
166 const char* header_comment, gboolean (*protocol_check)(protocol_t *protocol))
168 gchar *ff_path, *ff_path_new;
169 FILE *ff;
170 gint i;
171 protocol_t *protocol;
172 void *cookie;
173 gboolean first = TRUE;
175 *pref_path_return = NULL; /* assume no error */
177 ff_path = get_persconffile_path(filename, TRUE);
179 /* Write to "XXX.new", and rename if that succeeds.
180 That means we don't trash the file if we fail to write it out
181 completely. */
182 ff_path_new = g_strdup_printf("%s.new", ff_path);
184 if ((ff = ws_fopen(ff_path_new, "w")) == NULL) {
185 *pref_path_return = ff_path;
186 *errno_return = errno;
187 g_free(ff_path_new);
188 return;
191 /* Iterate over all the protocols */
192 for (i = proto_get_first_protocol(&cookie); i != -1;
193 i = proto_get_next_protocol(&cookie)) {
195 if (!proto_can_toggle_protocol(i)) {
196 continue;
199 protocol = find_protocol_by_id(i);
200 if (protocol_check(protocol) == FALSE)
201 continue;
203 if (first) {
204 if (header_comment != NULL) {
205 /* Write out a comment explaining what the file is */
206 fprintf(ff, "%s\n", header_comment);
208 first = FALSE;
211 /* Write out the protocol name. */
212 fprintf(ff, "%s\n", proto_get_protocol_filter_name(i));
215 if (fclose(ff) == EOF) {
216 *pref_path_return = ff_path;
217 *errno_return = errno;
218 ws_unlink(ff_path_new);
219 g_free(ff_path_new);
220 return;
223 #ifdef _WIN32
224 /* ANSI C doesn't say whether "rename()" removes the target if it
225 exists; the Win32 call to rename files doesn't do so, which I
226 infer is the reason why the MSVC++ "rename()" doesn't do so.
227 We must therefore remove the target file first, on Windows.
229 XXX - ws_rename() should be ws_stdio_rename() on Windows,
230 and ws_stdio_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING,
231 so it should remove the target if it exists, so this stuff
232 shouldn't be necessary. Perhaps it dates back to when we were
233 calling rename(), with that being a wrapper around Microsoft's
234 _rename(), which didn't remove the target. */
235 if (ws_remove(ff_path) < 0 && errno != ENOENT) {
236 /* It failed for some reason other than "it's not there"; if
237 it's not there, we don't need to remove it, so we just
238 drive on. */
239 *pref_path_return = ff_path;
240 *errno_return = errno;
241 ws_unlink(ff_path_new);
242 g_free(ff_path_new);
243 return;
245 #endif
247 if (ws_rename(ff_path_new, ff_path) < 0) {
248 *pref_path_return = ff_path;
249 *errno_return = errno;
250 ws_unlink(ff_path_new);
251 g_free(ff_path_new);
252 return;
254 g_free(ff_path_new);
255 g_free(ff_path);
258 static int
259 read_protos_list_file(const char *ff_path, FILE *ff, GList **flp)
261 protocol_def *prot;
262 int c;
263 char *prot_name;
264 int prot_name_len;
265 int prot_name_index;
266 int line = 1;
267 gboolean in_comment = FALSE;
270 /* Allocate the protocol name buffer. */
271 prot_name_len = INIT_BUF_SIZE;
272 prot_name = (char *)g_malloc(prot_name_len + 1);
274 for (line = 1; ; line++) {
275 /* Lines in a protocol file contain the "filter name" of a protocol
276 to be enabled or disabled. */
278 /* Skip over leading white space, if any. */
279 while ((c = ws_getc_unlocked(ff)) != EOF && g_ascii_isspace(c)) {
280 if (c == '\n') {
281 /* Blank line. */
282 continue;
286 if (c == EOF) {
287 if (ferror(ff))
288 goto error; /* I/O error */
289 else
290 break; /* Nothing more to read */
292 ungetc(c, ff); /* Unread the non-white-space character. */
294 /* Get the name of the protocol. */
295 prot_name_index = 0;
296 for (;;) {
297 c = ws_getc_unlocked(ff);
298 if (c == EOF)
299 break; /* End of file, or I/O error */
300 if (g_ascii_isspace(c))
301 break; /* Trailing white space, or end of line. */
302 if (c == '#') {
303 in_comment = TRUE;
304 break; /* Start of comment, running to end of line. */
306 /* Add this character to the protocol name string. */
307 if (prot_name_index >= prot_name_len) {
308 /* protocol name buffer isn't long enough; double its length. */
309 prot_name_len *= 2;
310 prot_name = (char *)g_realloc(prot_name, prot_name_len + 1);
312 prot_name[prot_name_index] = c;
313 prot_name_index++;
316 if (g_ascii_isspace(c) && c != '\n') {
317 /* Skip over trailing white space. */
318 while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n' && g_ascii_isspace(c))
320 if (c != EOF && c != '\n' && c != '#') {
321 /* Non-white-space after the protocol name; warn about it,
322 in case we come up with a reason to use it. */
323 g_warning("'%s' line %d has extra stuff after the protocol name.",
324 ff_path, line);
327 if (c != EOF && c != '\n' && in_comment == TRUE) {
328 /* Skip to end of line. */
329 while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n')
333 if (c == EOF) {
334 if (ferror(ff))
335 goto error; /* I/O error */
336 else {
337 /* EOF, not error; no newline seen before EOF */
338 g_warning("'%s' line %d doesn't have a newline.", ff_path,
339 line);
341 break; /* nothing more to read */
344 if (in_comment) {
345 in_comment = FALSE;
346 continue;
349 /* Null-terminate the protocol name. */
350 if (prot_name_index >= prot_name_len) {
351 /* protocol name buffer isn't long enough; double its length. */
352 prot_name_len *= 2;
353 prot_name = (char *)g_realloc(prot_name, prot_name_len + 1);
355 prot_name[prot_name_index] = '\0';
357 /* Add the new protocol to the list of disabled protocols */
358 prot = g_new(protocol_def, 1);
359 prot->name = g_strdup(prot_name);
360 *flp = g_list_append(*flp, prot);
362 g_free(prot_name);
363 return 0;
365 error:
366 g_free(prot_name);
367 return errno;
371 * Read in global and personal versions of a list of protocols.
373 * If we can open and read the global version, *gpath_return is set to
374 * NULL. Otherwise, *gpath_return is set to point to the pathname of
375 * the file we tried to read - it should be freed by our caller - and
376 * *gopen_errno_return is set to the error if an open failed or
377 * *gread_errno_return is set to the error if a read failed.
379 * If we can open and read the personal version, *path_return is set to
380 * NULL. Otherwise, *path_return is set to point to the pathname of
381 * the file we tried to read - it should be freed by our caller - and
382 * *open_errno_return is set to the error if an open failed or
383 * *read_errno_return is set to the error if a read failed.
385 static void
386 read_protos_list(char **gpath_return, int *gopen_errno_return,
387 int *gread_errno_return,
388 char **path_return, int *open_errno_return,
389 int *read_errno_return,
390 const char* filename,
391 GList **global_protos_list, GList **protos_list)
393 int err;
394 char *gff_path, *ff_path;
395 FILE *ff;
397 /* Construct the pathname of the global disabled protocols file. */
398 gff_path = get_datafile_path(filename);
400 /* If we already have a list of protocols, discard it. */
401 discard_existing_list (global_protos_list);
403 /* Read the global disabled protocols file, if it exists. */
404 *gpath_return = NULL;
405 if ((ff = ws_fopen(gff_path, "r")) != NULL) {
406 /* We succeeded in opening it; read it. */
407 err = read_protos_list_file(gff_path, ff, global_protos_list);
408 if (err != 0) {
409 /* We had an error reading the file; return the errno and the
410 pathname, so our caller can report the error. */
411 *gopen_errno_return = 0;
412 *gread_errno_return = err;
413 *gpath_return = gff_path;
414 } else
415 g_free(gff_path);
416 fclose(ff);
417 } else {
418 /* We failed to open it. If we failed for some reason other than
419 "it doesn't exist", return the errno and the pathname, so our
420 caller can report the error. */
421 if (errno != ENOENT) {
422 *gopen_errno_return = errno;
423 *gread_errno_return = 0;
424 *gpath_return = gff_path;
425 } else
426 g_free(gff_path);
429 /* Construct the pathname of the user's disabled protocols file. */
430 ff_path = get_persconffile_path(filename, TRUE);
432 /* If we already have a list of protocols, discard it. */
433 discard_existing_list (protos_list);
435 /* Read the user's disabled protocols file, if it exists. */
436 *path_return = NULL;
437 if ((ff = ws_fopen(ff_path, "r")) != NULL) {
438 /* We succeeded in opening it; read it. */
439 err = read_protos_list_file(ff_path, ff, protos_list);
440 if (err != 0) {
441 /* We had an error reading the file; return the errno and the
442 pathname, so our caller can report the error. */
443 *open_errno_return = 0;
444 *read_errno_return = err;
445 *path_return = ff_path;
446 } else
447 g_free(ff_path);
448 fclose(ff);
449 } else {
450 /* We failed to open it. If we failed for some reason other than
451 "it doesn't exist", return the errno and the pathname, so our
452 caller can report the error. */
453 if (errno != ENOENT) {
454 *open_errno_return = errno;
455 *read_errno_return = 0;
456 *path_return = ff_path;
457 } else
458 g_free(ff_path);
462 /************************************************************************
463 * Disabling dissectors
464 ************************************************************************/
467 * Disable a particular protocol by name
469 void
470 proto_disable_proto_by_name(const char *name)
472 protocol_t *protocol;
473 int proto_id;
475 proto_id = proto_get_id_by_filter_name(name);
476 if (proto_id >= 0 ) {
477 protocol = find_protocol_by_id(proto_id);
478 if (proto_is_protocol_enabled(protocol) == TRUE) {
479 if (proto_can_toggle_protocol(proto_id) == TRUE) {
480 proto_set_decoding(proto_id, FALSE);
486 static gboolean disable_proto_list_check(protocol_t *protocol)
488 if (proto_is_protocol_enabled(protocol) == FALSE)
489 return TRUE;
491 return FALSE;
494 /************************************************************************
495 * Enabling dissectors (that are disabled by default)
496 ************************************************************************/
498 WS_DLL_PUBLIC void
499 proto_enable_proto_by_name(const char *name)
501 protocol_t *protocol;
502 int proto_id;
504 proto_id = proto_get_id_by_filter_name(name);
505 if (proto_id >= 0 ) {
506 protocol = find_protocol_by_id(proto_id);
507 if ((proto_is_protocol_enabled_by_default(protocol) == FALSE) &&
508 (proto_is_protocol_enabled(protocol) == FALSE)) {
509 if (proto_can_toggle_protocol(proto_id) == TRUE) {
510 proto_set_decoding(proto_id, TRUE);
516 static gboolean enable_proto_list_check(protocol_t *protocol)
518 if ((proto_is_protocol_enabled_by_default(protocol) == FALSE) &&
519 (proto_is_protocol_enabled(protocol) == TRUE))
520 return TRUE;
522 return FALSE;
525 /************************************************************************
526 * Heuristic dissectors
527 ************************************************************************/
530 static void
531 set_disabled_heur_dissector_list(void)
533 GList *fl_ent;
534 heur_protocol_def *heur;
535 heur_dtbl_entry_t* h;
537 if (disabled_heuristics == NULL)
538 goto skip;
540 fl_ent = g_list_first(disabled_heuristics);
542 while (fl_ent != NULL) {
543 heur = (heur_protocol_def *) fl_ent->data;
544 h = find_heur_dissector_by_unique_short_name(heur->name);
545 if (h != NULL) {
546 h->enabled = heur->enabled;
549 fl_ent = fl_ent->next;
552 skip:
553 if (global_disabled_heuristics == NULL)
554 return;
556 fl_ent = g_list_first(global_disabled_heuristics);
558 while (fl_ent != NULL) {
559 heur = (heur_protocol_def *) fl_ent->data;
561 h = find_heur_dissector_by_unique_short_name(heur->name);
562 if (h != NULL) {
563 h->enabled = heur->enabled;
566 fl_ent = fl_ent->next;
570 static int
571 read_heur_dissector_list_file(const char *ff_path, FILE *ff, GList **flp)
573 heur_protocol_def *heur;
574 int c;
575 char *heuristic_name;
576 int heuristic_name_len;
577 int name_index;
578 gboolean parse_enabled;
579 gboolean enabled;
580 int line = 1;
583 /* Allocate the protocol name buffer. */
584 heuristic_name_len = INIT_BUF_SIZE;
585 heuristic_name = (char *)g_malloc(heuristic_name_len + 1);
587 for (line = 1; ; line++) {
588 /* Lines in a disabled protocol file contain the "filter name" of
589 a protocol to be disabled. */
591 /* Skip over leading white space, if any. */
592 while ((c = ws_getc_unlocked(ff)) != EOF && g_ascii_isspace(c)) {
593 if (c == '\n') {
594 /* Blank line. */
595 continue;
599 if (c == EOF) {
600 if (ferror(ff))
601 goto error; /* I/O error */
602 else
603 break; /* Nothing more to read */
605 ungetc(c, ff); /* Unread the non-white-space character. */
607 /* Get the name of the protocol. */
608 name_index = 0;
609 enabled = FALSE;
610 parse_enabled = FALSE;
611 for (;;) {
612 c = ws_getc_unlocked(ff);
613 if (c == EOF)
614 break; /* End of file, or I/O error */
615 if (g_ascii_isspace(c))
616 break; /* Trailing white space, or end of line. */
617 if (c == ',') {/* Separator for enable/disable */
618 parse_enabled = TRUE;
619 continue;
621 if (c == '#')
622 break; /* Start of comment, running to end of line. */
623 if (parse_enabled) {
624 enabled = ((c == '1') ? TRUE : FALSE);
625 break;
627 /* Add this character to the protocol name string. */
628 if (name_index >= heuristic_name_len) {
629 /* protocol name buffer isn't long enough; double its length. */
630 heuristic_name_len *= 2;
631 heuristic_name = (char *)g_realloc(heuristic_name, heuristic_name_len + 1);
633 heuristic_name[name_index] = c;
634 name_index++;
637 if (g_ascii_isspace(c) && c != '\n') {
638 /* Skip over trailing white space. */
639 while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n' && g_ascii_isspace(c))
641 if (c != EOF && c != '\n' && c != '#') {
642 /* Non-white-space after the protocol name; warn about it,
643 in case we come up with a reason to use it. */
644 g_warning("'%s' line %d has extra stuff after the protocol name.",
645 ff_path, line);
648 if (c != EOF && c != '\n') {
649 /* Skip to end of line. */
650 while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n')
654 if (c == EOF) {
655 if (ferror(ff))
656 goto error; /* I/O error */
657 else {
658 /* EOF, not error; no newline seen before EOF */
659 g_warning("'%s' line %d doesn't have a newline.", ff_path,
660 line);
662 break; /* nothing more to read */
665 /* Null-terminate the protocol name. */
666 if (name_index >= heuristic_name_len) {
667 /* protocol name buffer isn't long enough; double its length. */
668 heuristic_name_len *= 2;
669 heuristic_name = (char *)g_realloc(heuristic_name, heuristic_name_len + 1);
671 heuristic_name[name_index] = '\0';
673 /* Add the new protocol to the list of protocols */
674 heur = g_new(heur_protocol_def, 1);
675 heur->name = g_strdup(heuristic_name);
676 heur->enabled = enabled;
677 *flp = g_list_append(*flp, heur);
679 g_free(heuristic_name);
680 return 0;
682 error:
683 g_free(heuristic_name);
684 return errno;
687 static void
688 read_heur_dissector_list(char **gpath_return, int *gopen_errno_return,
689 int *gread_errno_return,
690 char **path_return, int *open_errno_return,
691 int *read_errno_return)
693 int err;
694 char *gff_path, *ff_path;
695 FILE *ff;
697 /* If we already have a list of protocols, discard it. */
698 heur_discard_existing_list(&global_disabled_heuristics);
700 /* Construct the pathname of the global disabled heuristic dissectors file. */
701 gff_path = get_datafile_path(HEURISTICS_FILE_NAME);
703 /* Read the global disabled protocols file, if it exists. */
704 *gpath_return = NULL;
705 if ((ff = ws_fopen(gff_path, "r")) != NULL) {
706 /* We succeeded in opening it; read it. */
707 err = read_heur_dissector_list_file(gff_path, ff,
708 &global_disabled_heuristics);
709 if (err != 0) {
710 /* We had an error reading the file; return the errno and the
711 pathname, so our caller can report the error. */
712 *gopen_errno_return = 0;
713 *gread_errno_return = err;
714 *gpath_return = gff_path;
715 } else
716 g_free(gff_path);
717 fclose(ff);
718 } else {
719 /* We failed to open it. If we failed for some reason other than
720 "it doesn't exist", return the errno and the pathname, so our
721 caller can report the error. */
722 if (errno != ENOENT) {
723 *gopen_errno_return = errno;
724 *gread_errno_return = 0;
725 *gpath_return = gff_path;
726 } else
727 g_free(gff_path);
730 /* Construct the pathname of the user's disabled protocols file. */
731 ff_path = get_persconffile_path(HEURISTICS_FILE_NAME, TRUE);
733 /* If we already have a list of protocols, discard it. */
734 heur_discard_existing_list (&disabled_heuristics);
736 /* Read the user's disabled protocols file, if it exists. */
737 *path_return = NULL;
738 if ((ff = ws_fopen(ff_path, "r")) != NULL) {
739 /* We succeeded in opening it; read it. */
740 err = read_heur_dissector_list_file(ff_path, ff, &disabled_heuristics);
741 if (err != 0) {
742 /* We had an error reading the file; return the errno and the
743 pathname, so our caller can report the error. */
744 *open_errno_return = 0;
745 *read_errno_return = err;
746 *path_return = ff_path;
747 } else
748 g_free(ff_path);
749 fclose(ff);
750 } else {
751 /* We failed to open it. If we failed for some reason other than
752 "it doesn't exist", return the errno and the pathname, so our
753 caller can report the error. */
754 if (errno != ENOENT) {
755 *open_errno_return = errno;
756 *read_errno_return = 0;
757 *path_return = ff_path;
758 } else
759 g_free(ff_path);
763 static gint
764 heur_compare(gconstpointer a, gconstpointer b)
766 return strcmp(((const heur_dtbl_entry_t *)a)->short_name,
767 ((const heur_dtbl_entry_t *)b)->short_name);
770 static void
771 write_heur_dissector(gpointer data, gpointer user_data)
773 heur_dtbl_entry_t* dtbl_entry = (heur_dtbl_entry_t*)data;
774 FILE *ff = (FILE*)user_data;
776 /* Write out the heuristic short name and its enabled state */
777 fprintf(ff, "%s,%d\n", dtbl_entry->short_name, dtbl_entry->enabled ? 1 : 0);
780 static void
781 sort_dissector_table_entries(const char *table_name _U_,
782 heur_dtbl_entry_t *dtbl_entry, gpointer user_data)
784 GSList **list = (GSList**)user_data;
785 *list = g_slist_insert_sorted(*list, dtbl_entry, heur_compare);
788 static void
789 sort_heur_dissector_tables(const char *table_name, struct heur_dissector_list *list, gpointer w)
791 if (list) {
792 heur_dissector_table_foreach(table_name, sort_dissector_table_entries, w);
796 static void
797 save_disabled_heur_dissector_list(char **pref_path_return, int *errno_return)
799 gchar *ff_path, *ff_path_new;
800 GSList *sorted_heur_list = NULL;
801 FILE *ff;
803 *pref_path_return = NULL; /* assume no error */
805 ff_path = get_persconffile_path(HEURISTICS_FILE_NAME, TRUE);
807 /* Write to "XXX.new", and rename if that succeeds.
808 That means we don't trash the file if we fail to write it out
809 completely. */
810 ff_path_new = g_strdup_printf("%s.new", ff_path);
812 if ((ff = ws_fopen(ff_path_new, "w")) == NULL) {
813 *pref_path_return = ff_path;
814 *errno_return = errno;
815 g_free(ff_path_new);
816 return;
819 /* Iterate over all the heuristic dissectors to sort them in alphabetical order by short name */
820 dissector_all_heur_tables_foreach_table(sort_heur_dissector_tables, &sorted_heur_list, NULL);
822 /* Write the list */
823 g_slist_foreach(sorted_heur_list, write_heur_dissector, ff);
824 g_slist_free(sorted_heur_list);
826 if (fclose(ff) == EOF) {
827 *pref_path_return = ff_path;
828 *errno_return = errno;
829 ws_unlink(ff_path_new);
830 g_free(ff_path_new);
831 return;
834 #ifdef _WIN32
835 /* ANSI C doesn't say whether "rename()" removes the target if it
836 exists; the Win32 call to rename files doesn't do so, which I
837 infer is the reason why the MSVC++ "rename()" doesn't do so.
838 We must therefore remove the target file first, on Windows.
840 XXX - ws_rename() should be ws_stdio_rename() on Windows,
841 and ws_stdio_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING,
842 so it should remove the target if it exists, so this stuff
843 shouldn't be necessary. Perhaps it dates back to when we were
844 calling rename(), with that being a wrapper around Microsoft's
845 _rename(), which didn't remove the target. */
846 if (ws_remove(ff_path) < 0 && errno != ENOENT) {
847 /* It failed for some reason other than "it's not there"; if
848 it's not there, we don't need to remove it, so we just
849 drive on. */
850 *pref_path_return = ff_path;
851 *errno_return = errno;
852 ws_unlink(ff_path_new);
853 g_free(ff_path_new);
854 return;
856 #endif
858 if (ws_rename(ff_path_new, ff_path) < 0) {
859 *pref_path_return = ff_path;
860 *errno_return = errno;
861 ws_unlink(ff_path_new);
862 g_free(ff_path_new);
863 return;
865 g_free(ff_path_new);
866 g_free(ff_path);
869 gboolean
870 proto_enable_heuristic_by_name(const char *name, gboolean enable)
872 heur_dtbl_entry_t* heur = find_heur_dissector_by_unique_short_name(name);
873 if (heur != NULL) {
874 heur->enabled = enable;
875 return TRUE;
876 } else {
877 return FALSE;
881 static void
882 disabled_protos_free(gpointer p, gpointer user_data _U_)
884 protocol_def* pd = (protocol_def*)p;
885 g_free(pd->name);
886 g_free(p);
890 * Read the files that enable and disable protocols and heuristic
891 * dissectors. Report errors through the UI.
893 void
894 read_enabled_and_disabled_lists(void)
896 char *gpath, *path;
897 int gopen_errno, gread_errno;
898 int open_errno, read_errno;
901 * Read the global and personal disabled protocols files.
903 read_protos_list(&gpath, &gopen_errno, &gread_errno,
904 &path, &open_errno, &read_errno,
905 DISABLED_PROTOCOLS_FILE_NAME,
906 &global_disabled_protos, &disabled_protos);
907 if (gpath != NULL) {
908 if (gopen_errno != 0) {
909 report_warning("Could not open global disabled protocols file\n\"%s\": %s.",
910 gpath, g_strerror(gopen_errno));
912 if (gread_errno != 0) {
913 report_warning("I/O error reading global disabled protocols file\n\"%s\": %s.",
914 gpath, g_strerror(gread_errno));
916 g_free(gpath);
917 gpath = NULL;
919 if (path != NULL) {
920 if (open_errno != 0) {
921 report_warning("Could not open your disabled protocols file\n\"%s\": %s.",
922 path, g_strerror(open_errno));
924 if (read_errno != 0) {
925 report_warning("I/O error reading your disabled protocols file\n\"%s\": %s.",
926 path, g_strerror(read_errno));
928 g_free(path);
929 path = NULL;
933 * Read the global and personal enabled protocols files.
935 read_protos_list(&gpath, &gopen_errno, &gread_errno,
936 &path, &open_errno, &read_errno,
937 ENABLED_PROTOCOLS_FILE_NAME,
938 &global_enabled_protos, &enabled_protos);
939 if (gpath != NULL) {
940 if (gopen_errno != 0) {
941 report_warning("Could not open global enabled protocols file\n\"%s\": %s.",
942 gpath, g_strerror(gopen_errno));
944 if (gread_errno != 0) {
945 report_warning("I/O error reading global enabled protocols file\n\"%s\": %s.",
946 gpath, g_strerror(gread_errno));
948 g_free(gpath);
949 gpath = NULL;
951 if (path != NULL) {
952 if (open_errno != 0) {
953 report_warning("Could not open your enabled protocols file\n\"%s\": %s.",
954 path, g_strerror(open_errno));
956 if (read_errno != 0) {
957 report_warning("I/O error reading your enabled protocols file\n\"%s\": %s.",
958 path, g_strerror(read_errno));
960 g_free(path);
961 path = NULL;
965 * Read the global and personal heuristic dissector list files.
967 read_heur_dissector_list(&gpath, &gopen_errno, &gread_errno,
968 &path, &open_errno, &read_errno);
969 if (gpath != NULL) {
970 if (gopen_errno != 0) {
971 report_warning("Could not open global heuristic dissectors file\n\"%s\": %s.",
972 gpath, g_strerror(gopen_errno));
974 if (gread_errno != 0) {
975 report_warning("I/O error reading global heuristic dissectors file\n\"%s\": %s.",
976 gpath, g_strerror(gread_errno));
978 g_free(gpath);
979 gpath = NULL;
981 if (path != NULL) {
982 if (open_errno != 0) {
983 report_warning("Could not open your heuristic dissectors file\n\"%s\": %s.",
984 path, g_strerror(open_errno));
986 if (read_errno != 0) {
987 report_warning("I/O error reading your heuristic dissectors file\n\"%s\": %s.",
988 path, g_strerror(read_errno));
990 g_free(path);
991 path = NULL;
995 * Enable/disable protocols and heuristic dissectors as per the
996 * contents of the files we just read.
998 set_protos_list(disabled_protos, global_disabled_protos, FALSE);
999 set_protos_list(enabled_protos, global_enabled_protos, TRUE);
1000 set_disabled_heur_dissector_list();
1004 * Write out the lists of enabled and disabled protocols and heuristic
1005 * dissectors to the corresponding files. Report errors through the UI.
1007 void
1008 save_enabled_and_disabled_lists(void)
1010 char *pf_dir_path;
1011 char *pf_path;
1012 int pf_save_errno;
1014 /* Create the directory that holds personal configuration files, if
1015 necessary. */
1016 if (create_persconffile_dir(&pf_dir_path) == -1) {
1017 report_failure("Can't create directory\n\"%s\"\nfor disabled protocols file: %s.",
1018 pf_dir_path, g_strerror(errno));
1019 g_free(pf_dir_path);
1020 return;
1023 save_protos_list(&pf_path, &pf_save_errno, DISABLED_PROTOCOLS_FILE_NAME,
1024 NULL, disable_proto_list_check);
1025 if (pf_path != NULL) {
1026 report_failure("Could not save to your disabled protocols file\n\"%s\": %s.",
1027 pf_path, g_strerror(pf_save_errno));
1028 g_free(pf_path);
1031 save_protos_list(&pf_path, &pf_save_errno, ENABLED_PROTOCOLS_FILE_NAME,
1032 "#This file is for enabling protocols that are disabled by default",
1033 enable_proto_list_check);
1034 if (pf_path != NULL) {
1035 report_failure("Could not save to your enabled protocols file\n\"%s\": %s.",
1036 pf_path, g_strerror(pf_save_errno));
1037 g_free(pf_path);
1040 save_disabled_heur_dissector_list(&pf_path, &pf_save_errno);
1041 if (pf_path != NULL) {
1042 report_failure("Could not save to your disabled heuristic protocol file\n\"%s\": %s.",
1043 pf_path, g_strerror(pf_save_errno));
1044 g_free(pf_path);
1048 void
1049 cleanup_enabled_and_disabled_lists(void)
1051 g_list_foreach(global_disabled_heuristics, disabled_protos_free, NULL);
1052 g_list_free(global_disabled_heuristics);
1053 g_list_foreach(disabled_heuristics, disabled_protos_free, NULL);
1054 g_list_free(disabled_heuristics);
1055 g_list_foreach(global_disabled_protos, disabled_protos_free, NULL);
1056 g_list_free(global_disabled_protos);
1057 g_list_foreach(disabled_protos, disabled_protos_free, NULL);
1058 g_list_free(disabled_protos);
1062 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1064 * Local Variables:
1065 * c-basic-offset: 2
1066 * tab-width: 8
1067 * indent-tabs-mode: nil
1068 * End:
1070 * ex: set shiftwidth=2 tabstop=8 expandtab:
1071 * :indentSize=2:tabSize=8:noTabs=true: