From 540db0b3e7e829e71c4c32a4bcc44d4d0addcfb7 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 20 Nov 2014 01:54:12 -0600 Subject: [PATCH] Add very early support for compressed PPDs to make_driver_db_cups This relates to Bug 2191 --- tdecore/tdeapplication.cpp | 6 +- tdeprint/cups/make_driver_db_cups.c | 284 +++++++++++++++++++--------- tdeprint/driverparse.c | 43 ++++- tdeprint/driverparse.h | 5 +- tdeprint/lpr/make_driver_db_lpr.c | 24 ++- 5 files changed, 262 insertions(+), 100 deletions(-) diff --git a/tdecore/tdeapplication.cpp b/tdecore/tdeapplication.cpp index 13fd76a2e..0f84807df 100644 --- a/tdecore/tdeapplication.cpp +++ b/tdecore/tdeapplication.cpp @@ -1925,7 +1925,7 @@ bool TDEApplication::isCompositionManagerAvailable() { char uidstr[sizeof(uid_t)*8+1]; sprintf(uidstr, "%d", getuid()); int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; - filename = (char*)malloc(n*sizeof(char)); + filename = (char*)malloc(n*sizeof(char)+1); memset(filename,0,n); strcat(filename, P_tmpdir); strcat(filename, "/."); @@ -1994,7 +1994,7 @@ bool TDEApplication::detectCompositionManagerAvailable(bool force_available, boo char uidstr[sizeof(uid_t)*8+1]; sprintf(uidstr, "%d", getuid()); int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; - filename = (char*)malloc(n*sizeof(char)); + filename = (char*)malloc(n*sizeof(char)+1); memset(filename,0,n); strcat(filename, P_tmpdir); strcat(filename, "/."); @@ -2117,7 +2117,7 @@ bool TDEApplication::detectCompositionManagerAvailable(bool force_available, boo char uidstr[sizeof(uid_t)*8+1]; sprintf(uidstr, "%d", getuid()); int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; - filename = (char*)malloc(n*sizeof(char)); + filename = (char*)malloc(n*sizeof(char)+1); memset(filename,0,n); strcat(filename, P_tmpdir); strcat(filename, "/."); diff --git a/tdeprint/cups/make_driver_db_cups.c b/tdeprint/cups/make_driver_db_cups.c index b39dda8de..bba9adce2 100644 --- a/tdeprint/cups/make_driver_db_cups.c +++ b/tdeprint/cups/make_driver_db_cups.c @@ -1,3 +1,23 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul + * Copyright (c) 2014 Timothy Pearson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + **/ + #include #include #include @@ -11,65 +31,163 @@ #include "driverparse.h" +#define PROCESS_PPD_FILE_CONTENTS \ + memset(value,0,256); \ + c1 = strchr(line,':'); \ + if (c1) \ + { \ + c2 = strchr(c1,'"'); \ + if (c2) \ + { \ + c2++; \ + c1 = strchr(c2,'"'); \ + if (c1) strlcpy(value,c2,c1-c2+1); \ + } \ + else \ + { \ + c1++; \ + while (*c1 && isspace(*c1)) \ + c1++; \ + if (!*c1) \ + continue; \ + c2 = line+strlen(line)-1; /* point to \n */ \ + while (*c2 && isspace(*c2)) \ + c2--; \ + strlcpy(value,c1,c2-c1+2); \ + } \ + } \ + count++; \ + if (strncmp(line,"*Manufacturer:",14) == 0) fprintf(output_file,"MANUFACTURER=%s\n",value); \ + else if (strncmp(line,"*ShortNickName:",15) == 0) fprintf(output_file,"MODEL=%s\n",value); \ + else if (strncmp(line,"*ModelName:",11) == 0) fprintf(output_file,"MODELNAME=%s\n",value); \ + else if (strncmp(line,"*NickName:",10) == 0) strncat(desc,value,255-strlen(desc)); \ + else if (strncmp(line,"*pnpManufacturer:",17) == 0) fprintf(output_file,"PNPMANUFACTURER=%s\n",value); \ + else if (strncmp(line,"*pnpModel:",10) == 0) fprintf(output_file,"PNPMODEL=%s\n",value); \ + else if (strncmp(line,"*LanguageVersion:",17) == 0) strncat(langver,value,63-strlen(langver)); \ + else count--; \ + /* Either we got everything we needed, or we encountered an "OpenUI" directive \ + * and it's reasonable to assume that there's no needed info further in the file, \ + * just stop here */ \ + if (count >= 7 || strncmp(line, "*OpenUI", 7) == 0) \ + { \ + if (strlen(langver) > 0) \ + { \ + strncat(desc, " [", 255-strlen(desc)); \ + strncat(desc, langver, 255-strlen(desc)); \ + strncat(desc, "]", 255-strlen(desc)); \ + } \ + if (strlen(desc) > 0) \ + fprintf(output_file, "DESCRIPTION=%s\n", desc); \ + break; \ + } + void initPpd(const char *dirname) { - DIR *dir = opendir(dirname); - struct dirent *entry; - char buffer[4096] = {0}; - char drFile[256]; - int len = strlen(dirname); - - if (dir == NULL) - { + struct stat stat_res; + if (stat(dirname, &stat_res) == -1) { fprintf(stderr, "Can't open drivers directory : %s\n", dirname); return; } - while ((entry=readdir(dir)) != NULL) - { - if (strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) + + if (S_ISDIR(stat_res.st_mode)) { + DIR *dir = opendir(dirname); + struct dirent *entry; + char buffer[4096] = {0}; + char drFile[256]; + int len = strlen(dirname); + + if (dir == NULL) { - continue; + fprintf(stderr, "Can't open drivers directory : %s\n", dirname); + return; } - if (len+strlen(entry->d_name)+1 < 4096) + while ((entry=readdir(dir)) != NULL) { - struct stat st; - - strcpy(buffer,dirname); - strcat(buffer,"/"); - strcat(buffer,entry->d_name); - if (stat(buffer,&st) == 0) + if (strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) { - if (S_ISDIR(st.st_mode)) - { - initPpd(buffer); - } - else if (S_ISREG(st.st_mode)) + continue; + } + if (len+strlen(entry->d_name)+1 < 4096) + { + struct stat st; + + strcpy(buffer,dirname); + strcat(buffer,"/"); + strcat(buffer,entry->d_name); + if (stat(buffer,&st) == 0) { - char *c = strrchr(buffer,'.'); - snprintf(drFile, 255, "ppd:%s", buffer); - if (c && strncmp(c,".ppd",4) == 0) + if (S_ISDIR(st.st_mode)) { - addFile(drFile); + initPpd(buffer); } - else if (c && strncmp(c, ".gz", 3) == 0) - { /* keep also compressed driver files */ - while (c != buffer) + else if (S_ISREG(st.st_mode)) + { + char *c = strrchr(buffer,'.'); + snprintf(drFile, 255, "ppd:%s", buffer); + if (c && strncmp(c,".ppd",4) == 0) { - if (*(--c) == '.') break; + addFile(drFile, ""); } - if (*c == '.' && strncmp(c, ".ppd",4) == 0) - { - addFile(drFile); + else if (c && strncmp(c, ".gz", 3) == 0) + { /* keep also compressed driver files */ + while (c != buffer) + { + if (*(--c) == '.') break; + } + if (*c == '.' && strncmp(c, ".ppd",4) == 0) + { + addFile(drFile, ""); + } } } } } } + closedir(dir); + } + else if (access(dirname, X_OK) != -1) { + char *filename; + int n = strlen(dirname)+strlen(" list"); + filename = (char*)malloc(n*sizeof(char)+1); + memset(filename,0,n); + strcat(filename, dirname); + strcat(filename, " list"); + + FILE* file = popen(filename, "r"); + if (file) { + char * line = NULL; + size_t len = 0; + ssize_t read; + while ((read = getline(&line, &len, file)) != -1) { + char * pos1 = strstr(line, "\""); + if (pos1 >= 0) { + char * pos2 = strstr(pos1 + 1, "\""); + if (pos2 >= 0) { + *pos2 = 0; + addFile(line+1, dirname); + } + } + } + if (line) { + free(line); + } + + pclose(file); + } + else { + fprintf(stderr, "Can't execute compressed driver handler : %s\n", dirname); + } + + free(filename); + filename = NULL; + } + else { + fprintf(stderr, "Can't open drivers directory : %s\n", dirname); + return; } - closedir(dir); } -int parsePpdFile(const char *filename, FILE *output_file) +int parsePpdFile(const char *filename, const char *origin, FILE *output_file) { gzFile ppd_file; char line[4096], value[256], langver[64] = {0}, desc[256] = {0}; @@ -86,54 +204,7 @@ int parsePpdFile(const char *filename, FILE *output_file) while (gzgets(ppd_file,line,4095) != Z_NULL) { - memset(value,0,256); - c1 = strchr(line,':'); - if (c1) - { - c2 = strchr(c1,'"'); - if (c2) - { - c2++; - c1 = strchr(c2,'"'); - if (c1) strlcpy(value,c2,c1-c2+1); - } - else - { - c1++; - while (*c1 && isspace(*c1)) - c1++; - if (!*c1) - continue; - c2 = line+strlen(line)-1; /* point to \n */ - while (*c2 && isspace(*c2)) - c2--; - strlcpy(value,c1,c2-c1+2); - } - } - count++; - if (strncmp(line,"*Manufacturer:",14) == 0) fprintf(output_file,"MANUFACTURER=%s\n",value); - else if (strncmp(line,"*ShortNickName:",15) == 0) fprintf(output_file,"MODEL=%s\n",value); - else if (strncmp(line,"*ModelName:",11) == 0) fprintf(output_file,"MODELNAME=%s\n",value); - else if (strncmp(line,"*NickName:",10) == 0) strncat(desc,value,255-strlen(desc)); - else if (strncmp(line,"*pnpManufacturer:",17) == 0) fprintf(output_file,"PNPMANUFACTURER=%s\n",value); - else if (strncmp(line,"*pnpModel:",10) == 0) fprintf(output_file,"PNPMODEL=%s\n",value); - else if (strncmp(line,"*LanguageVersion:",17) == 0) strncat(langver,value,63-strlen(langver)); - else count--; - /* Either we got everything we needed, or we encountered an "OpenUI" directive - * and it's reasonable to assume that there's no needed info further in the file, - * just stop here */ - if (count >= 7 || strncmp(line, "*OpenUI", 7) == 0) - { - if (strlen(langver) > 0) - { - strncat(desc, " [", 255-strlen(desc)); - strncat(desc, langver, 255-strlen(desc)); - strncat(desc, "]", 255-strlen(desc)); - } - if (strlen(desc) > 0) - fprintf(output_file, "DESCRIPTION=%s\n", desc); - break; - } + PROCESS_PPD_FILE_CONTENTS } fprintf(output_file,"\n"); @@ -141,9 +212,52 @@ int parsePpdFile(const char *filename, FILE *output_file) return 1; } +int parseCompressedPpdFile(const char *ppdfilename, const char *origin, FILE *output_file) +{ + char value[256], langver[64] = {0}, desc[256] = {0}; + char *c1, *c2; + int count = 0; + + char *filename; + int n = strlen(origin)+strlen(" cat ")+strlen(ppdfilename); + filename = (char*)malloc(n*sizeof(char)+1); + memset(filename,0,n); + strcat(filename, origin); + strcat(filename, " cat "); + strcat(filename, ppdfilename); + + FILE* file = popen(filename, "r"); + if (file) { + char * line = NULL; + size_t len = 0; + ssize_t read; + + fprintf(output_file,"FILE=foomatic-db-compressed-ppds:%s\n",ppdfilename); + + while ((read = getline(&line, &len, file)) != -1) { + PROCESS_PPD_FILE_CONTENTS + } + if (line) { + free(line); + } + + pclose(file); + } + else { + fprintf(stderr, "Can't open driver file : %s\n", ppdfilename); + return 0; + } + + free(filename); + filename = NULL; + + return 1; +} + int main(int argc, char *argv[]) { registerHandler("ppd:", initPpd, parsePpdFile); + registerHandler("foomatic-db-compressed-ppds:", initPpd, parseCompressedPpdFile); initFoomatic(); return execute(argc, argv); } diff --git a/tdeprint/driverparse.c b/tdeprint/driverparse.c index 2b7a93d60..8d850b837 100644 --- a/tdeprint/driverparse.c +++ b/tdeprint/driverparse.c @@ -1,3 +1,23 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul + * Copyright (c) 2014 Timothy Pearson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + **/ + #include "driverparse.h" #include @@ -9,15 +29,16 @@ #include char **files = NULL; +char **fileorigins = NULL; int nfiles = 0, maxfiles = 0; int nhandlers = 0, maxhandlers = 0; int nlibs = 0, maxlibs = 0; typedef struct { void (*init)(const char*); - int (*parse)(const char*, FILE*); + int (*parse)(const char*, const char*, FILE*); char *name; - int namelen; + int namelen; } handler; handler **handlers = NULL; void **libs = NULL; @@ -39,7 +60,7 @@ void freeHandlers(void) free(handlers); } -void registerHandler(const char *name, void(*initf)(const char*), int(*parsef)(const char*, FILE*)) +void registerHandler(const char *name, void(*initf)(const char*), int(*parsef)(const char*, const char*, FILE*)) { handler *h = (handler*)malloc(sizeof(handler)); h->init = initf; @@ -88,6 +109,7 @@ void initFiles(void) { maxfiles = 100; files = (char**)malloc(sizeof(char*) * maxfiles); + fileorigins = (char**)malloc(sizeof(char*) * maxfiles); } void freeFiles(void) @@ -95,7 +117,9 @@ void freeFiles(void) int i; for (i=0; iname, handlers[hi]->namelen) == 0) { - handlers[hi]->parse(files[i]+handlers[hi]->namelen, dbFile); + handlers[hi]->parse(files[i]+handlers[hi]->namelen, fileorigins[i], dbFile); break; } fprintf(stdout, "%d\n", i); diff --git a/tdeprint/driverparse.h b/tdeprint/driverparse.h index 775c81187..3e0d5d2fd 100644 --- a/tdeprint/driverparse.h +++ b/tdeprint/driverparse.h @@ -1,6 +1,7 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul + * Copyright (c) 2014 Timothy Pearson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,9 +23,9 @@ #include -void registerHandler(const char *name, void(*initf)(const char*), int(*parsef)(const char*, FILE*)); +void registerHandler(const char *name, void(*initf)(const char*), int(*parsef)(const char*, const char*, FILE*)); void initFoomatic(void); int execute(int argc, char *argv[]); -void addFile(const char *filename); +void addFile(const char *filename, const char *origin); #endif diff --git a/tdeprint/lpr/make_driver_db_lpr.c b/tdeprint/lpr/make_driver_db_lpr.c index fabbcb2fe..17fa25bf5 100644 --- a/tdeprint/lpr/make_driver_db_lpr.c +++ b/tdeprint/lpr/make_driver_db_lpr.c @@ -1,3 +1,23 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul + * Copyright (c) 2014 Timothy Pearson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + **/ + #include #include #include @@ -94,7 +114,7 @@ void initAps(const char *base) gsversion = 1; } snprintf(drFile, 256, "apsfilter:%s/%s", base, d->d_name); - addFile(drFile); + addFile(drFile, ""); } closedir(apsdir); } @@ -179,7 +199,7 @@ void initIfhp(const char *base) snprintf(path, 255, "lprngtool:%s/printerdb", base); if (access(path+10, R_OK) == 0) { - addFile(path); + addFile(path, ""); } }