/* ianachar.c - Convert IANA Charset Registry to corresponding MIB */ /* Donated to IANA by Ira E McDonald - Version 0.30 (September 2003) */ /**************************/ /* Standard Header Files */ /**************************/ #include #include #include #include #include #include /*********************/ /* Global Variables */ /*********************/ char *ianachar_synopsis[] = { "Usage: ianachar [-hv] [-iFile] [-oFile] [-pFile] [-mNNNN]", " -h Display this program synopsis", " -i Input filename (replaces default)", " -m Maximum MIBenum value (default 2999)", " -o Output filename (replaces default)", " -p Prefix (template) filename (replaces default)", " -v Verbose", "", "Utility to convert IANA Charset Registry to corresponding MIB", NULL }; #define IANACHAR_INDEXMAX 2999 /* max MIBenum per registry */ #define IANACHAR_BUFMAX 256 /* max file buffer length */ #define IANACHAR_TAGMAX 63 /* max SMIv2 enum tag length */ time_t ianachar_time; /* system time */ char *ianachar_name = NULL; char **ianachar_index; int ianachar_namemax = (IANACHAR_INDEXMAX * 8); int ianachar_nametotal = 0; int ianachar_indexmax = IANACHAR_INDEXMAX; int ianachar_indexcount = 0; int ianachar_namelimit = 0; char ianachar_version[] = "Version 0.30 (September 2003)"; char ianachar_inputfile[IANACHAR_BUFMAX+1] = #ifdef OSMSDOS "ianachar.txt"; #else "character-sets"; #endif FILE *ianachar_inputfp = NULL; char ianachar_inputbuf[IANACHAR_BUFMAX+1]; int ianachar_inputlen; int ianachar_inputcount = 0; char ianachar_prefixfile[IANACHAR_BUFMAX+1] = #ifdef OSMSDOS "ianachar.dat"; #else "ianacharset-mib-template"; #endif FILE *ianachar_prefixfp = NULL; char ianachar_prefixbuf[IANACHAR_BUFMAX+1]; int ianachar_prefixlen; int ianachar_prefixcount = 0; char ianachar_outputfile[IANACHAR_BUFMAX+1] = #ifdef OSMSDOS "ianachar.mib"; #else "ianacharset-mib"; #endif FILE *ianachar_outputfp = NULL; char ianachar_outputbuf[IANACHAR_BUFMAX+1]; int ianachar_outputlen; int ianachar_outputcount = 0; int ianachar_verbose = 0; /***************/ /* Prototypes */ /***************/ extern int main (int argc, char *argv[]); static void ianachar_show_synopsis (void); static int ianachar_read_file (void); static int ianachar_read_line (void); static int ianachar_read_prefix (void); static int ianachar_write_file (void); static int ianachar_write_line (void); /**********************/ /* Function 'main()' */ /**********************/ extern int main (int argc, char *argv[]) { /* 'main' */ int ai; /* argument index */ char *ap; /* argument pointer */ int status; /* status returned */ /* Check for missing input arguments */ printf ("ianachar - %s\n", &ianachar_version[0]); if (argc < 1) ianachar_show_synopsis (); ai = 1; ap = argv[ai]; /* Check for switches */ for (ai = 1; ai < argc; ai++) { ap = argv[ai]; if (*ap != '-') break; for (ap++; *ap; ap++) { switch (*ap) { case 'h': /* help? */ ianachar_show_synopsis (); break; case 'i': /* input filename? */ case 'I': ap++; strncpy (ianachar_inputfile, ap, IANACHAR_BUFMAX); while (*ap) ap++; ap--; break; case 'm': /* max MIBenum value? */ case 'M': ap++; ianachar_indexmax = atoi (ap); while (*ap) ap++; ap--; break; case 'o': /* output filename? */ case 'O': ap++; strncpy (ianachar_outputfile, ap, IANACHAR_BUFMAX); while (*ap) ap++; ap--; break; case 'p': /* prefix filename? */ case 'P': ap++; strncpy (ianachar_prefixfile, ap, IANACHAR_BUFMAX); while (*ap) ap++; ap--; break; case 'v': /* verbose? */ case 'V': ianachar_verbose = 1; break; default: break; } } } /* Range check switch changes */ if (ianachar_indexmax < 2999) { printf ("ianachar - (Error) Invalid max MIBenum value\n"); exit (0); } /* Allocate dynamic arrays */ ianachar_namemax = (ianachar_indexmax * 8); ianachar_name = (char *) calloc (1, ianachar_namemax); ianachar_index = (char **) calloc (1, (ianachar_indexmax + 1) * sizeof (char *)); if ((ianachar_name == NULL) || (ianachar_index == NULL)) { printf ("ianachar - Error allocating memory\n"); exit (0); } /* Read and process charset registry input file */ status = ianachar_read_file (); if (ianachar_verbose) { printf ("ianachar - Input lines %d\n", ianachar_inputcount); printf ("ianachar - Input names %d\n", ianachar_indexcount); printf ("ianachar - Longest name %d\n", ianachar_namelimit); printf ("ianachar - Sum of names %d\n", ianachar_nametotal); } /* Write MIB output file */ status = ianachar_write_file (); if (ianachar_verbose) { printf ("ianachar - Prefix lines %d\n", ianachar_prefixcount); printf ("ianachar - Output lines %d\n", ianachar_outputcount); } return (0); } /* 'main' */ /****************************************/ /* Function 'ianachar_show_synopsis()' */ /****************************************/ static void ianachar_show_synopsis (void) { /* 'ianachar_show_synopsis' */ int si; /* synopsis index */ for (si = 0; ianachar_synopsis[si]; si++) printf ("%s\n", ianachar_synopsis[si]); exit (0); } /* 'ianachar_show_synopsis' */ /************************************/ /* Function 'ianachar_read_file()' */ /************************************/ static int ianachar_read_file (void) { /* 'ianachar_read_file' */ FILE *ifp; /* input file pointer */ char *ibp; /* input buffer pointer */ int len; /* tag length */ char tag[IANACHAR_BUFMAX+1]; /* ASN.1 enum tag */ int value; /* ASN.1 enum value */ char *s; /* source string */ char *t; /* target string */ /* Open input file */ printf ("ianachar - Opening input '%s'\n", ianachar_inputfile); ifp = fopen (ianachar_inputfile, "r"); ianachar_inputfp = ifp; if (ifp == NULL) { perror ("ianachar - Error opening input file"); exit (0); } printf ("ianachar - Reading input file...\n"); /* Process input file */ ibp = &ianachar_inputbuf[0]; ianachar_read_line (); if (ianachar_inputlen < 0) { printf ("ianachar - Error reading input file - line %d\n", ianachar_inputcount); exit (0); } for (;;) { /* Find next name (start of charset record) */ if (strncmp (ibp, "Name:", 5) != 0) { while (ianachar_read_line () >= 0) { if (strncmp (ibp, "Name:", 5) == 0) break; } if (ianachar_inputlen < 0) break; } if (strncmp (ibp, "Name:", 5) != 0) break; /* Save name with 'cs' prefix (fallback from alias) */ /* and delete any punctuation characters (per SMIv2) */ s = (ibp + 5); while (isspace (*s)) s++; t = &tag[0]; *t++ = 'c'; *t++ = 's'; for (; *s; s++) { if (isspace (*s)) break; if (ispunct (*s)) continue; if (isalnum (*s)) *t++ = *s; } *t = '\0'; len = (int) (t - &tag[0]); if (len > IANACHAR_TAGMAX) { printf ("ianachar - (Error) Invalid name - line %d\n", ianachar_inputcount); exit (0); } /* Find MIBenum (if present in record) */ while (ianachar_read_line () >= 0) { if (strncmp (ibp, "Name:", 5) == 0) break; if (strncmp (ibp, "MIBenum:", 8) == 0) break; } if (ianachar_inputlen < 0) break; /* Save MIBenum value */ if (strncmp (ibp, "MIBenum:", 8) != 0) { printf ("ianachar - (Warning) Missing MIBenum - line %d\n", ianachar_inputcount); continue; } s = (ibp + 8); while (isspace (*s)) s++; value = atoi (s); if ((value < 1) || (value > ianachar_indexmax)) { printf ("ianachar - (Error) Invalid MIBenum - line %d\n", ianachar_inputcount); exit (0); } /* Find MIB charset 'cs' alias (if present in record) */ while (ianachar_read_line () >= 0) { if (strncmp (ibp, "Name:", 5) == 0) break; if (strncmp (ibp, "Alias:", 6) != 0) continue; s = (ibp + 6); while (isspace (*s)) s++; if (strncmp (s, "cs", 2) == 0) break; } /* Save MIB charset 'cs' alias */ if (strncmp (ibp, "Alias:", 6) == 0) { t = &tag[0]; for (; *s; s++) { if (isspace (*s)) break; if (ispunct (*s)) continue; *t++ = *s; } *t = '\0'; len = (int) (t - &tag[0]); if (len > IANACHAR_TAGMAX) { printf ("ianachar - Invalid alias - line %d\n", ianachar_inputcount); exit (0); } } /* Save enum tag and enum value in their tables */ len = strlen (tag); if (len > ianachar_namelimit) ianachar_namelimit = len; if ((ianachar_nametotal + len + 1) > ianachar_namemax) { printf ("ianachar - Overflow name array - line %d\n", ianachar_inputcount); exit (0); } t = ianachar_name + ianachar_nametotal; strcpy (t, tag); ianachar_nametotal += (len + 1); *(ianachar_index + value) = t; ianachar_indexcount++; } /* Close input file */ fclose (ifp); return (0); } /* 'ianachar_read_file' */ /************************************/ /* Function 'ianachar_read_line()' */ /************************************/ static int ianachar_read_line (void) { /* 'ianachar_read_line' */ char *ibp; /* input buffer pointer */ int len; /* input line length */ ibp = &ianachar_inputbuf[0]; *ibp = '\0'; ibp = fgets (ibp, IANACHAR_BUFMAX, ianachar_inputfp); if (ibp == NULL) { if (feof (ianachar_inputfp) == 0) { printf ("ianachar - non-EOF read error\n"); perror ("ianachar - Error reading input file"); exit (0); } return (ianachar_inputlen = -1); } ianachar_inputcount++; len = strlen (ianachar_inputbuf); if (len > 0) len--; ibp += len; if (*ibp != '\n') { printf ("ianachar - Missing newline - line %d\n", ianachar_inputcount); exit (0); } *ibp = '\0'; return (ianachar_inputlen = len); } /* 'ianachar_read_line' */ /**************************************/ /* Function 'ianachar_read_prefix()' */ /**************************************/ static int ianachar_read_prefix (void) { /* 'ianachar_read_prefix' */ char *pbp; /* prefix buffer pointer */ int len; /* prefix line length */ pbp = &ianachar_prefixbuf[0]; *pbp = '\0'; pbp = fgets (pbp, IANACHAR_BUFMAX, ianachar_prefixfp); if (pbp == NULL) { if (feof (ianachar_prefixfp) == 0) { printf ("ianachar - non-EOF read error\n"); perror ("ianachar - Error reading prefix file"); exit (0); } return (ianachar_prefixlen = -1); } ianachar_prefixcount++; len = strlen (ianachar_prefixbuf); if (len > 0) len--; pbp += len; if (*pbp != '\n') { printf ("ianachar - Missing newline - line %d\n", ianachar_prefixcount); exit (0); } *pbp = '\0'; return (ianachar_prefixlen = len); } /* 'ianachar_read_prefix' */ /*************************************/ /* Function 'ianachar_write_file()' */ /*************************************/ static int ianachar_write_file (void) { /* 'ianachar_write_file' */ struct tm *tmp; /* Greenwich mean time (GMT) */ FILE *pfp; /* prefix file pointer */ char *pbp; /* prefix buffer pointer */ int len; /* prefix buffer length */ FILE *ofp; /* output file pointer */ char *obp; /* output buffer pointer */ char *tag; /* ASN.1 enum tag */ int value; /* ASN.1 enum value */ /* Open output file */ printf ("ianachar - Opening output '%s'\n", ianachar_outputfile); ofp = fopen (ianachar_outputfile, "w"); ianachar_outputfp = ofp; if (ofp == NULL) { perror ("ianachar - Error opening output file"); exit (0); } printf ("ianachar - Writing output file...\n"); /* Read system time for LAST-UPDATED and REVISION clauses */ ianachar_time = time (NULL); tmp = gmtime (&ianachar_time); if (tmp == NULL) { printf ("ianachar - Error reading system time\n"); exit (0); } /* Open prefix file */ printf ("ianachar - Opening prefix '%s'\n", ianachar_prefixfile); pfp = fopen (ianachar_prefixfile, "r"); ianachar_prefixfp = pfp; if (pfp == NULL) { perror ("ianachar - Error opening prefix file"); exit (0); } /* Copy prefix file to output file */ printf ("ianachar - Copying prefix file to output file...\n"); for (;;) { len = ianachar_read_prefix (); if (len < 0) break; pbp = &ianachar_prefixbuf[0]; obp = &ianachar_outputbuf[0]; strcpy (obp, pbp); while (*pbp == ' ') pbp++; /* Fixup LAST-UPDATED clause to current date */ if (strncmp (pbp, "LAST-UPDATED", 12) == 0) { sprintf (obp, " LAST-UPDATED \"%04d%02d%02d0000Z\"", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday); } /* Insert REVISION clause with current date */ if (strncmp (pbp, "REVISION", 8) == 0) { sprintf (obp, " REVISION \"%04d%02d%02d0000Z\"", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday); len = ianachar_write_line (); strcpy (obp, " DESCRIPTION \"Newest version\""); len = ianachar_write_line (); strcpy (obp, ""); len = ianachar_write_line (); pbp = &ianachar_prefixbuf[0]; strcpy (obp, pbp); } len = ianachar_write_line (); } /* Close prefix file */ fclose (pfp); /* Write charset enums to output file */ /* Reserved values are other(1) and unknown(2) */ printf ("ianachar - Writing charset enums to output file...\n"); for (value = 3; value <= ianachar_indexmax; value++) { tag = *(ianachar_index + value); if (tag == NULL) continue; sprintf (ianachar_outputbuf, " %s(%d),", tag, value); len = ianachar_write_line (); } /* Write suffix to output file */ sprintf (ianachar_outputbuf, " reserved(%d)", ianachar_indexmax + 1); len = ianachar_write_line (); strcpy (ianachar_outputbuf, " }"); len = ianachar_write_line (); strcpy (ianachar_outputbuf, "END"); len = ianachar_write_line (); /* Close output file */ fclose (ofp); return (0); } /* 'ianachar_write_file' */ /*************************************/ /* Function 'ianachar_write_line()' */ /*************************************/ static int ianachar_write_line (void) { /* 'ianachar_write_line' */ char *obp; /* output buffer pointer */ int len; /* output line length */ obp = &ianachar_outputbuf[0]; strcat (obp, "\n"); ianachar_outputlen = strlen (obp); len = fputs (obp, ianachar_outputfp); if (len < 0) { perror ("ianachar - Error writing output file"); exit (0); } ianachar_outputcount++; return (ianachar_outputlen); } /* 'ianachar_write_line' */