-s <skip> feature


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@983 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/ChangeLog b/ChangeLog
index 4c9cef7..540af62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@
 	* Test cases 73 & 92 keep track of various circular references.
 	* Introduced compiler directives to allow finer control over the
 	  generated code ("--<ASN1C...>--" in comments), (Test case 93).
+	* New feature for unber(1): -s <skip> bytes.
 
 0.9.18:	2005-Aug-14
 
diff --git a/asn1c/unber.1 b/asn1c/unber.1
index e219df9..9055da8 100644
--- a/asn1c/unber.1
+++ b/asn1c/unber.1
@@ -12,7 +12,7 @@
 .SH NAME
 unber \- ASN.1 BER Decoder
 .SH SYNOPSIS
-unber [\fB-1\fR] [\fB-i\fRindent] [\fB-m\fR] [\fB-p\fR] [\fB\-t\fR\fIdata-string\fR] [\fB-\fR] [\fIinfile\fR...]
+unber [\fB-1\fR] [\fB-i\fRindent] [\fB-m\fR] [\fB-p\fR] [\fB\-s\fR\fIskip\fR] [\fB\-t\fR\fIhex-string\fR] [\fB-\fR] [\fIinfile\fR...]
 .SH DESCRIPTION
 unber takes the BER-encoded files and dumps their internal structure as human readable text.
 A single dash represents the standard input.
@@ -32,11 +32,15 @@
 Generate minimum amount of output while still preserving BER encoding information.
 .TP
 \fB\-p\fR
-Do \fInot\fR attempt pretty-printing of known ASN.1 types (OBJECT IDENTIFIER, INTEGER, BOOLEAN, etc). By default, some ASN.1 types are converted into
+Do \fInot\fR attempt pretty-printing of known ASN.1 types (BOOLEAN, INTEGER, OBJECT IDENTIFIER, etc). By default, some ASN.1 types are converted into
 the text representation. This option is required for \&\fIenber\fR\|(1).
 .TP
-\fB\-t\fR \fIdata-string\fR
-Interpret the data-string as a sequence of hexadecimal values representing
+\fB\-s\fR \fIskip\fR
+Ignore the first \fIskip\fR bytes in the input stream; useful for stripping off
+lower level protocol framing data.
+.TP
+\fB\-t\fR \fIhex-string\fR
+Interpret the hex-string as a sequence of hexadecimal values representing
 the start of BER TLV encoding. Print the human readable explanation.
 .SH XML FORMAT
 unber dumps the output in the regular XML format which preserves most of the
diff --git a/asn1c/unber.c b/asn1c/unber.c
index 5768a58..c573cfd 100644
--- a/asn1c/unber.c
+++ b/asn1c/unber.c
@@ -47,6 +47,7 @@
 static int single_type_decoding = 0;	/* -1 enables that */
 static int minimalistic = 0;		/* -m enables that */
 static int pretty_printing = 1;		/* -p disables that */
+static int skip_bytes = 0;		/* -s controls that */
 static char *indent_buffer = "    ";	/* -i controls that */
 
 int
@@ -57,21 +58,11 @@
 	/*
 	 * Process command-line options.
 	 */
-	while((ch = getopt(ac, av, "1hi:mpt:v")) != -1)
+	while((ch = getopt(ac, av, "1hi:mps:t:v")) != -1)
 	switch(ch) {
 	case '1':
 		single_type_decoding = 1;
 		break;
-	case 't':
-		if(decode_tlv_from_string(optarg))
-			exit(EX_DATAERR);
-		exit(0);
-	case 'm':
-		minimalistic = 1;
-		break;
-	case 'p':
-		pretty_printing = 0;
-		break;
 	case 'i':
 		i = atoi(optarg);
 		if(i >= 0 && i < 16) {
@@ -83,6 +74,24 @@
 			exit(EX_USAGE);
 		}
 		break;
+	case 'm':
+		minimalistic = 1;
+		break;
+	case 'p':
+		pretty_printing = 0;
+		break;
+	case 's':
+		skip_bytes = atoi(optarg);
+		if(skip_bytes < 0) {
+			fprintf(stderr, "-s %s: positive value expected\n",
+				optarg);
+			exit(EX_USAGE);
+		}
+		break;
+	case 't':
+		if(decode_tlv_from_string(optarg))
+			exit(EX_DATAERR);
+		exit(0);
 	case 'v':
 		fprintf(stderr, "ASN.1 BER Decoder, v" VERSION "\n" COPYRIGHT);
 		exit(0);
@@ -126,11 +135,12 @@
 "ASN.1 BER Decoder, v" VERSION "\n" COPYRIGHT
 "Usage: %s [options] [-] [file ...]\n"
 "Options:\n"
-"  -1                 Decode only the first BER structure (otherwise, until EOF)\n"
-"  -i <indent>        Amount of spaces for output indentation (default is 4)\n"
-"  -m                 Minimalistic mode: print as little as possible\n"
-"  -p                 Do not attempt pretty-printing of known ASN.1 types\n"
-"  -t <data-string>   Decode the given tag[/length] sequence (e.g. -t \"bf20\")\n"
+"  -1                Decode only the first BER structure (otherwise, until EOF)\n"
+"  -i <indent>       Amount of spaces for output indentation (default is 4)\n"
+"  -m                Minimalistic mode: print as little as possible\n"
+"  -p                Do not attempt pretty-printing of known ASN.1 types\n"
+"  -s <skip>         Ignore first <skip> bytes of input\n"
+"  -t <hex-string>   Decode the given tag[/length] sequence (e.g. -t \"bf20\")\n"
 "\n"
 "The XML opening tag format is as follows:\n"
 "  <tform O=\"off\" T=\"tag\" TL=\"tl_len\" V=\"{Indefinite|v_len}\" [A=\"type\"] [F]>\n"
@@ -177,6 +187,21 @@
 	}
 
 	/*
+	 * Skip the requested amount of bytes.
+	 */
+	for(; offset < skip_bytes; offset++) {
+		if(fgetc(fp) == -1) {
+			fprintf(stderr,
+				"%s: input source (%" PRIdASN " bytes) "
+				"has less data than \"-s %d\" switch "
+				"wants to skip\n",
+				fname, offset, skip_bytes);
+			if(fp != stdin) fclose(fp);
+			return -1;
+		}
+	}
+
+	/*
 	 * Fetch out BER-encoded data until EOF or error.
 	 */
 	do {
@@ -205,7 +230,7 @@
 	ssize_t t_len;
 	ssize_t l_len;
 
-	do {
+	for(;;) {
 		ber_tlv_len_t local_esize = 0;
 		int constr;
 		int ch;
@@ -348,7 +373,11 @@
 			 tlv_tag, tlv_len, local_esize);
 
 		tblen = 0;
-	} while(1);
+
+		/* Report success for a single top level TLV */
+		if(level == 0 && limit == -1 && !expect_eoc)
+			break;
+	} /* for(;;) */
 
 	return pdc;
 }