Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37729369
en ru br
Репозитории ALT
S:2.28.0-alt2
5.1: 1.99.1-alt4
4.1: 1.99.1-alt2
4.0: 1.0-ipl36mdk
3.0: 1.0-ipl36mdk
www.altlinux.org/Changes

Группа :: Игры/Прочее
Пакет: fortune-mod

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: fortune-mod-1.0-alt-utf-8-data.patch
Скачать


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	<ctype.h>
 #include	<stdlib.h>
 #include	<string.h>
+/* FIXME(raorn): use ifdef's */
+#include	<locale.h>
+#include	<langinfo.h>
+#include	<iconv.h>
+#include	<errno.h>
 
 /* 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	<string.h>
 #include	<unistd.h>
 #include	<time.h>
+/* FIXME(raorn): use ifdef's */
+#include	<locale.h>
+#include	<langinfo.h>
+#include	<iconv.h>
+#include	<errno.h>
 #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)
     {
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin