OK. Here's a complete version, with concordance.c integration. It works
for all the files in harmony_usb_logs, and a file of each type that I
got from the Website.
? concordance/.concordance.c.swp
? concordance/.deps
? concordance/.libs
? concordance/Makefile
? concordance/Makefile.in
? concordance/aclocal.m4
? concordance/autom4te.cache
? concordance/concordance
? concordance/config.guess
? concordance/config.h
? concordance/config.h.in
? concordance/config.log
? concordance/config.status
? concordance/config.sub
? concordance/configure
? concordance/depcomp
? concordance/dummy.c
? concordance/install-sh
? concordance/libtool
? concordance/ltmain.sh
? concordance/missing
? concordance/stamp-h1
? libconcord/.deps
? libconcord/.libconcord.cpp.swp
? libconcord/.libconcord.h.swp
? libconcord/.libs
? libconcord/Makefile
? libconcord/Makefile.in
? libconcord/aclocal.m4
? libconcord/autom4te.cache
? libconcord/binaryfile.lo
? libconcord/config.guess
? libconcord/config.h
? libconcord/config.h.in
? libconcord/config.log
? libconcord/config.status
? libconcord/config.sub
? libconcord/configure
? libconcord/depcomp
? libconcord/install-sh
? libconcord/libconcord.la
? libconcord/libconcord.lo
? libconcord/libtool
? libconcord/libusbhid.lo
? libconcord/ltmain.sh
? libconcord/missing
? libconcord/remote.lo
? libconcord/remote_z.lo
? libconcord/stamp-h1
? libconcord/usblan.lo
? libconcord/web.lo
Index: concordance/concordance.c
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.c,v
retrieving revision 1.21
diff -u -p -r1.21 concordance.c
--- concordance/concordance.c	3 Apr 2008 09:45:16 -0000	1.21
+++ concordance/concordance.c	4 Apr 2008 04:25:41 -0000
@@ -548,50 +548,30 @@ void parse_options(struct options_t *opt
 
 }
 
-void detect_mode(char *file_name, int *mode)
+int detect_mode(uint8_t *data, uint32_t size, int *mode)
 {
-	/*
-	 * Now, in case someone passed in just a filename, check arguments
-	 */
-	if (*mode == MODE_UNSET) {
-		char *file_name_copy;
-		char *file;
-
-		/*
-		 * FIXME: We'll attempt to figure out what to
-		 *        do based on filename. This is fragile
-		 *        and should be done based on some
-		 *        metadata in the file... but this will
-		 *        do for now.
-		 */
-
-		/*
-		 * Dup our string since POSIX basename()
-		 * may modify it.
-		 */
-		file_name_copy = (char *)strdup(file_name);
-		file = basename(file_name_copy);
-
-		if (!strcasecmp(file, "connectivity.ezhex")) {
-			*mode = MODE_CONNECTIVITY;
-		} else if (!strcasecmp(file, "update.ezhex")) {
-			*mode = MODE_WRITE_CONFIG;
-		} else if (!strcasecmp(file, "learnir.eztut")) {
-			*mode = MODE_LEARN_IR;
-		} else if (!strcasecmp(file, "latestfirmware.ezup")) {
-			*mode = MODE_WRITE_FIRMWARE;
-		} else {
-			fprintf(stderr,
-				"Don't know what to do with %s\n",
-				file_name);
-			exit(1);
-		}
-		free(file_name_copy);
-		/*	
-		 * Since basename returns a pointer to
-		 * file_name_copy, if we free(file), we get
-		 * a double-free bug.
-		 */
+	int err, type;
+
+	err = identify_file(data, size, &type);
+	if (err) {
+		return err;
+	}
+
+	switch (type) {
+	case TYPE_CONNECTIVITY:
+		*mode = MODE_CONNECTIVITY;
+		return 0;
+	case TYPE_CONFIGURATION:
+		*mode = MODE_WRITE_CONFIG;
+		return 0;
+	case TYPE_FIRMWARE:
+		*mode = MODE_WRITE_FIRMWARE;
+		return 0;
+	case TYPE_LEARN_IR:
+		*mode = MODE_LEARN_IR;
+		return 0;
+	default:
+		return LC_ERROR;
 	}
 }
 
@@ -818,7 +798,10 @@ int main(int argc, char *argv[])
  	 */
 	if (file_name && (mode != MODE_DUMP_CONFIG && mode != MODE_DUMP_FIRMWARE
 			  && mode != MODE_DUMP_SAFEMODE)) {
-		read_file(file_name, &data, &size);
+		if (read_file(file_name, &data, &size)) {
+			printf("Cannot read input file.\n");
+			exit(1);
+		}
 	}
 
 	/*
@@ -828,15 +811,10 @@ int main(int argc, char *argv[])
 	 * FIXME: This should be something NOT based on filename.
 	 */
 	if (mode == MODE_UNSET) {
-		detect_mode(file_name, &mode);
-	}
-
-	/*
-	 * And if we still don't have a mode, we exit.
-	 */
-	if (mode == MODE_UNSET) {
-		printf("No mode requested. No work to do.\n");
-		exit(1);
+		if (detect_mode(data, size, &mode)) {
+			printf("Cannot determine mode of operation from file.\n");
+			exit(1);
+		}
 	}
 
 	/*
Index: libconcord/libconcord.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.cpp,v
retrieving revision 1.23
diff -u -p -r1.23 libconcord.cpp
--- libconcord/libconcord.cpp	3 Apr 2008 07:01:46 -0000	1.23
+++ libconcord/libconcord.cpp	4 Apr 2008 04:25:41 -0000
@@ -324,6 +324,116 @@ void delete_blob(uint8_t *ptr)
 	delete[] ptr;
 }
 
+int identify_file(uint8_t *in, uint32_t size, int *type)
+{
+	int err;
+
+	/*
+	 * Validate this is a remotely sane XML file
+	 */
+	uint8_t *start_info_ptr;
+	err = GetTag("INFORMATION", in, size, start_info_ptr);
+	if (err == -1) {
+		return LC_ERROR;
+	}
+
+	uint8_t *end_info_ptr;
+        err = GetTag("/INFORMATION", in, size, end_info_ptr);
+	if (err == -1) {
+		return LC_ERROR;
+	}
+
+	/*
+	 * Determine size of binary data following /INFORMATION
+	 */
+	uint32_t data_len = size - (end_info_ptr - in);
+	/*
+	 * Account for CRLF after /INFORMATION>
+	 * But, don't screw up if it's missing
+	 */
+	if (data_len >= 2) {
+		data_len -= 2;
+	}
+
+	/*
+	 * Search for tag only in "connectivity test" files
+	 */
+	bool found_get_zaps_only = false;
+	uint8_t *tmp_data = in;
+	uint32_t tmp_size = size - data_len;
+	while (1) {
+		uint8_t *tag_ptr;
+		string tag_s;
+		err = GetTag("KEY", tmp_data, tmp_size, tag_ptr, &tag_s);
+		if (err == -1) {
+			break;
+		}
+		if (!stricmp(tag_s.c_str(), "GETZAPSONLY")) {
+			found_get_zaps_only = true;
+			break;
+		}
+		tmp_data = tag_ptr + tag_s.length();
+		tmp_size = end_info_ptr - tmp_data;
+	}
+
+	/*
+	 * Search for tag only in "firmware" files
+	 */
+	bool found_firmware = false;
+	tmp_data = in;
+	tmp_size = size - data_len;
+	while (1) {
+		uint8_t *tag_ptr;
+		string tag_s;
+		err = GetTag("TYPE", tmp_data, tmp_size, tag_ptr, &tag_s);
+		if (err == -1) {
+			break;
+		}
+		if (!stricmp(tag_s.c_str(), "Firmware_Main")) {
+			found_firmware = true;
+			break;
+		}
+		tmp_data = tag_ptr + tag_s.length();
+		tmp_size = end_info_ptr - tmp_data;
+	}
+
+	/*
+	 * Search for tag only in "IR learning files.
+	 */
+	uint8_t *tag_ptr;
+	err = GetTag("CHECKKEYS", in, size - data_len, tag_ptr);
+	bool found_learn_ir = (err != -1);
+
+	/*
+	 * Check tag search results for consistency, and deduce the file type
+	 */
+	if (found_get_zaps_only && !data_len && !found_firmware &&
+		!found_learn_ir) {
+		*type = TYPE_CONNECTIVITY;
+		return 0;
+	}
+	if (!found_get_zaps_only && (data_len >= 16) && !found_firmware &&
+		!found_learn_ir) {
+		*type = TYPE_CONFIGURATION;
+		return 0;
+	}
+	if (!found_get_zaps_only && !data_len && found_firmware &&
+		!found_learn_ir) {
+		*type = TYPE_FIRMWARE;
+		return 0;
+	}
+	if (!found_get_zaps_only && !data_len && !found_firmware &&
+		found_learn_ir) {
+		*type = TYPE_LEARN_IR;
+		return 0;
+	}
+
+	/*
+	 * Findings didn't match a single file type; indicate a problem
+	 */
+	return LC_ERROR;
+}
+
 /*
  * Common routine to read contents of file named *file_name into
  * byte buffer **out. Get size from file and return out[size] 
Index: libconcord/libconcord.h
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.h,v
retrieving revision 1.16
diff -u -p -r1.16 libconcord.h
--- libconcord/libconcord.h	3 Apr 2008 07:01:46 -0000	1.16
+++ libconcord/libconcord.h	4 Apr 2008 04:25:41 -0000
@@ -156,6 +156,20 @@ const char *lc_strerror(int err);
 void delete_blob(uint8_t *ptr);
 
 /*
+ * Attempt to identify the action to perform to process the given file,
+ * given its content.
+ *
+ * The function will indicate whether the file could be identified using
+ * the return value. If the file can be identified, the type of the file
+ * will be written to *mode.
+ */
+#define TYPE_CONNECTIVITY  0
+#define TYPE_CONFIGURATION 1
+#define TYPE_FIRMWARE      2
+#define TYPE_LEARN_IR      3
+int identify_file(uint8_t *in, uint32_t size, int *type);
+
+/*
  * GENERAL REMOTE INTERACTIONS
  */
 
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to