From: mike Date: Thu, 2 Feb 2006 20:38:29 +0000 (+0000) Subject: Add "executable" argument to cupsFileFind(), to only look for executable X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8be0ad4e4fd64b2980243aba302612a4e8c3a4ec;p=thirdparty%2Fcups.git Add "executable" argument to cupsFileFind(), to only look for executable files. Add filter cache to mimeLoad/Merge(). git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@5057 7a7537e8-13f0-0310-91df-b6672ffda945 --- diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c index 07a3b93220..56c9344f46 100644 --- a/cgi-bin/admin.c +++ b/cgi-bin/admin.c @@ -3088,15 +3088,15 @@ do_menu(http_t *http) /* I - HTTP connection */ * rpcclient... */ - if (cupsFileFind("smbclient", getenv("PATH"), line, sizeof(line)) && - cupsFileFind("rpcclient", getenv("PATH"), line, sizeof(line))) + if (cupsFileFind("smbclient", getenv("PATH"), 1, line, sizeof(line)) && + cupsFileFind("rpcclient", getenv("PATH"), 1, line, sizeof(line))) cgiSetVariable("HAVE_SAMBA", "Y"); else { - if (!cupsFileFind("smbclient", getenv("PATH"), line, sizeof(line))) + if (!cupsFileFind("smbclient", getenv("PATH"), 1, line, sizeof(line))) fputs("ERROR: smbclient not found!\n", stderr); - if (!cupsFileFind("rpcclient", getenv("PATH"), line, sizeof(line))) + if (!cupsFileFind("rpcclient", getenv("PATH"), 1, line, sizeof(line))) fputs("ERROR: rpcclient not found!\n", stderr); } } diff --git a/cups/file.c b/cups/file.c index 4456787d0c..a2ad0afadc 100644 --- a/cups/file.c +++ b/cups/file.c @@ -285,7 +285,8 @@ cupsFileEOF(cups_file_t *fp) /* I - CUPS file */ const char * /* O - Full path to file or NULL */ cupsFileFind(const char *filename, /* I - File to find */ const char *path, /* I - Colon/semicolon-separated path */ - char *buffer, /* I - Filename buffer */ + int executable, /* I - 1 = executable files, 0 = any file/dir */ + char *buffer, /* I - Filename buffer */ int bufsize) /* I - Size of filename buffer */ { char *bufptr, /* Current position in buffer */ @@ -330,7 +331,11 @@ cupsFileFind(const char *filename, /* I - File to find */ strlcpy(bufptr, filename, bufend - bufptr); +#ifdef WIN32 if (!access(buffer, 0)) +#else + if (!access(buffer, executable ? X_OK : 0)) +#endif /* WIN32 */ return (buffer); bufptr = buffer; diff --git a/cups/file.h b/cups/file.h index a4c4e29412..b007c2f434 100644 --- a/cups/file.h +++ b/cups/file.h @@ -75,7 +75,8 @@ extern int cupsFileClose(cups_file_t *fp); extern int cupsFileCompression(cups_file_t *fp); extern int cupsFileEOF(cups_file_t *fp); extern const char *cupsFileFind(const char *filename, const char *path, - char *buffer, int bufsize); + int executable, char *buffer, + int bufsize); extern int cupsFileFlush(cups_file_t *fp); extern int cupsFileGetChar(cups_file_t *fp); extern char *cupsFileGetConf(cups_file_t *fp, char *buf, size_t buflen, diff --git a/cups/testfile.c b/cups/testfile.c index 0aac563016..a3680c6e36 100644 --- a/cups/testfile.c +++ b/cups/testfile.c @@ -84,8 +84,8 @@ main(int argc, /* I - Number of command-line arguments */ */ fputs("cupsFileFind: ", stdout); - if (cupsFileFind("cat", "/bin", filename, sizeof(filename)) && - cupsFileFind("cat", "/bin:/usr/bin", filename, sizeof(filename))) + if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) && + cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename))) printf("PASS (%s)\n", filename); else { diff --git a/scheduler/mime.c b/scheduler/mime.c index e4ba69d4e6..2fb00ec7d6 100644 --- a/scheduler/mime.c +++ b/scheduler/mime.c @@ -28,7 +28,6 @@ * mimeDeleteType() - Delete a type from the MIME database. * mimeFirstFilter() - Get the first filter in the MIME database. * mimeFirstType() - Get the first type in the MIME database. - * mimeNextType() - Get the next type in the MIME database. * mimeLoad() - Create a new MIME database from disk. * mimeMerge() - Merge a MIME database from disk with the current one. * mimeNew() - Create a new, empty MIME database. @@ -36,9 +35,12 @@ * mimeNextType() - Get the next type in the MIME database. * mimeNumFilters() - Get the number of filters in a MIME database. * mimeNumTypes() - Get the number of types in a MIME database. - * load_types() - Load a xyz.types file... + * add_fcache() - Add a filter to the filter cache. + * compare_fcache() - Compare two filter cache entries. + * delete_fcache() - Free all memory used by the filter cache. * delete_rules() - Free all memory for the given rule tree. * load_convs() - Load a xyz.convs file... + * load_types() - Load a xyz.types file... */ /* @@ -54,14 +56,30 @@ #include "mime.h" +/* + * Local types... + */ + +typedef struct _mime_fcache_s /**** Filter cache structure ****/ +{ + char *name, /* Filter name */ + *path; /* Full path to filter if available */ +} _mime_fcache_t; + + /* * Local functions... */ -static void load_types(mime_t *mime, const char *filename); -static void load_convs(mime_t *mime, const char *filename, - const char *filterpath); +static const char *add_fcache(cups_array_t *filtercache, const char *name, + const char *filterpath); +static int compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b); +static void delete_fcache(cups_array_t *filtercache); static void delete_rules(mime_magic_t *rules); +static void load_convs(mime_t *mime, const char *filename, + const char *filterpath, + cups_array_t *filtercache); +static void load_types(mime_t *mime, const char *filename); /* @@ -192,6 +210,7 @@ mimeMerge(mime_t *mime, /* I - MIME database to add to */ cups_dir_t *dir; /* Directory */ cups_dentry_t *dent; /* Directory entry */ char filename[1024]; /* Full filename of types/converts file */ + cups_array_t *filtercache; /* Filter cache */ /* @@ -238,6 +257,8 @@ mimeMerge(mime_t *mime, /* I - MIME database to add to */ * Read all the .convs files... */ + filtercache = cupsArrayNew((cups_array_func_t)compare_fcache, NULL); + while ((dent = cupsDirRead(dir)) != NULL) { if (strlen(dent->filename) > 6 && @@ -248,10 +269,12 @@ mimeMerge(mime_t *mime, /* I - MIME database to add to */ */ snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); - load_convs(mime, filename, filterpath); + load_convs(mime, filename, filterpath, filtercache); } } + delete_fcache(filtercache); + cupsDirClose(dir); return (mime); @@ -326,94 +349,99 @@ mimeNumTypes(mime_t *mime) /* I - MIME database */ /* - * 'load_types()' - Load a xyz.types file... + * 'add_fcache()' - Add a filter to the filter cache. */ -static void -load_types(mime_t *mime, /* I - MIME database */ - const char *filename) /* I - Types file to load */ +static const char * /* O - Full path to filter or NULL */ +add_fcache(cups_array_t *filtercache, /* I - Filter cache */ + const char *name, /* I - Filter name */ + const char *filterpath) /* I - Filter path */ { - cups_file_t *fp; /* Types file */ - int linelen; /* Length of line */ - char line[65536], /* Input line from file */ - *lineptr, /* Current position in line */ - super[MIME_MAX_SUPER], /* Super-type name */ - type[MIME_MAX_TYPE], /* Type name */ - *temp; /* Temporary pointer */ - mime_type_t *typeptr; /* New MIME type */ + _mime_fcache_t key, /* Search key */ + *temp; /* New filter cache */ + char path[1024]; /* Full path to filter */ - /* - * First try to open the file... - */ + key.name = (char *)name; + if ((temp = (_mime_fcache_t *)cupsArrayFind(filtercache, &key)) != NULL) + return (temp->path); - if ((fp = cupsFileOpen(filename, "r")) == NULL) - return; + if ((temp = calloc(1, sizeof(_mime_fcache_t))) == NULL) + return (NULL); - /* - * Then read each line from the file, skipping any comments in the file... - */ + temp->name = strdup(name); - while (cupsFileGets(fp, line, sizeof(line)) != NULL) - { - /* - * Skip blank lines and lines starting with a #... - */ + if (cupsFileFind(name, filterpath, 1, path, sizeof(path))) + temp->path = strdup(path); - if (!line[0] || line[0] == '#') - continue; + cupsArrayAdd(filtercache, temp); - /* - * While the last character in the line is a backslash, continue on to the - * next line (and the next, etc.) - */ + return (temp->path); +} - linelen = strlen(line); - while (line[linelen - 1] == '\\') - { - linelen --; +/* + * 'compare_fcache()' - Compare two filter cache entries. + */ - if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL) - line[linelen] = '\0'; - else - linelen += strlen(line + linelen); - } +static int /* O - Result of comparison */ +compare_fcache(_mime_fcache_t *a, /* I - First entry */ + _mime_fcache_t *b) /* I - Second entry */ +{ + return (strcmp(a->name, b->name)); +} - /* - * Extract the super-type and type names from the beginning of the line. - */ - lineptr = line; - temp = super; +/* + * 'delete_fcache()' - Free all memory used by the filter cache. + */ - while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' && - (temp - super + 1) < MIME_MAX_SUPER) - *temp++ = tolower(*lineptr++ & 255); +static void +delete_fcache(cups_array_t *filtercache)/* I - Filter cache */ +{ + _mime_fcache_t *current; /* Current cache entry */ - *temp = '\0'; - if (*lineptr != '/') - continue; + for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache); + current; + current = (_mime_fcache_t *)cupsArrayNext(filtercache)) + { + free(current->name); - lineptr ++; - temp = type; + if (current->path) + free(current->path); - while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' && - *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE) - *temp++ = tolower(*lineptr++ & 255); + free(current); + } - *temp = '\0'; + cupsArrayDelete(filtercache); +} - /* - * Add the type and rules to the MIME database... - */ - typeptr = mimeAddType(mime, super, type); - mimeAddTypeRule(typeptr, lineptr); - } +/* + * 'delete_rules()' - Free all memory for the given rule tree. + */ - cupsFileClose(fp); +static void +delete_rules(mime_magic_t *rules) /* I - Rules to free */ +{ + mime_magic_t *next; /* Next rule to free */ + + + /* + * Free the rules list, descending recursively to free any child rules. + */ + + while (rules != NULL) + { + next = rules->next; + + if (rules->child != NULL) + delete_rules(rules->child); + + free(rules); + rules = next; + } } @@ -422,9 +450,10 @@ load_types(mime_t *mime, /* I - MIME database */ */ static void -load_convs(mime_t *mime, /* I - MIME database */ - const char *filename, /* I - Convs file to load */ - const char *filterpath) /* I - Path for filters */ +load_convs(mime_t *mime, /* I - MIME database */ + const char *filename, /* I - Convs file to load */ + const char *filterpath, /* I - Path for filters */ + cups_array_t *filtercache) /* I - Filter program cache */ { cups_file_t *fp; /* Convs file */ char line[1024], /* Input line from file */ @@ -436,9 +465,6 @@ load_convs(mime_t *mime, /* I - MIME database */ mime_type_t *temptype, /* MIME type looping var */ *dsttype; /* Destination MIME type */ int cost; /* Cost of filter */ -#ifndef WIN32 - char filterprog[1024]; /* Full path of filter... */ -#endif /* !WIN32 */ /* @@ -530,23 +556,15 @@ load_convs(mime_t *mime, /* I - MIME database */ filter = lineptr; -#ifndef WIN32 if (strcmp(filter, "-")) { /* * Verify that the filter exists and is executable... */ - if (filter[0] == '/') - strlcpy(filterprog, filter, sizeof(filterprog)); - else if (!cupsFileFind(filter, filterpath, filterprog, - sizeof(filterprog))) + if (!add_fcache(filtercache, filter, filterpath)) continue; - - if (access(filterprog, X_OK)) - continue; } -#endif /* !WIN32 */ /* * Finally, get the source super-type and type names from the beginning of @@ -601,29 +619,94 @@ load_convs(mime_t *mime, /* I - MIME database */ /* - * 'delete_rules()' - Free all memory for the given rule tree. + * 'load_types()' - Load a xyz.types file... */ static void -delete_rules(mime_magic_t *rules) /* I - Rules to free */ +load_types(mime_t *mime, /* I - MIME database */ + const char *filename) /* I - Types file to load */ { - mime_magic_t *next; /* Next rule to free */ + cups_file_t *fp; /* Types file */ + int linelen; /* Length of line */ + char line[65536], /* Input line from file */ + *lineptr, /* Current position in line */ + super[MIME_MAX_SUPER], /* Super-type name */ + type[MIME_MAX_TYPE], /* Type name */ + *temp; /* Temporary pointer */ + mime_type_t *typeptr; /* New MIME type */ /* - * Free the rules list, descending recursively to free any child rules. + * First try to open the file... */ - while (rules != NULL) + if ((fp = cupsFileOpen(filename, "r")) == NULL) + return; + + /* + * Then read each line from the file, skipping any comments in the file... + */ + + while (cupsFileGets(fp, line, sizeof(line)) != NULL) { - next = rules->next; + /* + * Skip blank lines and lines starting with a #... + */ - if (rules->child != NULL) - delete_rules(rules->child); + if (!line[0] || line[0] == '#') + continue; - free(rules); - rules = next; + /* + * While the last character in the line is a backslash, continue on to the + * next line (and the next, etc.) + */ + + linelen = strlen(line); + + while (line[linelen - 1] == '\\') + { + linelen --; + + if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL) + line[linelen] = '\0'; + else + linelen += strlen(line + linelen); + } + + /* + * Extract the super-type and type names from the beginning of the line. + */ + + lineptr = line; + temp = super; + + while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' && + (temp - super + 1) < MIME_MAX_SUPER) + *temp++ = tolower(*lineptr++ & 255); + + *temp = '\0'; + + if (*lineptr != '/') + continue; + + lineptr ++; + temp = type; + + while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' && + *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE) + *temp++ = tolower(*lineptr++ & 255); + + *temp = '\0'; + + /* + * Add the type and rules to the MIME database... + */ + + typeptr = mimeAddType(mime, super, type); + mimeAddTypeRule(typeptr, lineptr); } + + cupsFileClose(fp); }