diff options
Diffstat (limited to 'utils/messages.c')
-rw-r--r-- | utils/messages.c | 313 |
1 files changed, 152 insertions, 161 deletions
diff --git a/utils/messages.c b/utils/messages.c index e2d45e9da..418276ec3 100644 --- a/utils/messages.c +++ b/utils/messages.c @@ -42,116 +42,104 @@ /** Messages are stored in a fixed-size hash table. */ #define HASH_SIZE 101 -/** The hash table used to store the standard Messages file for the old API */ +/** + * The hash table used to store the standard Messages file for the old API + */ static struct hash_table *messages_hash = NULL; + /** - * process a line of input. + * Create a message context + * + * generate a message context populated with english fallbacks for + * some formatted messages. */ -static nserror -message_process_line(struct hash_table *hash, uint8_t *ln, int lnlen) +static struct hash_table *messages_create_ctx(int hash_size) { - uint8_t *value; - uint8_t *colon; - - /* empty or comment lines */ - if (ln[0] == 0 || ln[0] == '#') { - return NSERROR_OK; - } - - /* find first colon as key/value separator */ - for (colon = ln; colon < (ln + lnlen); colon++) { - if (*colon == ':') { - break; + struct hash_table *nctx; + const struct { + const char *key; + const char *value; + } fallback[] = { + { "LoginDescription", + "The site %s is requesting your username and password. " + "The realm is \"%s\""}, + { "PrivacyDescription", + "A privacy error occurred while communicating with %s this " + "may be a site configuration error or an attempt to steal " + "private information (passwords, messages or credit cards)"}, + { "TimeoutDescription", + "A connection to %s could not be established. The site may " + "be temporarily unavailable or too busy to respond."}, + { "FetchErrorDescription", + "An error occurred when connecting to %s"}, + { NULL, NULL} + }; + nctx = hash_create(hash_size); + + if (nctx != NULL) { + int floop; + for (floop = 0; fallback[floop].key != NULL; floop++) { + hash_add(nctx, + fallback[floop].key, + fallback[floop].value); } } - if (colon == (ln + lnlen)) { - /* no colon found */ - return NSERROR_INVALID; - } - *colon = 0; /* terminate key */ - value = colon + 1; + return nctx; +} - if (hash_add(hash, (char *)ln, (char *)value) == false) { - NSLOG(netsurf, INFO, "Unable to add %s:%s to hash table", ln, - value); - return NSERROR_INVALID; - } - return NSERROR_OK; +/** + * Free memory used by a messages hash. + * The context will not be valid after this function returns. + * + * \param ctx context of messages file to free + */ +static void messages_destroy_ctx(struct hash_table *ctx) +{ + if (ctx == NULL) + return; + + hash_destroy(ctx); } + /** * Read keys and values from messages file. * * \param path pathname of messages file - * \param ctx reference of hash table to merge with. + * \param ctx reference of hash table to merge with or NULL to create one. * \return NSERROR_OK on sucess and ctx updated or error code on faliure. */ static nserror messages_load_ctx(const char *path, struct hash_table **ctx) { - char s[400]; /* line buffer */ - gzFile fp; /* compressed file handle */ struct hash_table *nctx; /* new context */ + nserror res; - assert(path != NULL); - - fp = gzopen(path, "r"); - if (!fp) { - NSLOG(netsurf, INFO, - "Unable to open messages file \"%.100s\": %s", path, - strerror(errno)); - - return NSERROR_NOT_FOUND; - } - - if (*ctx == NULL) { - nctx = hash_create(HASH_SIZE); - } else { + if (*ctx != NULL) { /** * \note The passed hash is not copied here so this * updates in place. */ - nctx = *ctx; + return hash_add_file(*ctx, path); } + + nctx = messages_create_ctx(HASH_SIZE); if (nctx == NULL) { NSLOG(netsurf, INFO, "Unable to create hash table for messages file %s", path); - gzclose(fp); return NSERROR_NOMEM; } - while (gzgets(fp, s, sizeof s)) { - char *colon, *value; - - if (s[0] == 0 || s[0] == '#') - continue; - - s[strlen(s) - 1] = 0; /* remove \n at end */ - colon = strchr(s, ':'); - if (!colon) - continue; - *colon = 0; /* terminate key */ - value = colon + 1; - - if (hash_add(nctx, s, value) == false) { - NSLOG(netsurf, INFO, - "Unable to add %s:%s to hash table of %s", s, - value, path); - gzclose(fp); - if (*ctx == NULL) { - hash_destroy(nctx); - } - return NSERROR_INVALID; - } + res = hash_add_file(nctx, path); + if (res == NSERROR_OK) { + *ctx = nctx; + } else { + hash_destroy(nctx); } - gzclose(fp); - - *ctx = nctx; - - return NSERROR_OK; + return res; } @@ -185,113 +173,34 @@ messages_get_ctx(const char *key, struct hash_table *ctx) } -/** - * Free memory used by a messages hash. - * The context will not be valid after this function returns. - * - * \param ctx context of messages file to free - */ -static void messages_destroy_ctx(struct hash_table *ctx) -{ - if (ctx == NULL) - return; - - hash_destroy(ctx); -} - - /* exported interface documented in messages.h */ nserror messages_add_from_file(const char *path) { - nserror err; - if (path == NULL) { return NSERROR_BAD_PARAMETER; } NSLOG(netsurf, INFO, "Loading Messages from '%s'", path); - err = messages_load_ctx(path, &messages_hash); - - - return err; + return messages_load_ctx(path, &messages_hash); } /* exported interface documented in messages.h */ -nserror messages_add_from_inline(const uint8_t *data, size_t data_size) +nserror messages_add_from_inline(const uint8_t *data, size_t size) { - z_stream strm; - int ret; - uint8_t s[512]; /* line buffer */ - size_t used = 0; /* number of bytes in buffer in use */ - uint8_t *nl; - /* ensure the hash table is initialised */ if (messages_hash == NULL) { - messages_hash = hash_create(HASH_SIZE); + messages_hash = messages_create_ctx(HASH_SIZE); } if (messages_hash == NULL) { NSLOG(netsurf, INFO, "Unable to create hash table"); return NSERROR_NOMEM; } - - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - - strm.next_in = (uint8_t *)data; - strm.avail_in = data_size; - - ret = inflateInit2(&strm, 32 + MAX_WBITS); - if (ret != Z_OK) { - NSLOG(netsurf, INFO, "inflateInit returned %d", ret); - return NSERROR_INVALID; - } - - do { - strm.next_out = s + used; - strm.avail_out = sizeof(s) - used; - - ret = inflate(&strm, Z_NO_FLUSH); - if ((ret != Z_OK) && (ret != Z_STREAM_END)) { - break; - } - - used = sizeof(s) - strm.avail_out; - while (used > 0) { - /* find nl */ - for (nl = &s[0]; nl < &s[used]; nl++) { - if (*nl == '\n') { - break; - } - } - if (nl == &s[used]) { - /* no nl found */ - break; - } - /* found newline */ - *nl = 0; /* null terminate line */ - message_process_line(messages_hash, &s[0], nl - &s[0]); - memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) ); - used -= ((nl +1) - &s[0]); - } - if (used == sizeof(s)) { - /* entire buffer used and no newline */ - NSLOG(netsurf, INFO, "Overlength line"); - used = 0; - } - } while (ret != Z_STREAM_END); - - inflateEnd(&strm); - - if (ret != Z_STREAM_END) { - NSLOG(netsurf, INFO, "inflate returned %d", ret); - return NSERROR_INVALID; - } - return NSERROR_OK; + return hash_add_inline(messages_hash, data, size); } + /* exported interface documented in messages.h */ char *messages_get_buff(const char *key, ...) { @@ -300,7 +209,17 @@ char *messages_get_buff(const char *key, ...) int buff_len = 0; va_list ap; - msg_fmt = messages_get_ctx(key, messages_hash); + assert(key != NULL); + + if (messages_hash == NULL) { + return NULL; + } + + msg_fmt = hash_get(messages_hash, key); + + if (msg_fmt == NULL) { + return NULL; + } va_start(ap, key); buff_len = vsnprintf(buff, buff_len, msg_fmt, ap); @@ -456,6 +375,22 @@ const char *messages_get_errorcode(nserror code) case NSERROR_UNKNOWN: /* Unknown error */ return messages_get_ctx("Unknown", messages_hash); + + case NSERROR_BAD_AUTH: + /* Authentication required */ + return messages_get_ctx("BadAuth", messages_hash); + + case NSERROR_BAD_REDIRECT: + /* To many redirects */ + return messages_get_ctx("TooManyRedirects", messages_hash); + + case NSERROR_BAD_CERTS: + /* Certificate chain verification failure */ + return messages_get_ctx("CertificateVerificationNeeded", messages_hash); + + case NSERROR_TIMEOUT: + /* Operation timed out */ + return messages_get_ctx("Timeout", messages_hash); } /* The switch has no default, so the compiler should tell us when we @@ -466,6 +401,63 @@ const char *messages_get_errorcode(nserror code) return messages_get_ctx("Unknown", messages_hash); } +/* exported function documented in utils/messages.h */ +const char *messages_get_sslcode(ssl_cert_err code) +{ + switch (code) { + case SSL_CERT_ERR_OK: + /* Nothing wrong with this certificate */ + return messages_get_ctx("SSLCertErrOk", messages_hash); + + case SSL_CERT_ERR_UNKNOWN: + /* Unknown error */ + return messages_get_ctx("SSLCertErrUnknown", messages_hash); + + case SSL_CERT_ERR_BAD_ISSUER: + /* Bad issuer */ + return messages_get_ctx("SSLCertErrBadIssuer", messages_hash); + + case SSL_CERT_ERR_BAD_SIG: + /* Bad signature on this certificate */ + return messages_get_ctx("SSLCertErrBadSig", messages_hash); + + case SSL_CERT_ERR_TOO_YOUNG: + /* This certificate is not yet valid */ + return messages_get_ctx("SSLCertErrTooYoung", messages_hash); + + case SSL_CERT_ERR_TOO_OLD: + /* This certificate is no longer valid */ + return messages_get_ctx("SSLCertErrTooOld", messages_hash); + + case SSL_CERT_ERR_SELF_SIGNED: + /* This certificate is self signed */ + return messages_get_ctx("SSLCertErrSelfSigned", messages_hash); + + case SSL_CERT_ERR_CHAIN_SELF_SIGNED: + /* This certificate chain is self signed */ + return messages_get_ctx("SSLCertErrChainSelfSigned", messages_hash); + + case SSL_CERT_ERR_REVOKED: + /* This certificate has been revoked */ + return messages_get_ctx("SSLCertErrRevoked", messages_hash); + + case SSL_CERT_ERR_HOSTNAME_MISMATCH: + /* Common name is invalid */ + return messages_get_ctx("SSLCertErrHostnameMismatch", messages_hash); + + case SSL_CERT_ERR_CERT_MISSING: + /* Common name is invalid */ + return messages_get_ctx("SSLCertErrCertMissing", messages_hash); + + } + + /* The switch has no default, so the compiler should tell us when we + * forget to add messages for new error codes. As such, we should + * never get here. + */ + assert(0); + return messages_get_ctx("Unknown", messages_hash); +} /* exported function documented in utils/messages.h */ void messages_destroy(void) @@ -473,4 +465,3 @@ void messages_destroy(void) messages_destroy_ctx(messages_hash); messages_hash = NULL; } - |