Remove Nmake build system
[metze/wireshark/wip.git] / wiretap / vms.c
index 56ae0c378e664755ffa8d61294439387dec2042f..e9fc9a423a86e46066cc46680e09550a51be60d1 100644 (file)
@@ -1,6 +1,4 @@
 /* vms.c
- *
- * $Id$
  *
  * Wiretap Library
  * Copyright (c) 2001 by Marc Milgram <ethereal@mmilgram.NOSPAMmail.net>
  */
 #include "config.h"
 #include "wtap-int.h"
-#include "buffer.h"
 #include "vms.h"
 #include "file_wrappers.h"
 
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 
 /* This module reads the output of the various VMS TCPIP trace utilities
  * such as TCPIPTRACE, TCPTRACE and UCX$TRACE
@@ -119,7 +114,7 @@ Format 2:
 
  ... packet seq # = nn at DD-MMM-YYYY hh:mm:ss.ss
 
-If there are other formats then code will have to be written in parse_vms_rec_hdr()
+If there are other formats then code will have to be written in parse_vms_packet()
 to handle them.
 
 --------------------------------------------------------------------------------
@@ -129,14 +124,14 @@ to handle them.
 /* Magic text to check for VMS-ness of file using possible utility names
  *
  */
-#define VMS_HDR_MAGIC_STR1     "TCPIPtrace"
-#define VMS_HDR_MAGIC_STR2     "TCPtrace"
-#define VMS_HDR_MAGIC_STR3     "INTERnet trace"
+#define VMS_HDR_MAGIC_STR1      "TCPIPtrace"
+#define VMS_HDR_MAGIC_STR2      "TCPtrace"
+#define VMS_HDR_MAGIC_STR3      "INTERnet trace"
 
 /* Magic text for start of packet */
-#define VMS_REC_MAGIC_STR1     VMS_HDR_MAGIC_STR1
-#define VMS_REC_MAGIC_STR2     VMS_HDR_MAGIC_STR2
-#define VMS_REC_MAGIC_STR3     VMS_HDR_MAGIC_STR3
+#define VMS_REC_MAGIC_STR1      VMS_HDR_MAGIC_STR1
+#define VMS_REC_MAGIC_STR2      VMS_HDR_MAGIC_STR2
+#define VMS_REC_MAGIC_STR3      VMS_HDR_MAGIC_STR3
 
 #define VMS_HEADER_LINES_TO_CHECK    200
 #define VMS_LINE_LENGTH              240
@@ -144,14 +139,11 @@ to handle them.
 static gboolean vms_read(wtap *wth, int *err, gchar **err_info,
     gint64 *data_offset);
 static gboolean vms_seek_read(wtap *wth, gint64 seek_off,
-    struct wtap_pkthdr *phdr, guint8 *pd, int len,
-    int *err, gchar **err_info);
+    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
 static gboolean parse_single_hex_dump_line(char* rec, guint8 *buf,
     long byte_offset, int in_off, int remaining_bytes);
-static gboolean parse_vms_hex_dump(FILE_T fh, int pkt_len, guint8* buf,
-    int *err, gchar **err_info);
-static gboolean parse_vms_rec_hdr(FILE_T fh, struct wtap_pkthdr *phdr,
-    int *err, gchar **err_info);
+static gboolean parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr,
+    Buffer *buf, int *err, gchar **err_info);
 
 #ifdef TCPIPTRACE_FRAGMENTS_HAVE_HEADER_LINE
 /* Seeks to the beginning of the next packet, and returns the
@@ -240,23 +232,23 @@ static gboolean vms_check_file_type(wtap *wth, int *err, gchar **err_info)
 }
 
 
-int vms_open(wtap *wth, int *err, gchar **err_info)
+wtap_open_return_val vms_open(wtap *wth, int *err, gchar **err_info)
 {
     /* Look for VMS header */
     if (!vms_check_file_type(wth, err, err_info)) {
         if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
-            return -1;
-        return 0;
+            return WTAP_OPEN_ERROR;
+        return WTAP_OPEN_NOT_MINE;
     }
 
     wth->file_encap = WTAP_ENCAP_RAW_IP;
-    wth->file_type = WTAP_FILE_VMS;
+    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_VMS;
     wth->snapshot_length = 0; /* not known */
     wth->subtype_read = vms_read;
     wth->subtype_seek_read = vms_seek_read;
-    wth->tsprecision = WTAP_FILE_TSPREC_CSEC;
+    wth->file_tsprec = WTAP_TSPREC_CSEC;
 
-    return 1;
+    return WTAP_OPEN_MINE;
 }
 
 /* Find the next packet and parse it; called from wtap_read(). */
@@ -264,7 +256,6 @@ static gboolean vms_read(wtap *wth, int *err, gchar **err_info,
     gint64 *data_offset)
 {
     gint64   offset = 0;
-    guint8    *buf;
 
     /* Find the next packet */
 #ifdef TCPIPTRACE_FRAGMENTS_HAVE_HEADER_LINE
@@ -276,42 +267,26 @@ static gboolean vms_read(wtap *wth, int *err, gchar **err_info,
         *err = file_error(wth->fh, err_info);
         return FALSE;
     }
-
-    /* Parse the header */
-    if (!parse_vms_rec_hdr(wth->fh, &wth->phdr, err, err_info))
-       return FALSE;
-
-    /* Make sure we have enough room for the packet */
-    buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
-    buf = buffer_start_ptr(wth->frame_buffer);
-
-    /* Convert the ASCII hex dump to binary data */
-    if (!parse_vms_hex_dump(wth->fh, wth->phdr.caplen, buf, err, err_info))
-        return FALSE;
-
     *data_offset = offset;
-    return TRUE;
+
+    /* Parse the packet */
+    return parse_vms_packet(wth->fh, &wth->phdr, wth->frame_buffer, err, err_info);
 }
 
 /* Used to read packets in random-access fashion */
 static gboolean
-vms_seek_read (wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
-    guint8 *pd, int len, int *err, gchar **err_info)
+vms_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
+    Buffer *buf, int *err, gchar **err_info)
 {
     if (file_seek(wth->random_fh, seek_off - 1, SEEK_SET, err) == -1)
         return FALSE;
 
-    if (!parse_vms_rec_hdr(wth->random_fh, phdr, err, err_info))
-        return FALSE;
-
-    if (phdr->caplen != (guint32)len) {
-        *err = WTAP_ERR_BAD_FILE;
-        *err_info = g_strdup_printf("vms: requested length %d doesn't match length %d",
-            len, phdr->caplen);
+    if (!parse_vms_packet(wth->random_fh, phdr, buf, err, err_info)) {
+        if (*err == 0)
+            *err = WTAP_ERR_SHORT_READ;
         return FALSE;
     }
-
-    return parse_vms_hex_dump(wth->random_fh, phdr->caplen, pd, err, err_info);
+    return TRUE;
 }
 
 /* isdumpline assumes that dump lines start with some non-alphanumerics
@@ -323,35 +298,38 @@ isdumpline( gchar *line )
 {
     int i, j;
 
-    while (*line && !isalnum((guchar)*line))
-       line++;
+    while (*line && !g_ascii_isalnum(*line))
+        line++;
 
     for (j=0; j<4; j++) {
-       for (i=0; i<8; i++, line++)
-           if (! isxdigit((guchar)*line))
-               return FALSE;
+        for (i=0; i<8; i++, line++)
+            if (! g_ascii_isxdigit(*line))
+                return FALSE;
 
-       for (i=0; i<3; i++, line++)
-           if (*line != ' ')
-               return FALSE;
+        for (i=0; i<3; i++, line++)
+            if (*line != ' ')
+                return FALSE;
     }
 
-    return isspace((guchar)*line);
+    return g_ascii_isspace(*line);
 }
 
-/* Parses a packet record header. */
+/* Parses a packet record. */
 static gboolean
-parse_vms_rec_hdr(FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_info)
+parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
 {
     char   line[VMS_LINE_LENGTH + 1];
     int    num_items_scanned;
-    int           pkt_len = 0;
-    int           pktnum;
-    int           csec = 101;
+    int    pkt_len = 0;
+    int    pktnum;
+    int    csec = 101;
     struct tm tm;
     char mon[4] = {'J', 'A', 'N', 0};
     gchar *p;
     static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
+    int    i;
+    int    offset = 0;
+    guint8 *pd;
 
     tm.tm_year = 1970;
     tm.tm_mon = 0;
@@ -364,54 +342,65 @@ parse_vms_rec_hdr(FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_inf
     do {
         if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
             *err = file_error(fh, err_info);
-           if ((*err == 0) && (csec != 101)) {
-               *err = WTAP_ERR_SHORT_READ;
+            if ((*err == 0) && (csec != 101)) {
+                *err = WTAP_ERR_SHORT_READ;
             }
             return FALSE;
         }
-       line[VMS_LINE_LENGTH] = '\0';
-
-       if ((csec == 101) && (p = strstr(line, "packet ")) != NULL
-           && (! strstr(line, "could not save "))) {
-           /* Find text in line starting with "packet ". */
-
-           /* First look for the Format 1 type sequencing */
-           num_items_scanned = sscanf(p,
-                                      "packet %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
-                                      &pktnum, &tm.tm_mday, mon,
-                                      &tm.tm_year, &tm.tm_hour,
-                                      &tm.tm_min, &tm.tm_sec, &csec);
-           /* Next look for the Format 2 type sequencing */
-           if (num_items_scanned != 8) {
-             num_items_scanned = sscanf(p,
-                                        "packet seq # = %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
-                                        &pktnum, &tm.tm_mday, mon,
-                                        &tm.tm_year, &tm.tm_hour,
-                                        &tm.tm_min, &tm.tm_sec, &csec);
-           }
-           /* if unknown format then exit with error        */
-           /* We will need to add code to handle new format */
-           if (num_items_scanned != 8) {
-               *err = WTAP_ERR_BAD_FILE;
-               *err_info = g_strdup_printf("vms: header line not valid");
-               return FALSE;
-           }
-       }
+        line[VMS_LINE_LENGTH] = '\0';
+
+        if ((csec == 101) && (p = strstr(line, "packet ")) != NULL
+            && (! strstr(line, "could not save "))) {
+            /* Find text in line starting with "packet ". */
+
+            /* First look for the Format 1 type sequencing */
+            num_items_scanned = sscanf(p,
+                                       "packet %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
+                                       &pktnum, &tm.tm_mday, mon,
+                                       &tm.tm_year, &tm.tm_hour,
+                                       &tm.tm_min, &tm.tm_sec, &csec);
+            /* Next look for the Format 2 type sequencing */
+            if (num_items_scanned != 8) {
+              num_items_scanned = sscanf(p,
+                                         "packet seq # = %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
+                                         &pktnum, &tm.tm_mday, mon,
+                                         &tm.tm_year, &tm.tm_hour,
+                                         &tm.tm_min, &tm.tm_sec, &csec);
+            }
+            /* if unknown format then exit with error        */
+            /* We will need to add code to handle new format */
+            if (num_items_scanned != 8) {
+                *err = WTAP_ERR_BAD_FILE;
+                *err_info = g_strdup("vms: header line not valid");
+                return FALSE;
+            }
+        }
         if ( (! pkt_len) && (p = strstr(line, "Length"))) {
             p += sizeof("Length ");
-            while (*p && ! isdigit((guchar)*p))
+            while (*p && ! g_ascii_isdigit(*p))
                 p++;
 
             if ( !*p ) {
                 *err = WTAP_ERR_BAD_FILE;
-               *err_info = g_strdup_printf("vms: Length field not valid");
+                *err_info = g_strdup("vms: Length field not valid");
                 return FALSE;
             }
 
             pkt_len = atoi(p);
-           break;
+            break;
         }
     } while (! isdumpline(line));
+    if (pkt_len > WTAP_MAX_PACKET_SIZE) {
+        /*
+         * Probably a corrupt capture file; return an error,
+         * so that our caller doesn't blow up trying to allocate
+         * space for an immensely-large packet.
+         */
+        *err = WTAP_ERR_BAD_FILE;
+        *err_info = g_strdup_printf("vms: File has %u-byte packet, bigger than maximum of %u",
+                                    pkt_len, WTAP_MAX_PACKET_SIZE);
+        return FALSE;
+    }
 
     p = strstr(months, mon);
     if (p)
@@ -419,24 +408,18 @@ parse_vms_rec_hdr(FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_inf
     tm.tm_year -= 1900;
     tm.tm_isdst = -1;
 
+    phdr->rec_type = REC_TYPE_PACKET;
     phdr->presence_flags = WTAP_HAS_TS;
     phdr->ts.secs = mktime(&tm);
     phdr->ts.nsecs = csec * 10000000;
     phdr->caplen = pkt_len;
     phdr->len = pkt_len;
 
-    return TRUE;
-}
-
-/* Converts ASCII hex dump to binary data */
-static gboolean
-parse_vms_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err,
-    gchar **err_info)
-{
-    gchar line[VMS_LINE_LENGTH + 1];
-    int    i;
-    int    offset = 0;
+    /* Make sure we have enough room for the packet */
+    ws_buffer_assure_space(buf, pkt_len);
+    pd = ws_buffer_start_ptr(buf);
 
+    /* Convert the ASCII hex dump to binary data */
     for (i = 0; i < pkt_len; i += 16) {
         if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
             *err = file_error(fh, err_info);
@@ -445,25 +428,25 @@ parse_vms_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err,
             }
             return FALSE;
         }
-       line[VMS_LINE_LENGTH] = '\0';
+        line[VMS_LINE_LENGTH] = '\0';
         if (i == 0) {
-           while (! isdumpline(line)) { /* advance to start of hex data */
-               if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
-                   *err = file_error(fh, err_info);
-                   if (*err == 0) {
-                       *err = WTAP_ERR_SHORT_READ;
-                   }
-                   return FALSE;
-               }
-               line[VMS_LINE_LENGTH] = '\0';
-           }
-            while (line[offset] && !isxdigit((guchar)line[offset]))
+            while (! isdumpline(line)) { /* advance to start of hex data */
+                if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
+                    *err = file_error(fh, err_info);
+                    if (*err == 0) {
+                        *err = WTAP_ERR_SHORT_READ;
+                    }
+                    return FALSE;
+                }
+                line[VMS_LINE_LENGTH] = '\0';
+            }
+            while (line[offset] && !g_ascii_isxdigit(line[offset]))
                 offset++;
-       }
-       if (!parse_single_hex_dump_line(line, buf, i,
-                                       offset, pkt_len - i)) {
+        }
+        if (!parse_single_hex_dump_line(line, pd, i,
+                                        offset, pkt_len - i)) {
             *err = WTAP_ERR_BAD_FILE;
-           *err_info = g_strdup_printf("vms: hex dump not valid");
+            *err_info = g_strdup("vms: hex dump not valid");
             return FALSE;
         }
     }
@@ -515,14 +498,14 @@ parse_single_hex_dump_line(char* rec, guint8 *buf, long byte_offset,
 
     /* Get the byte_offset directly from the record */
     s = rec;
-    value = (int)strtoul(s + 45 + in_off, NULL, 16);   /* XXX - error check? */
+    value = (int)strtoul(s + 45 + in_off, NULL, 16);    /* XXX - error check? */
 
     if (value != byte_offset) {
         return FALSE;
     }
 
     if (remaining > 16)
-       remaining = 16;
+        remaining = 16;
 
     /* Read the octets right to left, as that is how they are displayed
      * in VMS.
@@ -537,3 +520,16 @@ parse_single_hex_dump_line(char* rec, guint8 *buf, long byte_offset,
 
     return TRUE;
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */