Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37569565
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.99.1-alt2.patch
Скачать


 Makefile              |    8 +-
 datfiles/Makefile     |    4 -
 datfiles/off/Makefile |    2 -
 datfiles/riddles      |    3 -
 fortune/fortune.c     |  194 +++++++++++++++++++++++++++++++-----------------
 util/randstr.c        |   79 +++++++++++++++++++-
 6 files changed, 203 insertions(+), 87 deletions(-)
diff --git a/Makefile b/Makefile
index 89e1385..4048d7b 100644
--- a/Makefile
+++ b/Makefile
@@ -62,11 +62,9 @@ REGEXDEFS=-DHAVE_REGEX_H -DBSD_REGEX -DHAVE_STDBOOL
 #
 REGEXLIBS=
 
-RECODELIBS=-lrecode
-
 DEFINES=-DFORTDIR="\"$(COOKIEDIR)\"" -DOFFDIR="\"$(OCOOKIEDIR)\"" -DLOCFORTDIR="\"$(LOCALDIR)\"" -DLOCOFFDIR="\"$(LOCALODIR)\""
-CFLAGS=-O2 $(DEFINES) -Wall -fomit-frame-pointer -pipe -fsigned-char
-LDFLAGS=-s
+CFLAGS=$(RPM_OPT_FLAGS) $(DEFINES) -Wall -fomit-frame-pointer -pipe -fsigned-char
+LDFLAGS=
 
 # The above flags are used by default; the debug flags are used when make
 # is called with a debug target, such as 'make debug'
@@ -103,7 +101,7 @@ debug: fortune-debug util-debug cookies-z
 fortune-bin:
 	cd fortune && $(MAKE) CC='$(CC)' \
 		    CFLAGS='$(CFLAGS) $(REGEXDEFS) -I../util'	\
-		    LDFLAGS='$(LDFLAGS)' LIBS='$(REGEXLIBS) $(RECODELIBS)'
+		    LDFLAGS='$(LDFLAGS)' LIBS='$(REGEXLIBS)'
 
 fortune-debug:
 	cd fortune && $(MAKE) CC='$(CC)' \
diff --git a/datfiles/Makefile b/datfiles/Makefile
index 1fb2b58..70a6e9e 100644
--- a/datfiles/Makefile
+++ b/datfiles/Makefile
@@ -46,9 +46,7 @@ cookies-stamp:
 	        if [ ! -f $$i.old ] ; then \
 	        	cp $$i $$i.old; \
 		fi; \
-	        recode latin1..u8 $$i ; \
 		$(STRFILE) $$i ; \
-		ln -s $$i $$i.u8 || exit $? ; \
 	    done
 	touch cookies-stamp
 
@@ -58,12 +56,10 @@ install: cookies-stamp
 	if [ $(WEB) = 1 ] ; then cd html && $(MAKE) install ; fi
 	for i in $(COOKIES) ; do \
 		install -m 0644 $$i $$i.dat $(COOKIEDIR) || exit $? ; \
-		cp -d $$i.u8 $(COOKIEDIR) ; \
 		done
 
 clean:
 	rm -f cookies-stamp *.dat
-	rm -f *.u8
 	cd off && $(MAKE) clean
 	cd html && $(MAKE) clean
 	for i in $(COOKIES) ; do \
diff --git a/datfiles/off/Makefile b/datfiles/off/Makefile
index 3a78738..896af7d 100644
--- a/datfiles/off/Makefile
+++ b/datfiles/off/Makefile
@@ -30,7 +30,6 @@ recoded-stamp:
 	        if [ ! -f unrotated/$$i.old ]; then \
 	    	    cp unrotated/$$i unrotated/$$i.old ; \
 		fi; \
-		recode latin1..u8 unrotated/$$i; \
 	    done
 	touch recoded-stamp
 	    
@@ -38,7 +37,6 @@ install:
 	install -m 0755 -d $(OCOOKIEDIR)
 	for i in $(OCOOKIES) ; \
 	    do install -m 0644 $$i $$i.dat $(OCOOKIEDIR) || exit $$? ; \
-	    cp -d $$i.u8 $(OCOOKIEDIR) ; \
 	done
 
 clean:
diff --git a/datfiles/riddles b/datfiles/riddles
index 7afbae5..54cabf3 100644
--- a/datfiles/riddles
+++ b/datfiles/riddles
@@ -419,9 +419,6 @@ A:	Nothing.
 Q:	What's a light-year?
 A:	One-third less calories than a regular year.
 %
-Q:	What's a WASP's idea of open-mindedness?
-A:	Dating a Canadian.
-%
 Q:	What's buried in Grant's tomb?
 A:	A corpse.
 %
diff --git a/fortune/fortune.c b/fortune/fortune.c
index 05520fa..80717ee 100644
--- a/fortune/fortune.c
+++ b/fortune/fortune.c
@@ -140,8 +140,7 @@ typedef enum
 #include	<errno.h>
 #include	<locale.h>
 #include	<langinfo.h>
-#include 	<recode.h>
-
+#include	<iconv.h>
 
 /* This makes GNU libc to prototype the BSD regex functions */
 #ifdef BSD_REGEX
@@ -189,7 +188,6 @@ typedef struct fd
     char *datfile, *posfile;
     bool read_tbl;
     bool was_pos_file;
-    bool utf8_charset;
     STRFILE tbl;
     int num_children;
     struct fd *child, *parent;
@@ -252,8 +250,8 @@ regex_t Re_pat;
 
 #endif /* BSD_REGEX */
 
-RECODE_REQUEST request;
-RECODE_OUTER outer;
+iconv_t cd = NULL;
+char *Codeset = NULL;
 
 int add_dir(register FILEDESC *);
 
@@ -287,6 +285,57 @@ void usage(void)
 
 
 /*
+ * 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
@@ -394,6 +443,11 @@ void *do_malloc(unsigned int size)
     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;
@@ -673,15 +727,6 @@ int add_file(int percent, register char *file, char *dir,
     fp->path = do_malloc (strlen (path) + 1);
     strncpy (fp->path, path, strlen (path) + 1);
 
-    //FIXME
-    fp->utf8_charset = FALSE;
-    testpath = do_malloc(strlen (path) + 4);
-    sprintf(testpath, "%s.u8", path);
-//    fprintf(stderr, "State mal: %s\n", testpath);
-    if(stat(testpath, &statbuf) == 0)
-	fp->utf8_charset = TRUE;
-//    fprintf(stderr, "Is utf8?: %i\n",	fp->utf8_charset );
-
     fp->parent = parent;
 
     if ((isdir && !add_dir(fp)) ||
@@ -1135,6 +1180,10 @@ void init_prob(void)
     {
 	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)
@@ -1142,12 +1191,20 @@ void init_prob(void)
 	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 */
@@ -1243,6 +1300,10 @@ void get_tbl(FILEDESC * fp)
 	if ((fd = open(fp->datfile, O_RDONLY)) < 0)
 	{
 	    perror(fp->datfile);
+	    if (cd && cd != (iconv_t) -1) {
+		iconv_close(cd);
+		cd = NULL;
+	    }
 	    exit(1);
 	}
 	if (read(fd, &fp->tbl.str_version, sizeof fp->tbl.str_version) !=
@@ -1250,6 +1311,10 @@ void get_tbl(FILEDESC * fp)
 	{
 	    fprintf(stderr,
 		    "fortune: %s corrupted\n", fp->path);
+	    if (cd && cd != (iconv_t) -1) {
+		iconv_close(cd);
+		cd = NULL;
+	    }
 	    exit(1);
 	}
 	if (read(fd, &fp->tbl.str_numstr, sizeof fp->tbl.str_numstr) !=
@@ -1376,6 +1441,10 @@ void open_dat(FILEDESC * fp)
     if (fp->datfd < 0 && (fp->datfd = open(fp->datfile, O_RDONLY)) < 0)
     {
 	perror(fp->datfile);
+	if (cd && cd != (iconv_t) -1) {
+	    iconv_close(cd);
+	    cd = NULL;
+	}
 	exit(1);
     }
 }
@@ -1480,6 +1549,10 @@ void open_fp(FILEDESC * fp)
     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);
     }
 }
@@ -1523,7 +1596,7 @@ void matches_in_list(FILEDESC * list)
     unsigned char ch; /* -allover */
     register FILEDESC *fp;
     int in_file, nchar;
-    char *output;
+    unsigned char buf[BUFSIZ];
 
     for (fp = list; fp != NULL; fp = fp->next)
     {
@@ -1536,7 +1609,9 @@ void matches_in_list(FILEDESC * list)
 	open_fp(fp);
 	sp = Fortbuf;
 	in_file = FALSE;
-	while (fgets(sp, Fort_len, fp->inf) != NULL)
+	while (fgets(buf, sizeof buf, fp->inf) != NULL) {
+	    if (fortune_iconv(cd, buf, strlen(buf), sp, Fort_len + 8 - (sp - Fortbuf)))
+		break;
 	    if (!STR_ENDSTRING(sp, fp->tbl))
 		sp += strlen(sp);
 	    else
@@ -1544,29 +1619,10 @@ void matches_in_list(FILEDESC * list)
 		*sp = '\0';
 		nchar = sp - Fortbuf;
 
-		if (fp->utf8_charset) 
-		{
-		    output = recode_string (request, Fortbuf);
-		} else {
-		    output = Fortbuf;
-		}
-		/* Should maybe rot13 Fortbuf -allover */
-
-                if(fp->tbl.str_flags & STR_ROTATED)
-		{
-                    for (p = output; (ch = *p); ++p)
-		    {
-                        if (isupper(ch) && isascii(ch))
-                            *p = 'A' + (ch - 'A' + 13) % 26;
-                        else if (islower(ch) && isascii(ch))
-                            *p = 'a' + (ch - 'a' + 13) % 26;
-		    }
-		}
- 
 		DPRINTF(1, (stdout, "nchar = %d\n", nchar));
 		if ( (nchar < SLEN || !Short_only) &&
 			(nchar > SLEN || !Long_only) &&
-			RE_EXEC(output) )
+			RE_EXEC(Fortbuf) )
 		{
 		    if (!in_file)
 		    {
@@ -1574,15 +1630,13 @@ void matches_in_list(FILEDESC * list)
 			Found_one = TRUE;
 			in_file = TRUE;
 		    }
-		    fputs (output, stdout);
+		    fwrite(Fortbuf, 1, sp - Fortbuf, stdout);
 		    printf("%c\n", fp->tbl.str_delim);
 		}
 
-		if (fp->utf8_charset)
-		  free (output);
-
 		sp = Fortbuf;
 	    }
+	}
     }
 }
 
@@ -1607,15 +1661,18 @@ int find_matches(void)
 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);
     if (Show_filename)
 	printf ("(%s)\n%%\n", fp->name);
-    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 &&
+	 !STR_ENDSTRING(buf, fp->tbl); Fort_len++)
     {
+	if (fortune_iconv(cd, buf, strlen(buf), line, sizeof(line)))
+	    break;
 	if (fp->tbl.str_flags & STR_ROTATED)
 	{
 	    for (p = line; (ch = *p); ++p)
@@ -1626,20 +1683,9 @@ void display(FILEDESC * fp)
 		    *p = 'a' + (ch - 'a' + 13) % 26;
 	    }
 	}
-	if(fp->utf8_charset) {
-	    char *output;
-	    output = recode_string (request, line);
-	    fputs(output, stdout);
-	    free(output);
-	}
-	else
-	    fputs(line, stdout);
+	fputs(line, stdout);
     }
     fflush(stdout);
-
-    if(fp->utf8_charset) {
-	recode_delete_request(request);
-    }	
 }
 
 /*
@@ -1673,25 +1719,25 @@ int max(register int i, register int j)
 
 int main(int ac, char *av[])
 {
-    char *ctype, *crequest;
-    getargs(ac, av);
+    setlocale(LC_ALL, "");
+    Codeset = nl_langinfo(CODESET);
 
-    outer = recode_new_outer(true);
-    request = recode_new_request (outer);
+    if (Codeset && *Codeset)
+	cd = iconv_open(Codeset, "UTF-8");
 
-    setlocale(LC_ALL,"");
-    ctype = nl_langinfo(CODESET);
-    if(strcmp(ctype,"ANSI_X3.4-1968") == 0)
-        ctype="ISO-8859-1";
-	
-    crequest = malloc(strlen(ctype) + 7 + 1);
-    sprintf(crequest, "UTF-8..%s", ctype);
-    recode_scan_request (request, crequest);
-    free(crequest);
+    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)
@@ -1700,6 +1746,11 @@ int main(int ac, char *av[])
 	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()));
@@ -1717,6 +1768,11 @@ int main(int ac, char *av[])
         fortlen();
 	sleep((unsigned int) max(Fort_len / CPERS, MINW));
     }
+
+    if (cd && cd != (iconv_t) -1) {
+	iconv_close(cd);
+	cd = NULL;
+    }
     exit(0);
     /* NOTREACHED */
 }
diff --git a/tools/.gitignore b/tools/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/util/randstr.c b/util/randstr.c
index 3300715..52529cd 100644
--- a/util/randstr.c
+++ b/util/randstr.c
@@ -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 @@ FILE *Inf, *Dataf, *Outf;
 
 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 @@ void get_fort(STRFILE fp)
     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