Move the new files to the same places as in automake.
[obnox/wireshark/wip.git] / wiretap / k12text.l
index f3e9c94d42117f73ab9405bd39cd1666e9524181..867725231c25e064afea0d8e1c6ba49ad8e76b2d 100644 (file)
-%option noyywrap\r
-%option nounput \r
-%option outfile="k12text.c"\r
-%option prefix="K12Text_"\r
-%option never-interactive\r
-%{\r
-/* k12text.l\r
- *\r
- * $Id: $\r
- *\r
- * Wiretap Library\r
- * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- */\r
\r
- /* \r
-  * TODO:\r
-  *   - fix timestamps after midnight\r
-  *   - verify encapsulations\r
-  */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <errno.h>\r
-#include <time.h>\r
-#include "wtap-int.h"\r
-#include "wtap.h"\r
-#include "file_wrappers.h"\r
-#include "buffer.h"\r
-\r
-static guint h;\r
-static guint m;\r
-static guint s;\r
-static guint ms;\r
-static guint ns;\r
-static gint encap;\r
-static guint8 b[65536];\r
-static guint i;\r
-static gboolean is_k12text;\r
-static gboolean at_eof;\r
-static guint junk_chars = 0;\r
-static void finalize_frame(void);\r
-static gchar* error_str;\r
-static gint64 cum_offset;\r
-static gboolean ok_frame;\r
-static FILE_T yy_fh;\r
-\r
-#define RESET() do { ok_frame = FALSE; h=0; m=0; s=0; ns=0; ms=0; i=0; is_k12text=FALSE; junk_chars = 0; error_str = NULL; } while(0)\r
-\r
-#define KERROR(text) do { error_str = (text); yyterminate(); } while(0)\r
-#define START_PACKET RESET\r
-#define SET_HOURS(text) h = strtoul(text,NULL,10)\r
-#define SET_MINUTES(text) m = strtoul(text,NULL,10)\r
-#define SET_SECONDS(text) s = strtoul(text,NULL,10)\r
-#define SET_MS(text) ms = strtoul(text,NULL,10)\r
-#define SET_NS(text) ns = strtoul(text,NULL,10)\r
-#define SET_ENCAP(text) set_encap(text)\r
-#define ADD_BYTE(text) do {if (i >= 65536) {KERROR("frame too large");} b[i++] = (guint8)strtoul(text,NULL,16); } while(0)\r
-#define FINALIZE_FRAME() finalize_frame()\r
-//~ #define ECHO\r
-#define YY_USER_ACTION cum_offset += yyleng;\r
-#define YY_INPUT(buf,result,max_size) { int c = file_getc(yy_fh);  result = (c==EOF) ? YY_NULL : (buf[0] = c, 1); } \r
-\r
-#define MAX_JUNK 400000\r
-#define ECHO\r
-%}\r
-start_timestamp \053[\055]{9}\053[\055]{15,100}\053[\055]{10,100}\053\r
-oneormoredigits [0-9]+:\r
-twodigits [0-9][0-9]\r
-colon :\r
-comma ,\r
-threedigits [0-9][0-9][0-9]\r
-start_bytes \174\060\040\040\040\174\r
-bytes_junk \174[A-F0-9][A-F0-9\040][A-F0-9\040][A-F0-9\040]\174\r
-byte [a-f0-9][a-f0-9]\174\r
-end_bytes \015\012\015\012\r
-eth ETHER\r
-mtp2 MTP-L2\r
-sscop SSCOP\r
-sscfnni SSCF\r
-hdlc HDLC\r
-\r
-%START NEXT_FRAME HOURS H2M MINUTES M2S S2M MS M2N NS ENCAP STARTBYTES BYTE ENDBYTES MAGIC SECONDS\r
-%%\r
-<MAGIC>{start_timestamp}  { is_k12text = TRUE; yyterminate(); }\r
-\r
-<MAGIC>. { if (++ junk_chars > MAX_JUNK) { is_k12text = FALSE;  yyterminate(); } }\r
-\r
-<NEXT_FRAME>{start_timestamp} { START_PACKET(); BEGIN(HOURS); }\r
-<HOURS>{oneormoredigits} { SET_HOURS(yytext); BEGIN(MINUTES); }\r
-<MINUTES>{twodigits} { SET_MINUTES(yytext); BEGIN(M2S);}\r
-<M2S>{colon} { BEGIN(SECONDS);}\r
-<SECONDS>{twodigits} { SET_SECONDS(yytext); BEGIN(S2M); }\r
-<S2M>{comma}  { BEGIN(MS); }\r
-<MS>{threedigits} { SET_MS(yytext); BEGIN(M2N);  }\r
-<M2N>{comma}  { BEGIN(NS); }\r
-<NS>{threedigits} { SET_NS(yytext); BEGIN(ENCAP);}\r
-<ENCAP>{eth} {encap = WTAP_ENCAP_ETHERNET; BEGIN(STARTBYTES); }\r
-<ENCAP>{mtp2} {encap = WTAP_ENCAP_MTP2; BEGIN(STARTBYTES); }\r
-<ENCAP>{sscop} {encap = WTAP_ENCAP_ATM_PDUS; BEGIN(STARTBYTES); }\r
-<ENCAP>{sscfnni} {encap = WTAP_ENCAP_MTP3; BEGIN(STARTBYTES); }\r
-<ENCAP>{hdlc} {encap = WTAP_ENCAP_CHDLC; BEGIN(STARTBYTES); }\r
-<ENCAP,STARTBYTES>{start_bytes} { BEGIN(BYTE); }\r
-<BYTE>{byte} { ADD_BYTE(yytext); }\r
-<BYTE>{bytes_junk} ;\r
-<BYTE>{end_bytes} { FINALIZE_FRAME(); yyterminate(); }\r
-\r
-. {  if (++junk_chars > MAX_JUNK) { KERROR("too much junk");  } }\r
-<<EOF>> { at_eof = TRUE; yyterminate(); }\r
-\r
-%%\r
-\r
-static void finalize_frame(void) {\r
-       ok_frame = TRUE;\r
-}\r
-\r
-static gboolean k12text_read(wtap *wth, int *err, gchar **err_info _U_, gint64 *data_offset) {\r
-       gint64 start_offset = cum_offset;\r
-       \r
-       encap = WTAP_ENCAP_UNKNOWN;\r
-       ok_frame = FALSE;\r
-       \r
-       BEGIN(NEXT_FRAME);\r
-       yylex();\r
-       \r
-       if (ok_frame == FALSE) {\r
-               if (at_eof) {\r
-                       *err_info = NULL;\r
-                       *err = 0;\r
-               } else {\r
-                       *err_info = error_str;\r
-                       *err = WTAP_ERR_BAD_RECORD;\r
-               }\r
-               return FALSE;\r
-       }\r
-       \r
-       wth->data_offset = *data_offset = start_offset ;\r
-       \r
-       \r
-       wth->phdr.ts.secs = 946681200 + (3600*h) + (60*m) + s;\r
-       wth->phdr.ts.nsecs = 1000000*ms + 1000*ns;\r
-       \r
-       wth->phdr.caplen = wth->phdr.len = i;\r
-       \r
-       wth->phdr.pkt_encap = encap;\r
-       \r
-       buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);\r
-       memcpy(buffer_start_ptr(wth->frame_buffer), b, wth->phdr.caplen);\r
-\r
-       return TRUE;\r
-}\r
-\r
-static gboolean k12text_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err, gchar **err_info) {\r
-       gint64 save_offset = cum_offset;\r
-\r
-       ok_frame = FALSE;\r
-       RESET();\r
-\r
-       yy_fh = wth->random_fh;\r
-\r
-\r
-       if ( file_seek(yy_fh, seek_off, SEEK_SET, err) == -1) {\r
-               return FALSE;\r
-       }\r
-       \r
-       BEGIN(NEXT_FRAME);\r
-       yylex();\r
-\r
-       if (ok_frame == FALSE) {\r
-               *err_info = error_str;\r
-               *err = WTAP_ERR_BAD_RECORD;\r
-               return FALSE;\r
-       }\r
-               \r
-       memcpy(pd, b, length);\r
-\r
-       cum_offset = save_offset ;\r
-       return TRUE;\r
-}\r
-\r
-static void k12text_close(wtap *wth _U_) {\r
-       (void)0;\r
-}\r
-\r
-int k12text_open(wtap *wth, int *err, gchar **err_info _U_) {\r
-       \r
-       cum_offset = 0;\r
-       \r
-       RESET();\r
-       yy_fh = wth->fh;\r
-       BEGIN(MAGIC);\r
-       yylex();\r
-\r
-       if (! is_k12text) return 0;\r
-       \r
-       if ( file_seek(yy_fh, 0, SEEK_SET, err) == -1) {\r
-               return -1;\r
-       }\r
-\r
-       cum_offset = 0;\r
-\r
-       wth->data_offset = 0;\r
-       wth->file_type = WTAP_FILE_K12TEXT;\r
-       wth->file_encap = WTAP_ENCAP_PER_PACKET;\r
-       wth->snapshot_length = 0;\r
-       wth->subtype_read = k12text_read;\r
-       wth->subtype_seek_read = k12text_seek_read;\r
-       wth->subtype_close = k12text_close;\r
-       wth->capture.generic  = NULL;\r
-       wth->tsprecision = WTAP_FILE_TSPREC_NSEC;    \r
-\r
-       return 1;\r
-}\r
-\r
-\r
-static const struct { int e; const char* s; } encaps[] = {\r
-       { WTAP_ENCAP_ETHERNET, "ETHER" },\r
-       { WTAP_ENCAP_MTP2, "MTP-L2" },\r
-       { WTAP_ENCAP_ATM_PDUS, "SSCOP" },\r
-       { WTAP_ENCAP_MTP3, "SSCF" },\r
-       { WTAP_ENCAP_CHDLC, "HDLC" },\r
-       /* ... */\r
-       { WTAP_ENCAP_UNKNOWN, "UNKNOWN" },\r
-       { 0, NULL }\r
-};\r
-\r
-static gboolean k12text_dump(wtap_dumper *wdh _U_, const struct wtap_pkthdr *phdr,\r
-                         const union wtap_pseudo_header *pseudo_header _U_,\r
-                         const guchar *pd, int *err _U_) {\r
-       char buf[196808];\r
-       char* p=buf;\r
-       const char* str_enc;\r
-       guint i;\r
-       guint ns;\r
-       guint ms;\r
-       \r
-       ms = phdr->ts.nsecs / 1000000;\r
-       ns = (phdr->ts.nsecs - (1000000*ms))/1000;\r
-\r
-       for(i=0; encaps[i].s; i++) {\r
-               str_enc = encaps[i].s;\r
-               if (phdr->pkt_encap == encaps[i].e) break;\r
-       }\r
-       \r
-       strftime(p,90,"+---------+---------------+----------+\r\n%H:%M:%S,",gmtime(&phdr->ts.secs));\r
-       p+= strlen(p);\r
-       sprintf(p,"%.3d,%.3d   %s\r\n|0   |",ms,ns,str_enc);\r
-       p+= strlen(p);\r
-\r
-       for(i=0;i < phdr->caplen; i++) {\r
-               sprintf(p,"%.2x|",pd[i]);\r
-               p+= 3;\r
-       }\r
-       \r
-       sprintf(p,"\r\n\r\n");\r
-       \r
-       fwrite(buf, 1, strlen(buf), wdh->fh);\r
-       \r
-       return TRUE;\r
-}\r
-\r
-\r
-static gboolean k12text_dump_close(wtap_dumper *wdh, int *err) {\r
-       (void)0;\r
-       return TRUE;\r
-}\r
-\r
-gboolean k12text_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err) {\r
-    \r
-    if (cant_seek) {\r
-        *err = WTAP_ERR_CANT_WRITE_TO_PIPE;\r
-        return FALSE;\r
-    }\r
-    \r
-    wdh->subtype_write = k12text_dump;\r
-    wdh->subtype_close = k12text_dump_close;\r
-\r
-    return TRUE;\r
-}\r
-\r
-int k12text_dump_can_write_encap(int encap) {\r
-    switch (encap) {\r
-       case WTAP_ENCAP_PER_PACKET:\r
-       case WTAP_ENCAP_ETHERNET:\r
-       case WTAP_ENCAP_MTP2:\r
-       case WTAP_ENCAP_ATM_PDUS:\r
-       case WTAP_ENCAP_MTP3:\r
-       case WTAP_ENCAP_CHDLC:\r
-       case WTAP_ENCAP_UNKNOWN:\r
-               return 0;\r
-       default:\r
-               return WTAP_ERR_UNSUPPORTED_ENCAP;\r
-    }\r
-}
\ No newline at end of file
+/*
+ * We don't use unput, so don't generate code for it.
+ */
+%option nounput
+
+/*
+ * We don't read from the terminal.
+ */
+%option never-interactive
+
+/*
+ * Prefix scanner routines with "K12Text_" rather than "yy", so this scanner
+ * can coexist with other scanners.
+ */
+%option prefix="K12Text_"
+
+%option outfile="k12text.c"
+
+/* Options useful for debugging                                */
+/* noline:  Prevent generation of #line directives     */
+/*         Seems to be required when using the         */
+/*         Windows VS debugger so as to be able        */
+/*         to properly step through the code and       */
+/*         set breakpoints & etc using the             */
+/*         k12text.c file rather than the              */
+/*         k12text.l file                              */
+/*     XXX: %option noline gives an error message:     */
+/*         "unrecognized %option: line"                */
+/*         with flex 2.5.35; the --noline              */
+/*         command-line option works OK.               */
+/*                                                     */
+/* debug:   Do output of "rule acceptance" info                */
+/*         during parse                                */
+/*                                                     */
+/* %option noline  */
+/* %option debug   */
+
+%{
+/* k12text.l
+ *
+ * $Id$
+ *
+ * Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+ /*
+  * TODO:
+  *   - fix timestamps after midnight
+  *   - verify encapsulations
+  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include "wtap-int.h"
+#include "wtap.h"
+#include "file_wrappers.h"
+#include "buffer.h"
+#include "k12.h"
+#include "k12text_lex.h"
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+static guint g_h;
+static guint g_m;
+static guint g_s;
+static guint g_ms;
+static guint g_ns;
+static gint g_encap;
+static guint8 bb[WTAP_MAX_PACKET_SIZE];
+static guint ii;
+static gboolean is_k12text;
+static gboolean at_eof;
+static guint junk_chars;
+static void finalize_frame(void);
+static gchar* error_str;
+static guint file_bytes_read;
+static gboolean ok_frame;
+static FILE_T yy_fh;
+
+#define KERROR(text) do { error_str = g_strdup(text); yyterminate(); } while(0)
+#define SET_HOURS(text) g_h = strtoul(text,NULL,10)
+#define SET_MINUTES(text) g_m = strtoul(text,NULL,10)
+#define SET_SECONDS(text) g_s = strtoul(text,NULL,10)
+#define SET_MS(text) g_ms = strtoul(text,NULL,10)
+#define SET_NS(text) g_ns = strtoul(text,NULL,10)
+#define ADD_BYTE(text) do {if (ii >= WTAP_MAX_PACKET_SIZE) {KERROR("frame too large");} bb[ii++] = (guint8)strtoul(text,NULL,16); } while(0)
+#define FINALIZE_FRAME() finalize_frame()
+/*~ #define ECHO*/
+#define YY_USER_ACTION file_bytes_read += yyleng;
+#define YY_INPUT(buf,result,max_size) { int c = file_getc(yy_fh);  result = (c==EOF) ? YY_NULL : (buf[0] = c, 1); }
+
+#define MAX_JUNK 400000
+#define ECHO
+%}
+start_timestamp \053[\055]{9}\053[\055]{15,100}\053[\055]{10,100}\053
+oneormoredigits [0-9]+:
+twodigits [0-9][0-9]
+colon :
+comma ,
+threedigits [0-9][0-9][0-9]
+start_bytes \174\060\040\040\040\174
+bytes_junk \174[A-F0-9][A-F0-9\040][A-F0-9\040][A-F0-9\040]\174
+byte [a-f0-9][a-f0-9]\174
+end_bytes \015?\012\015?\012
+eth ETHER
+ /* mtp2 MTP-L2 ;; XXX: Not supported until it's determined how to fill in the pseudo_header req'd by packet-mtp2 */
+ /* sscop SSCOP ;; XXX: Not supported until it's determined how to fill in the pseudo_header req'd by packet-atm  */
+sscfnni SSCF
+hdlc HDLC
+
+%START MAGIC NEXT_FRAME HOURS MINUTES M2S SECONDS S2M MS M2N NS ENCAP STARTBYTES BYTE
+%%
+<MAGIC>{start_timestamp}  { is_k12text = TRUE; yyterminate(); }
+
+<MAGIC>. { if (++ junk_chars > MAX_JUNK) { is_k12text = FALSE;  yyterminate(); } }
+
+<NEXT_FRAME>{start_timestamp} {BEGIN(HOURS); }
+<HOURS>{oneormoredigits} { SET_HOURS(yytext); BEGIN(MINUTES); }
+<MINUTES>{twodigits} { SET_MINUTES(yytext); BEGIN(M2S);}
+<M2S>{colon} { BEGIN(SECONDS);}
+<SECONDS>{twodigits} { SET_SECONDS(yytext); BEGIN(S2M); }
+<S2M>{comma}  { BEGIN(MS); }
+<MS>{threedigits} { SET_MS(yytext); BEGIN(M2N);  }
+<M2N>{comma}  { BEGIN(NS); }
+<NS>{threedigits} { SET_NS(yytext); BEGIN(ENCAP);}
+<ENCAP>{eth} {g_encap = WTAP_ENCAP_ETHERNET; BEGIN(STARTBYTES); }
+ /* <ENCAP>{mtp2} {g_encap = WTAP_ENCAP_MTP2; BEGIN(STARTBYTES); }      Not supported as yet */
+ /* <ENCAP>{sscop} {g_encap = WTAP_ENCAP_ATM_PDUS; BEGIN(STARTBYTES); } Not supported as yet */
+<ENCAP>{sscfnni} {g_encap = WTAP_ENCAP_MTP3; BEGIN(STARTBYTES); }
+<ENCAP>{hdlc} {g_encap = WTAP_ENCAP_CHDLC; BEGIN(STARTBYTES); }
+<ENCAP,STARTBYTES>{start_bytes} { BEGIN(BYTE); }
+<BYTE>{byte} { ADD_BYTE(yytext); }
+<BYTE>{bytes_junk} ;
+<BYTE>{end_bytes} { FINALIZE_FRAME(); yyterminate(); }
+
+. {  if (++junk_chars > MAX_JUNK) { KERROR("too much junk");  } }
+<<EOF>> { at_eof = TRUE; yyterminate(); }
+
+%%
+
+static void finalize_frame(void) {
+       ok_frame = TRUE;
+}
+
+/* Fill in pseudo-header according to the encapsulation type   */
+
+static void
+k12text_set_pseudo_header(gint encap, union wtap_pseudo_header *pseudo_header)
+{
+       /* The file-encap is WTAP_ENCAP_PER_PACKET */
+       switch(encap) {
+           case WTAP_ENCAP_ETHERNET:
+                   pseudo_header->eth.fcs_len = 0;
+                   break;
+           case WTAP_ENCAP_MTP3:
+           case WTAP_ENCAP_CHDLC:
+                   /* no pseudo_header to fill in for these types */
+                   break;
+#if 0
+           case WTAP_ENCAP_MTP2:      /* not (yet) supported           */
+           case WTAP_ENCAP_ATM_PDUS:  /* not (yet) supported           */
+                   /* XXX: I don't know how to fill in the             */
+                   /* pseudo_header for these types. So: The Lexer     */
+                   /* has recognition for these types commented        */
+                   /* out ....                                         */
+                   break;
+#endif
+           default:
+                   break;
+       }
+}
+
+/* Note: k12text_reset is called each time data is to be processed from        */
+/*       a file. This ensures that no "state" from a previous read is  */
+/*       used (such as the lexer look-ahead buffer, file_handle, file  */
+/*       position and so on. This allows a single lexer buffer to be   */
+/*       used even when multiple files are open simultaneously (as for */
+/*       a file merge).                                                        */
+
+static void
+k12text_reset(FILE_T fh)
+{
+       yy_fh = fh;
+       yyrestart(0);
+       g_encap = WTAP_ENCAP_UNKNOWN;
+       ok_frame = FALSE;
+       is_k12text = FALSE;
+       at_eof = FALSE;
+       junk_chars = 0;
+       error_str = NULL;
+       file_bytes_read=0;
+       g_h=0;
+       g_m=0;
+       g_s=0;
+       g_ns=0;
+       g_ms=0;
+       ii=0;
+}
+
+static gboolean
+k12text_read(wtap *wth, int *err, char ** err_info, gint64 *data_offset)
+{
+
+       /* We seek to the file position after the end of the previous frame processed by                */
+       /* k12text_read (kept in wth->data_offset). We do this each time since the lexer                */
+       /* undoubtedly did some amount of look-ahead when processing the previous frame.                */
+       /* We also clear out any lexer state (eg: look-ahead buffer) and init vars set by lexer.        */
+
+       if ( file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
+               return FALSE;
+       }
+       k12text_reset(wth->fh);         /* init lexer buffer and vars set by lexer */
+
+       BEGIN(NEXT_FRAME);
+       yylex();
+
+       if (ok_frame == FALSE) {
+               if (at_eof) {
+                       *err = 0;
+                       *err_info = NULL;
+               } else {
+                       *err = WTAP_ERR_BAD_FILE;
+                       *err_info = error_str;
+               }
+               return FALSE;
+       }
+
+       *data_offset = wth->data_offset;       /* file position for beginning of this frame   */
+       wth->data_offset += file_bytes_read;   /* file position after end of this frame       */
+
+       wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
+
+       wth->phdr.ts.secs = 946681200 + (3600*g_h) + (60*g_m) + g_s;
+       wth->phdr.ts.nsecs = 1000000*g_ms + 1000*g_ns;
+
+       wth->phdr.caplen = wth->phdr.len = ii;
+
+       wth->phdr.pkt_encap = g_encap;
+       k12text_set_pseudo_header(g_encap, &wth->pseudo_header);
+
+       buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
+       memcpy(buffer_start_ptr(wth->frame_buffer), bb, wth->phdr.caplen);
+
+       return TRUE;
+}
+
+static gboolean
+k12text_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int length, int *err, char **err_info)
+{
+
+       if ( file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) {
+               return FALSE;
+       }
+       k12text_reset(wth->random_fh);          /* init lexer buffer and vars set by lexer */
+
+       BEGIN(NEXT_FRAME);
+       yylex();
+
+       if (ok_frame == FALSE) {
+               *err = WTAP_ERR_BAD_FILE;
+               if (at_eof) {
+                       /* What happened ? The desired frame was previously read without a problem */
+                       *err_info = g_strdup("Unexpected EOF (program error ?)");
+               } else {
+                       *err_info = error_str;
+               }
+               return FALSE;
+       }
+
+       /* verify frame length parsed this time against original frame length */
+       if (ii != (guint)length) {
+               /* What happened ? This now seems to have a different length than originally */
+               *err = WTAP_ERR_BAD_FILE;
+               *err_info = g_strdup("Incorrect frame length (program error ?)");
+               return FALSE;
+       }
+
+       k12text_set_pseudo_header(g_encap, pseudo_header);
+
+       memcpy(pd, bb, length);
+
+       return TRUE;
+}
+
+int
+k12text_open(wtap *wth, int *err, gchar **err_info _U_)
+{
+
+       k12text_reset(wth->fh);       /* init lexer buffer and vars set by lexer */
+
+       BEGIN(MAGIC);
+       yylex();
+
+       if (! is_k12text) return 0;
+
+       if ( file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
+               return -1;
+       }
+
+       wth->data_offset = 0;
+       wth->file_type = WTAP_FILE_K12TEXT;
+       wth->file_encap = WTAP_ENCAP_PER_PACKET;
+       wth->snapshot_length = 0;
+       wth->subtype_read = k12text_read;
+       wth->subtype_seek_read = k12text_seek_read;
+       wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
+
+       return 1;
+}
+
+
+static const struct { int e; const char* s; } encaps[] = {
+       { WTAP_ENCAP_ETHERNET, "ETHER" },
+       { WTAP_ENCAP_MTP2, "MTP-L2" },
+       { WTAP_ENCAP_ATM_PDUS, "SSCOP" },
+       { WTAP_ENCAP_MTP3, "SSCF" },
+       { WTAP_ENCAP_CHDLC, "HDLC" },
+       /* ... */
+       { 0, NULL }
+};
+
+static gboolean
+k12text_dump(wtap_dumper *wdh _U_, const struct wtap_pkthdr *phdr,
+            const union wtap_pseudo_header *pseudo_header _U_,
+            const guint8 *pd, int *err) {
+#define K12BUF_SIZE 196808
+       char *buf;
+       size_t left = K12BUF_SIZE;
+       gint wl;
+       char *p;
+       const char* str_enc;
+       guint i;
+       guint ns;
+       guint ms;
+       gboolean ret;
+
+       str_enc = NULL;
+       for(i=0; encaps[i].s; i++) {
+               if (phdr->pkt_encap == encaps[i].e) {
+                       str_enc = encaps[i].s;
+                       break;
+               }
+       }
+       if (str_enc == NULL) {
+               /*
+                * That encapsulation type is not supported.  Fail.
+                */
+               *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+               return FALSE;
+       }
+
+       buf = g_malloc(K12BUF_SIZE);
+       p = buf;
+
+       ms = phdr->ts.nsecs / 1000000;
+       ns = (phdr->ts.nsecs - (1000000*ms))/1000;
+
+#ifdef _MSC_VER
+       /* calling gmtime() on MSVC 2005 with huge values causes it to crash */
+       /* XXX - find the exact value that still does work */
+       /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
+       if (phdr->ts.secs > 2000000000)
+               g_snprintf(p, 90, "+---------+---------------+----------+\r\nXX:XX:XX,");
+       else
+#endif
+       strftime(p, 90, "+---------+---------------+----------+\r\n%H:%M:%S,",
+                gmtime(&phdr->ts.secs));
+       wl = strlen(p);
+       p += wl;
+       left -= wl;
+
+       wl = g_snprintf(p, left, "%.3d,%.3d   %s\r\n|0   |", ms, ns, str_enc);
+       p += wl;
+       left -= wl;
+
+       for(i = 0; i < phdr->caplen && left > 2; i++) {
+               wl = g_snprintf(p, left, "%.2x|", pd[i]);
+               p += wl;
+               left -= wl;
+       }
+
+       wl = g_snprintf(p, left, "\r\n\r\n");
+       left -= wl;
+
+       ret = wtap_dump_file_write(wdh, buf, K12BUF_SIZE - left, err);
+
+       g_free(buf);
+       return ret;
+}
+
+
+gboolean
+k12text_dump_open(wtap_dumper *wdh, int *err _U_)
+{
+    wdh->subtype_write = k12text_dump;
+
+    return TRUE;
+}
+
+int
+k12text_dump_can_write_encap(int encap)
+{
+    switch (encap) {
+       case WTAP_ENCAP_PER_PACKET:
+       case WTAP_ENCAP_ETHERNET:
+       case WTAP_ENCAP_MTP3:
+       case WTAP_ENCAP_CHDLC:
+               return 0;
+       case WTAP_ENCAP_MTP2:
+       case WTAP_ENCAP_ATM_PDUS:
+       default:
+               return WTAP_ERR_UNSUPPORTED_ENCAP;
+    }
+}
+
+/*
+ * We want to stop processing when we get to the end of the input.
+ * (%option noyywrap is not used because if used then
+ * some flex versions (eg: 2.5.35) generate code which causes
+ * warnings by the Windows VC compiler).
+ */
+
+int yywrap(void) {
+    return 1;
+}