--- pgp/src/language.c 2018/04/24 16:37:53 1.1.1.1 +++ pgp/src/language.c 2018/04/24 16:40:52 1.1.1.5 @@ -1,7 +1,24 @@ /* - * language.c - Foreign language translation for PGP - * Finds foreign language "subtitles" for English phrases - * in external foriegn language text file. + language.c - Foreign language translation for PGP + Finds foreign language "subtitles" for English phrases + in external foriegn language text file. + + (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved. + The author assumes no liability for damages resulting from the use + of this software, even if the damage results from defects in this + software. No warranty is expressed or implied. + + Note that while most PGP source modules bear Philip Zimmermann's + copyright notice, many of them have been revised or entirely written + by contributors who frequently failed to put their names in their + code. Code that has been incorporated into PGP from other authors + was either originally published in the public domain or is used with + permission from the various authors. + + PGP is available for free to the public under certain restrictions. + See the PGP User's Guide (included in the release package) for + important information about licensing, patent restrictions on + certain algorithms, trademarks, copyrights, and export controls. */ #include @@ -12,6 +29,8 @@ #include "fileio.h" #include "language.h" #include "pgp.h" +#include "charset.h" +#include "armor.h" #define SUBTITLES_FILE "language.txt" #define LANG_INDEXFILE "language.idx" @@ -45,126 +64,124 @@ static int line = 0; */ static char * readstr (FILE *f, char *buf, int nlabort) -{ int c, d; +{ + int c, d; char *p = buf; int state = NEWLINE; int i = 0; - while ((c = getc(f)) != EOF) - { + while ((c = getc(f)) != EOF) { if (c == '\r') continue; /* line numbers are only incremented when creating index file */ if (line && c == '\n') ++line; - switch (state) - { - case NEWLINE: - switch(c) - { - case '#': state = COMMENT; break; - case '"': state = INSTRING; break; - case '\n': - if (nlabort) - { *buf = '\0'; - return(buf); - } - default: - if (i == 0 && isalnum(c)) - { - state = IDENT; - lang[i++] = c; - break; - } - if (!isspace(c)) - { - fprintf(stderr, "language.txt:%d: syntax error\n", line); - state = ERROR; - } - } - break; - case COMMENT: - if (c == '\n') - state = NEWLINE; - break; - case INSTRING: - switch(c) - { - case '\\': state = ESCAPE; break; - case '"': state = DONE; break; - default: *p++ = c; - } - break; - case ESCAPE: - switch (c) - { - case 'n': *p++ = '\n'; break; - case 'r': *p++ = '\r'; break; - case 't': *p++ = '\t'; break; - case 'e': *p++ = '\033'; break; - case 'a': *p++ = '\007'; break; - case '#': - case '"': - case '\\': *p++ = c; break; - case '\n': break; - case '0': - d = 0; - while ((c = fgetc(f)) >= '0' && c <= '7') - d = 8 * d + c - '0'; - *p++ = d; - ungetc(c, f); - break; - default: - fprintf(stderr, "language.txt:%d: illegal escape sequence: '\\%c'\n", line, c); - break; - } - state = INSTRING; - break; - case IDENT: /* language identifier */ - if (c == ':') { - state = NEWLINE; - break; + switch (state) { + case NEWLINE: + switch(c) { + case '#': state = COMMENT; break; + case '"': state = INSTRING; break; + case '\n': + if (nlabort) { + *buf = '\0'; + return buf; } - if (c == '\n' && strncmp(lang, "No translation", 14) == 0) - { - i = 0; - state = NEWLINE; + default: + if (i == 0 && isalnum(c)) { + state = IDENT; + lang[i++] = c; break; } - lang[i++] = c; - if (i == 15 || !isalnum(c) && !isspace(c)) - { - lang[i] = '\0'; - fprintf(stderr, "language.txt:%d: bad language identifier: '%s'\n", line, lang); + if (!isspace(c)) { + fprintf(stderr, "language.txt:%d: syntax error\n", line); state = ERROR; - i = 0; - } - break; - case DONE: - if (c == '\n') - { - lang[i] = '\0'; - *p = '\0'; - return(buf); } - if (!isspace(c)) - { - fprintf(stderr, "language.txt:%d: extra characters after '\"'\n", line); - state = ERROR; - } - break; - case ERROR: - if (c == '\n') - state = ERR1; + } + break; + case COMMENT: + if (c == '\n') + state = NEWLINE; + break; + case INSTRING: + switch(c) { + case '\\': state = ESCAPE; break; + case '"': state = DONE; break; + default: *p++ = c; + } + break; + case ESCAPE: + switch (c) { + case 'n': *p++ = '\n'; break; + case 'r': *p++ = '\r'; break; + case 't': *p++ = '\t'; break; + case 'e': *p++ = '\033'; break; + case 'a': *p++ = '\007'; break; + case '#': + case '"': + case '\\': *p++ = c; break; + case '\n': break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + d = c - '0'; + while ((c = fgetc(f)) >= '0' && c <= '7') + d = 8 * d + c - '0'; + *p++ = d; + ungetc(c, f); + break; + default: + fprintf(stderr, "language.txt:%d: illegal escape sequence: '\\%c'\n", line, c); + break; + } + state = INSTRING; + break; + case IDENT: /* language identifier */ + if (c == ':') { + state = NEWLINE; break; - case ERR1: - state = (c == '\n' ? NEWLINE : ERROR); + } + if (c == '\n' && strncmp(lang, "No translation", 14) == 0) + { + i = 0; + state = NEWLINE; break; + } + lang[i++] = c; + if (i == 15 || !isalnum(c) && !isspace(c)) { + lang[i] = '\0'; + fprintf(stderr, "language.txt:%d: bad language identifier: '%s'\n", line, lang); + state = ERROR; + i = 0; + } + break; + case DONE: + if (c == '\n') { + lang[i] = '\0'; + *p = '\0'; + return buf; + } + if (!isspace(c)) { + fprintf(stderr, "language.txt:%d: extra characters after '\"'\n", line); + state = ERROR; + } + break; + case ERROR: + if (c == '\n') + state = ERR1; + break; + case ERR1: + state = (c == '\n' ? NEWLINE : ERROR); + break; } } if (state != NEWLINE) fprintf(stderr, "language.txt: unexpected EOF\n"); - return(NULL); + return NULL; } #ifdef TEST @@ -192,10 +209,9 @@ static int nmsg = 0; static FILE *langf; -static void init_lang(); +static void init_lang(void); + static int make_indexfile(char *); -word32 crcupdate(byte, word32); -void init_crc(); /* * uses 24-bit CRC function from armor.c @@ -203,11 +219,7 @@ void init_crc(); static word32 message_crc(char *s) { - word32 crc = 0; - - while (*s) - crc = crcupdate(*s++, crc); - return(crc); + return crcbytes((byte *)s, strlen(s), (word32)0); } /* @@ -220,8 +232,8 @@ lookup_offset(word32 crc) for (i = 0; i < nmsg; ++i) if (indx_tbl[i].crc == crc) - return(indx_tbl[i].offset); - return(-1); + return indx_tbl[i].offset; + return -1; } @@ -229,30 +241,29 @@ lookup_offset(word32 crc) * return foreign translation of s */ char * -PSTR (char *s) +LANG (char *s) { long filepos; if (subtitles_available == 0) init_lang(); if (subtitles_available < 0) - return(s); + return s; filepos = lookup_offset(message_crc(s)); - if (filepos == -1) - return(s); - else - { + if (filepos == -1) { + return s; + } else { fseek(langf, filepos, SEEK_SET); readstr(langf, strbuf, 1); } if (strbuf[0] == '\0') - return(s); + return s; for (s = strbuf; *s; ++s) *s = EXT_C(*s); - return(strbuf); + return strbuf; } @@ -276,36 +287,35 @@ init_lang() char subtitles_file[MAX_PATH]; FILE *indexf; - if (strcmp(language, "en") == 0) - { subtitles_available = -1; + if (strcmp(language, "en") == 0) { + subtitles_available = -1; return; /* use default messages */ } buildfilename (subtitles_file, SUBTITLES_FILE); - if ((langf = fopenbin(subtitles_file, "r")) == NULL) - { + langf = fopen(subtitles_file, FOPRTXT); + if (langf == NULL) { subtitles_available = -1; return; } init_crc(); - if ((strbuf = (char *) malloc(STRBUFSIZE)) == NULL) - { + strbuf = (char *)malloc(STRBUFSIZE); + if (strbuf == NULL) { fprintf(stderr, "Not enough memory for foreign subtitles\n"); fclose(langf); subtitles_available = -1; return; } buildfilename(indexfile, LANG_INDEXFILE); - if ((indexf = fopenbin(indexfile, "r")) != NULL) - { + indexf = fopen(indexfile, FOPRBIN); + if (indexf != NULL) { if (fread(&indx_hdr, 1, sizeof(indx_hdr), indexf) == sizeof(indx_hdr) && indx_hdr.lang_fsize == fsize(langf) && strcmp(indx_hdr.lang, language) == 0) { nmsg = indx_hdr.nmsg; indx_tbl = (struct indx_ent *) malloc(nmsg * sizeof(struct indx_ent)); - if (indx_tbl == NULL) - { + if (indx_tbl == NULL) { fprintf(stderr, "Not enough memory for foreign subtitles\n"); fclose(indexf); fclose(langf); @@ -320,13 +330,12 @@ init_lang() } fclose(indexf); } - if (indx_tbl == NULL && make_indexfile(indexfile) < 0) - { + if (indx_tbl == NULL && make_indexfile(indexfile) < 0) { fclose(langf); subtitles_available = -1; - } - else + } else { subtitles_available = 1; + } } @@ -347,24 +356,20 @@ make_indexfile(char *indexfile) init_crc(); line = 1; nmsg = 0; - while (readstr(langf, strbuf, 0)) - { - if (nmsg == max_msgs) - { - if (max_msgs) - { max_msgs *= 2; + while (readstr(langf, strbuf, 0)) { + if (nmsg == max_msgs) { + if (max_msgs) { + max_msgs *= 2; indx_tbl = (struct indx_ent *) realloc(indx_tbl, max_msgs * sizeof(struct indx_ent)); - } - else - { max_msgs = 400; + } else { + max_msgs = 400; indx_tbl = (struct indx_ent *) malloc(max_msgs * sizeof(struct indx_ent)); } - if (indx_tbl == NULL) - { + if (indx_tbl == NULL) { fprintf(stderr, "Not enough memory for foreign subtitles\n"); - return(-1); + return -1; } } ++total_msgs; @@ -372,8 +377,7 @@ make_indexfile(char *indexfile) if (lookup_offset(indx_tbl[nmsg].crc) != -1) fprintf(stderr, "language.txt:%d: Message CRC not unique: \"%s\"\n", line, strbuf); - do - { + do { filepos = ftell(langf); res = readstr (langf, strbuf, 1); /* Abort if find newline first */ } while (res && strbuf[0] != '\0' && strcmp(language, lang) != 0); @@ -391,23 +395,22 @@ make_indexfile(char *indexfile) } line = 0; indx_hdr.nmsg = nmsg; - if (nmsg == 0) - { fprintf(stderr, "No translations available for language \"%s\"\n\n", + if (nmsg == 0) { + fprintf(stderr, "No translations available for language \"%s\"\n\n", language); - return(-1); + return -1; } if (verbose || total_msgs != nmsg) fprintf(stderr, "%d messages, %d translations\n\n", total_msgs, nmsg); - if ((indexf = fopenbin(indexfile, "w")) == NULL) + if ((indexf = fopen(indexfile, FOPWBIN)) == NULL) { fprintf(stderr, "Cannot create %s\n", indexfile); - else - { + } else { fwrite(&indx_hdr, 1, sizeof(indx_hdr), indexf); fwrite(indx_tbl, sizeof(struct indx_ent), nmsg, indexf); if (ferror(indexf) || fclose(indexf)) fprintf(stderr, "error writing %s\n", indexfile); } - return(0); + return 0; } #endif /* TEST */