diff -urN fortune-mod-9708-orig/fortune/fortune.c fortune-mod-9708/fortune/fortune.c --- fortune-mod-9708-orig/fortune/fortune.c 2004-02-26 22:38:13 +0300 +++ fortune-mod-9708/fortune/fortune.c 2004-02-27 02:02:46 +0300 @@ -106,6 +106,11 @@ #include #include #include +/* FIXME(raorn): use ifdef's */ +#include +#include +#include +#include /* This makes GNU libc to prototype the BSD regex functions */ #ifdef BSD_REGEX @@ -212,6 +217,10 @@ #endif /* BSD_REGEX */ +/* FIXME(raorn): use ifdef's */ +iconv_t cd = NULL; +char *Codeset = NULL; + int add_dir(register FILEDESC *); char *program_version(void) @@ -244,6 +253,57 @@ /* + * fortune_iconv: + * Translate text from UTF-8 to current CODESET (LC_CTYPE). + * Thanx to Alexander Bokovoy for this code. + */ +int fortune_iconv(iconv_t _cd, char *inbuf, int inlen, char *outbuf, int outlen) +{ + char *outptr; + size_t n; + int needed_from; + + if (_cd && _cd == (iconv_t) -1) { + memmove(outbuf, inbuf, inlen); + return 0; + } + + outptr = outbuf; + while (inlen > 0) { + n = iconv (_cd, (char **) &inbuf, &inlen, &outptr, &outlen); + + if(inlen == 0) break; + + if (n != (size_t) - 1) { + n = iconv (_cd, NULL, NULL, &outptr, &outlen); + + break; + } + + if (errno != E2BIG) { + switch (errno) { + case EILSEQ: + case EINVAL: + needed_from = ((__gconv_t) _cd)->__steps->__min_needed_from; + outptr[0] = '?'; + outptr++; + outlen--; + inbuf += needed_from; + inlen -= needed_from; + break; + default: + return -1; + } + } else { + /* FIXME: no space left in output buffer */ + break; + } + } + outptr[0] = 0; + return 0; +} + +/* * calc_equal_probs: * Set the global values for number of files/children, to be used * in printing probabilities when listing files @@ -351,6 +411,11 @@ if ((new = malloc(size)) == NULL) { (void) fprintf(stderr, "fortune: out of memory.\n"); + + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } return new; @@ -828,6 +893,10 @@ { fprintf(stderr, "fortune: probabilities sum to %d%%!\n", percent); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } else if (percent < 100 && num_noprob == 0) @@ -835,12 +904,20 @@ fprintf(stderr, "fortune: no place to put residual probability (%d%%)\n", percent); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } else if (percent == 100 && num_noprob != 0) { fprintf(stderr, "fortune: no probability left to put in residual files\n"); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } Spec_prob = percent; /* this is for -f when % is specified on cmd line */ @@ -916,12 +993,20 @@ if ((fd = open(fp->datfile, 0)) < 0) { perror(fp->datfile); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } if (read(fd, (char *) &fp->tbl, sizeof fp->tbl) != sizeof fp->tbl) { fprintf(stderr, "fortune: %s corrupted\n", fp->path); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } /* fp->tbl.str_version = ntohl(fp->tbl.str_version); */ @@ -1013,6 +1098,10 @@ if (fp->datfd < 0 && (fp->datfd = open(fp->datfile, 0)) < 0) { perror(fp->datfile); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } } @@ -1111,6 +1200,10 @@ if (fp->inf == NULL && (fp->inf = fdopen(fp->fd, "r")) == NULL) { perror(fp->path); + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(1); } } @@ -1152,6 +1245,7 @@ unsigned char *sp; register FILEDESC *fp; int in_file, nchar; + unsigned char buf[BUFSIZ]; for (fp = list; fp != NULL; fp = fp->next) { @@ -1164,7 +1258,11 @@ open_fp(fp); sp = Fortbuf; in_file = FALSE; - while (fgets(sp, Fort_len, fp->inf) != NULL) + while (fgets(buf, sizeof buf, fp->inf) != NULL) { + /* FIXME(raorn): use ifdef's */ + if (fortune_iconv(cd, buf, strlen(buf), sp, Fort_len + 8 - (sp - Fortbuf))) + /* FIXME(raorn): should we give up on error? */ + break; if (!STR_ENDSTRING(sp, fp->tbl)) sp += strlen(sp); else @@ -1187,6 +1285,7 @@ } sp = Fortbuf; } + } } } @@ -1211,18 +1310,23 @@ void display(FILEDESC * fp) { register char *p, ch; + unsigned char buf[BUFSIZ]; unsigned char line[BUFSIZ]; open_fp(fp); fseek(fp->inf, (long) Seekpts[0], 0); - for (Fort_len = 0; fgets(line, sizeof line, fp->inf) != NULL && - !STR_ENDSTRING(line, fp->tbl); Fort_len++) + for (Fort_len = 0; fgets(buf, sizeof buf, fp->inf) != NULL; Fort_len++) { + /* FIXME(raorn): use ifdef's */ + if (fortune_iconv(cd, buf, strlen(buf), line, sizeof(line))) + break; + if (STR_ENDSTRING(line, fp->tbl)) + break; if (fp->tbl.str_flags & STR_ROTATED) for (p = line; (ch = *p); ++p) - if (isupper(ch)) + if (ch >= 'A' && ch <= 'Z') *p = 'A' + (ch - 'A' + 13) % 26; - else if (islower(ch)) + else if (ch >= 'a' && ch <= 'z') *p = 'a' + (ch - 'a' + 13) % 26; fputs(line, stdout); } @@ -1260,11 +1364,27 @@ int main(int ac, char *av[]) { + /* FIXME(raorn): use ifdef's */ + setlocale(LC_ALL, ""); + Codeset = nl_langinfo(CODESET); + + /* FIXME(raorn): use ifdef's */ + if (Codeset && *Codeset) + cd = iconv_open(Codeset, "UTF-8"); + getargs(ac, av); #ifndef NO_REGEX - if (Match) - exit(find_matches() != 0); + if (Match) { + int n; + + n = find_matches() != 0; + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } + exit(n); + } #endif init_prob(); if (Find_files) @@ -1273,6 +1393,11 @@ if (Equal_probs) calc_equal_probs(); print_list(File_list, 0); + + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(0); } srandom((int) (time((time_t *) NULL) + getpid())); @@ -1290,6 +1415,11 @@ fortlen(); sleep((unsigned int) max(Fort_len / CPERS, MINW)); } + + if (cd && cd != (iconv_t) -1) { + iconv_close(cd); + cd = NULL; + } exit(0); /* NOTREACHED */ } diff -urN fortune-mod-9708-orig/util/randstr.c fortune-mod-9708/util/randstr.c --- fortune-mod-9708-orig/util/randstr.c 2004-02-26 22:38:13 +0300 +++ fortune-mod-9708/util/randstr.c 2004-02-27 02:04:05 +0300 @@ -95,6 +95,11 @@ #include #include #include +/* FIXME(raorn): use ifdef's */ +#include +#include +#include +#include #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif /* MAXPATHLEN */ @@ -107,6 +112,9 @@ off_t pos, Seekpts[2]; /* seek pointers to fortunes */ +/* FIXME(raorn): use ifdef's */ +iconv_t cd = NULL; +char *Codeset = NULL; void getargs(int ac, char *av[]) { @@ -170,31 +178,94 @@ Seekpts[1] = ntohl(Seekpts[1]); } +int fortune_iconv(iconv_t _cd, char *inbuf, int inlen, char *outbuf, int outlen) +{ + char *outptr; + size_t n; + int needed_from; + + if (_cd && _cd == (iconv_t) -1) { + memmove(outbuf, inbuf, inlen); + return 0; + } + + outptr = outbuf; + while (inlen > 0) { + outptr = outbuf; + n = iconv (_cd, (char **) &inbuf, &inlen, &outptr, &outlen); + + if(inlen == 0) break; + + if (n != (size_t) - 1) { + n = iconv (_cd, NULL, NULL, &outptr, &outlen); + + break; + } + + if (errno != E2BIG) { + switch (errno) { + case EILSEQ: + case EINVAL: + needed_from = ((__gconv_t) _cd)->__steps->__min_needed_from; + outptr[0] = '?'; + outptr++; + outlen--; + inbuf += needed_from; + inlen -= needed_from; + break; + default: + return -1; + } + } else { + /* FIXME: no space left in output buffer */ + break; + } + } + outptr[0] = 0; + return 0; +} + void display(FILE * fp, STRFILE table) { register char *p, ch; + unsigned char buf[BUFSIZ]; unsigned char line[BUFSIZ]; int i; + /* FIXME(raorn): use ifdef's */ + if (Codeset && *Codeset) + cd = iconv_open(Codeset, "UTF-8"); + fseek(fp, (long) Seekpts[0], 0); - for (i = 0; fgets(line, sizeof line, fp) != NULL && - !STR_ENDSTRING(line, table); i++) + for (i = 0; fgets(buf, sizeof line, fp) != NULL; i++) { + /* FIXME(raorn): use ifdef's */ + if (fortune_iconv(cd, buf, strlen(buf), line, sizeof(line))) + break; + if (!STR_ENDSTRING(line, table)) + break; if (table.str_flags & STR_ROTATED) for (p = line; (ch = *p); ++p) - if (isupper(ch)) + if (ch >= 'A' && ch <= 'Z') *p = 'A' + (ch - 'A' + 13) % 26; - else if (islower(ch)) + else if (ch >= 'a' && ch <= 'z') *p = 'a' + (ch - 'a' + 13) % 26; fputs(line, stdout); } fflush(stdout); + + if (cd && cd != (iconv_t) -1) + iconv_close(cd); } int main(int ac, char **av) { static STRFILE tbl; /* description table */ + /* FIXME(raorn): use ifdef's */ + setlocale(LC_ALL, ""); + Codeset = nl_langinfo(CODESET); + getargs(ac, av); if ((Inf = fopen(Infile, "r")) == NULL) {