Bug#539338: mkfontscale: add option to recurse subdirectories

2009-08-01 Thread Thomas Viehmann

Hi,

thanks, Julien, for the comments, and sorry about the half-baked patch...

Julien Cristau wrote:

+   && (stat(filename, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) {

this can lead to an infinite loop since you follow symlinks.  Juliusz
suggested limiting the recursion to something like 100.


Indeed. There would be an implicit upper bound of 2048 by the dsprintf 
implementation, but that's one more reason to check the return value and 
probably not good to rely on.


Please find attached a revised patch. The fixes to the manpage are 
mainly for reminding myself and I can split out the unrelated parts for 
cleaner commits.


Kind regards

T.
--
Thomas Viehmann, http://thomas.viehmann.net/
diff -Nru xfonts-utils-7.4+1/mkfontscale/mkfontscale.c xfonts-utils-7.4+1/mkfontscale/mkfontscale.c
--- xfonts-utils-7.4+1/mkfontscale/mkfontscale.c	2008-05-11 00:01:42.0 +0200
+++ xfonts-utils-7.4+1/mkfontscale/mkfontscale.c	2009-08-01 23:34:02.0 +0200
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -63,6 +64,8 @@
 #define MAXFONTNAMELEN 1024
 #endif
 
+#define MAXDEPTHINRECURSIVESCAN 100
+
 char *encodings_array[] =
 { "ascii-0",
   "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5",
@@ -103,6 +106,7 @@
 static FT_Library ft_library;
 static float bigEncodingFuzz = 0.02;
 
+static int recurse;
 static int relative;
 static int doScalable;
 static int doBitmaps;
@@ -118,8 +122,8 @@
 {
 fprintf(stderr, 
 "mkfontscale [ -b ] [ -s ] [ -o filename ] [-x suffix ]\n"
-"[ -a encoding ] [ -f fuzz ] [ -l ] "
-"[ -e directory ] [ -p prefix ] [ -n ] [ -r ] \n"
+"[ -a encoding ] [ -f fuzz ] [ -l ]\n"
+"[ -e directory ] [ -p prefix ] [ -n ] [ -r ] [ -R ] \n"
 "[-u] [-U] [ directory ]...\n");
 }
 
@@ -154,6 +158,7 @@
 doScalable = 1;
 onlyEncodings = 0;
 relative = 0;
+recurse = 0;
 reencodeLegacy = 1;
 encodingsToDo = NULL;
 
@@ -217,6 +222,9 @@
 } else if(strcmp(argv[argn], "-r") == 0) {
 relative = 1;
 argn++;
+} else if(strcmp(argv[argn], "-R") == 0) {
+recurse = 1;
+argn++;
 } else if(strcmp(argv[argn], "-l") == 0) {
 reencodeLegacy = !reencodeLegacy;
 argn++;
@@ -749,57 +757,20 @@
 return 0;
 }
 
+
 static int
-doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo)
+scanDirectory(char *dirname, char *dir_prefix, int xl, HashTablePtr entries, int depthtogo)
 {
-char *dirname, *fontscale_name, *filename, *encdir;
-FILE *fontscale, *encfile;
 DIR *dirp;
 struct dirent *entry;
+struct stat statbuf;
+ListPtr encoding, xlfd, lp;
+char* filename;
+char* prefixedname;
+int rc, found;
+int isBitmap=0;
 FT_Error ftrc;
 FT_Face face;
-ListPtr encoding, xlfd, lp;
-HashTablePtr entries;
-HashBucketPtr *array;
-int i, n, found, rc;
-int isBitmap=0,xl=0;
-
-if (exclusionSuffix)
-xl = strlen (exclusionSuffix);
-
-i = strlen(dirname_given);
-if(i == 0)
-dirname = dsprintf("./");
-else if(dirname_given[i - 1] != '/')
-dirname = dsprintf("%s/", dirname_given);
-else
-dirname = dsprintf("%s", dirname_given);
-
-if(dirname == NULL) {
-perror("dirname");
-exit(1);
-}
-
-if (onlyEncodings) 
-	goto encodings;
-
-entries = makeHashTable();
-if(doBitmaps && !doScalable) {
-readFontScale(entries, dirname);
-}
-
-if(strcmp(outfilename, "-") == 0)
-fontscale_name = NULL;
-else {
-if(outfilename[0] == '/')
-fontscale_name = dsprintf("%s", outfilename);
-else
-fontscale_name = dsprintf("%s%s", dirname, outfilename);
-if(fontscale_name == NULL) {
-perror("fontscale_name");
-exit(1);
-}
-}
 
 dirp = opendir(dirname);
 if(dirp == NULL) {
@@ -808,17 +779,6 @@
 return 0;
 }
 
-if(fontscale_name == NULL)
-fontscale = stdout;
-else
-fontscale = fopen(fontscale_name, "wb");
-
-if(fontscale == NULL) {
-fprintf(stderr, "%s: ", fontscale_name);
-perror("fopen(w)");
-return 0;
-}
-
 while((entry = readdir(dirp)) != NULL) {
 int have_face = 0;
 char *xlfd_name = NULL;
@@ -831,7 +791,33 @@
 	}
 
 filename = dsprintf("%s%s", dirname, entry->d_name);
-
+if (recurse && depthtogo>0 && strcmp(entry->d_name, ".") != 0
+	&& strcmp(entry->d_name, "..") != 0
+	&& stat(filename, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
+	char* prefix;
+	int retval;
+	free(filename);
+	filename = dsprintf("%s%s/", dirname, entry->d_name);
+	prefix = dsprintf("%s%s/", dir_prefix, entry->d_name);
+	if (filename == NULL || p

Bug#539338: mkfontscale: add option to recurse subdirectories

2009-07-31 Thread Julien Cristau
Hi Thomas,

a couple comments on the patch.

On Thu, Jul 30, 2009 at 21:00:05 +0200, Thomas Viehmann wrote:

> @@ -831,7 +789,24 @@
>   }
>  
>  filename = dsprintf("%s%s", dirname, entry->d_name);
> +if (recurse & (strcmp(entry->d_name, ".") != 0) && 
> (strcmp(entry->d_name, "..") != 0)
  ^^
  should be &&

> + && (stat(filename, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) {

this can lead to an infinite loop since you follow symlinks.  Juliusz
suggested limiting the recursion to something like 100.

> + char* prefix;
> + int retval;
> + free(filename);
> + filename = dsprintf("%s%s/", dirname, entry->d_name);
> + prefix = dsprintf("%s%s/", dir_prefix, entry->d_name);

probably need to check the return value of dsprintf here.

Cheers,
Julien



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Bug#539338: mkfontscale: add option to recurse subdirectories

2009-07-30 Thread Thomas Viehmann

X-Debbugs-CC: Juliusz Chroboczek 
Package: xfonts-utils
Version: 1:7.4+1
Severity: wishlist

Hi Juliusz, everyone,

in the medium run it might be nice to use /usr/share/fonts/truetype in 
the X font path. However, fonts seem to be organized into subdirectories.
To facilitate using the directory with adding only one element to the X 
font path, the attached patch implements recursive scanning of 
subdirectories in mkfontscale.

I appreciate feedback and if you could consider adopting it.

Acknowledgement: Julien Cristau answered questions on IRC, so if I have 
gotten anything right here, it's to his credit, all errors are my own.


Kind regards and thanks for your work on Debian and X

T.

P.S.: If this patch seems feasible (even if only in Debian), I would 
submit a follow-up to add a packaging system trigger to keep font 
information up to date in that directory.

--
Thomas Viehmann, http://thomas.viehmann.net/
diff -dur orig/xfonts-utils-7.4+1/mkfontscale/mkfontscale.c xfonts-utils-7.4+1/mkfontscale/mkfontscale.c
--- orig/xfonts-utils-7.4+1/mkfontscale/mkfontscale.c	2008-05-11 00:01:42.0 +0200
+++ xfonts-utils-7.4+1/mkfontscale/mkfontscale.c	2009-07-30 20:49:23.0 +0200
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -103,6 +104,7 @@
 static FT_Library ft_library;
 static float bigEncodingFuzz = 0.02;
 
+static int recurse;
 static int relative;
 static int doScalable;
 static int doBitmaps;
@@ -154,6 +156,7 @@
 doScalable = 1;
 onlyEncodings = 0;
 relative = 0;
+recurse = 0;
 reencodeLegacy = 1;
 encodingsToDo = NULL;
 
@@ -217,6 +220,9 @@
 } else if(strcmp(argv[argn], "-r") == 0) {
 relative = 1;
 argn++;
+} else if(strcmp(argv[argn], "-R") == 0) {
+recurse = 1;
+argn++;
 } else if(strcmp(argv[argn], "-l") == 0) {
 reencodeLegacy = !reencodeLegacy;
 argn++;
@@ -749,57 +755,20 @@
 return 0;
 }
 
+
 static int
-doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo)
+scanDirectory(char *dirname, char *dir_prefix, int xl, HashTablePtr entries)
 {
-char *dirname, *fontscale_name, *filename, *encdir;
-FILE *fontscale, *encfile;
 DIR *dirp;
 struct dirent *entry;
+struct stat statbuf;
+ListPtr encoding, xlfd, lp;
+char* filename;
+char* prefixedname;
+int rc, found;
+int isBitmap=0;
 FT_Error ftrc;
 FT_Face face;
-ListPtr encoding, xlfd, lp;
-HashTablePtr entries;
-HashBucketPtr *array;
-int i, n, found, rc;
-int isBitmap=0,xl=0;
-
-if (exclusionSuffix)
-xl = strlen (exclusionSuffix);
-
-i = strlen(dirname_given);
-if(i == 0)
-dirname = dsprintf("./");
-else if(dirname_given[i - 1] != '/')
-dirname = dsprintf("%s/", dirname_given);
-else
-dirname = dsprintf("%s", dirname_given);
-
-if(dirname == NULL) {
-perror("dirname");
-exit(1);
-}
-
-if (onlyEncodings) 
-	goto encodings;
-
-entries = makeHashTable();
-if(doBitmaps && !doScalable) {
-readFontScale(entries, dirname);
-}
-
-if(strcmp(outfilename, "-") == 0)
-fontscale_name = NULL;
-else {
-if(outfilename[0] == '/')
-fontscale_name = dsprintf("%s", outfilename);
-else
-fontscale_name = dsprintf("%s%s", dirname, outfilename);
-if(fontscale_name == NULL) {
-perror("fontscale_name");
-exit(1);
-}
-}
 
 dirp = opendir(dirname);
 if(dirp == NULL) {
@@ -808,17 +777,6 @@
 return 0;
 }
 
-if(fontscale_name == NULL)
-fontscale = stdout;
-else
-fontscale = fopen(fontscale_name, "wb");
-
-if(fontscale == NULL) {
-fprintf(stderr, "%s: ", fontscale_name);
-perror("fopen(w)");
-return 0;
-}
-
 while((entry = readdir(dirp)) != NULL) {
 int have_face = 0;
 char *xlfd_name = NULL;
@@ -831,7 +789,24 @@
 	}
 
 filename = dsprintf("%s%s", dirname, entry->d_name);
+if (recurse & (strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)
+	&& (stat(filename, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) {
+	char* prefix;
+	int retval;
+	free(filename);
+	filename = dsprintf("%s%s/", dirname, entry->d_name);
+	prefix = dsprintf("%s%s/", dir_prefix, entry->d_name);
+	retval = scanDirectory(filename, prefix, xl, entries);
+	free(filename);
+	free(prefix);
+	if (retval == 0) {
+	closedir(dirp);
+	return 0;
+	}
+	continue;
+	}   
 
+prefixedname = dsprintf("%s%s", dir_prefix, entry->d_name);
 if(doBitmaps)
 rc = bitmapIdentify(filename, &xlfd_name);
 else
@@ -892,7 +867,7 @@
 xlfd = listCons(s, xlfd);
 } else {
 /* Not a reencodable font -- skip all the r