Skip to content

getopt debug

magnum edited this page Nov 27, 2020 · 1 revision

Be sure to update o_flags in case options.h was changed

diff --git a/src/getopt.c b/src/getopt.c
index ef862bacb..05bf28944 100644
--- a/src/getopt.c
+++ b/src/getopt.c
@@ -17,6 +17,8 @@
 #include "getopt.h"
 #include "john.h"
 
+#define GETOPT_DEBUG
+
 static char *opt_errors[] = {
 	NULL,	/* No error */
 	"Unknown option",
@@ -35,6 +37,31 @@ static int completed_negated;
 void *opt_tri_negated = "* prefixed with no- *";
 void *opt_tri_noparam = "* no param given *";
 
+#ifdef GETOPT_DEBUG
+static char* opt_debug(opt_flags flags)
+{
+	int i;
+	static char *o_flags[] =
+		{ "ACTION", "PASSWD", "PWD_SUP", "PWD_REQ", "MULTI", "CRK_MODE", "CRK_SUP", "WORDLIST",
+		  "STDIN", "RULES", "SINGLE", "INC", "MASK", "EXTERNAL", "BATCH", "STDOUT",
+		  "RESTORE", "SESSION", "STATUS", "MAKECHR", "SHOW", "TEST", "FUZZ", "FUZZ_DUMP",
+		  "FORMAT", "SAVEMEM", "FORK", "LOOPBACK", "PIPE", "OPT_BOOL", "OPT_TRISTATE", "OPT_REQ_PARAM",
+		  "UNUSED32", "MARKOV", "UNUSED34", "DUPESUPP", "SCALAR", "VECTOR", "REJECT_PRINTABLE", "NOTESTS",
+		  "REGEX", "INPUT_ENC", "SECOND_ENC", "VERBOSITY", "UNUSED39", "UNUSED40", "STRESSTEST", "MASK_STACKED",
+		  "PRINCE", "PRINCE_DIST", "PRINCE_KEYSPACE", "PRINCE_CASE", "PRINCE_LOOP", "PRINCE_MMAP", "RULES_ALLOW", "REGEX_STACK",
+		  "SUBSETS", "RULES_STACK", "RULES_IN_USE", "RULES_SKIP_NOP", "NO_MASK_BENCH", "FORCE_TTY", "NO-LOG", "UNUSED63" };
+	size_t c;
+	char *output = mem_alloc(sizeof(o_flags));
+
+	c = sprintf(output, "0x%016llx:", flags);
+	for (i = 0; i < sizeof(opt_flags) * 8; i++)
+		if (flags & (1ULL << i))
+			c += sprintf(output + c, " %s", o_flags[i]);
+
+	return output;
+}
+#endif
+
 static char *opt_find(struct opt_entry *list, char *opt, struct opt_entry **entry)
 {
 	char *name, *param;
@@ -140,7 +167,17 @@ static int opt_process_one(struct opt_entry *list, opt_flags *flg, char *opt)
 		return OPT_ERROR_DUPE;
 
 	if (*flg & entry->flg_set & entry->flg_clr)
+#ifdef GETOPT_DEBUG
+	{
+		fprintf(stderr,
+		        "error in %s() flg & entry->flg_set & entry->flg_clr\n\t%s & %s & %s = %s\n",
+		        __FUNCTION__, opt_debug(*flg), opt_debug(entry->flg_set), opt_debug(entry->flg_clr),
+		        opt_debug(*flg & entry->flg_set & entry->flg_clr));
+#endif
 		return OPT_ERROR_COMB;
+#ifdef GETOPT_DEBUG
+	}
+#endif
 
 	*flg &= ~entry->flg_clr;
 	*flg |= entry->flg_set;
@@ -185,7 +222,18 @@ static int opt_check_one(struct opt_entry *list, opt_flags flg, char *opt)
 		return OPT_ERROR_UNKNOWN;
 
 	if ((flg & entry->req_set) != entry->req_set || (flg & entry->req_clr))
+	{
+#ifdef GETOPT_DEBUG
+		if ((flg & entry->req_set) != entry->req_set)
+			fprintf(stderr,
+			        "error in %s() (flg & entry->req_set) != entry->req_set\n\t(%s & %s) == %s\n",
+			        __FUNCTION__, opt_debug(flg), opt_debug(entry->req_set), opt_debug(flg & entry->req_set));
+		if (flg & entry->req_clr)
+			fprintf(stderr, "error in %s() (flg & entry->req_clr)\n\t(%s & %s) = %s\n", __FUNCTION__,
+			        opt_debug(flg), opt_debug(entry->req_clr), opt_debug(flg & entry->req_clr));
+#endif
 		return OPT_ERROR_COMB;
+	}
 
 	return OPT_ERROR_NONE;
 }
@@ -251,4 +299,8 @@ void opt_check(struct opt_entry *list, opt_flags flg, char **argv)
 		}
 		entry++;
 	}
+
+#ifdef GETOPT_DEBUG
+	fprintf(stderr, "flags now %s\n", opt_debug(flg));
+#endif
 }