X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fxmlconfig.c;h=a02e47e0ae57ab68f2666cf828939a07594a9dc9;hb=41d0a81c2a3f09701e8c694b520c8d900f6ac2f1;hp=64363522d2f55f8f6a5017edfcf42b8b3154fff6;hpb=10206ba17b3f685035418b2ab99b10ea261600e1;p=mesa.git diff --git a/src/util/xmlconfig.c b/src/util/xmlconfig.c index 64363522d2f..a02e47e0ae5 100644 --- a/src/util/xmlconfig.c +++ b/src/util/xmlconfig.c @@ -43,14 +43,26 @@ #include #include #include +#include "strndup.h" #include "xmlconfig.h" #include "u_process.h" +#include "os_file.h" /* For systems like Hurd */ #ifndef PATH_MAX #define PATH_MAX 4096 #endif +static bool +be_verbose(void) +{ + const char *s = getenv("MESA_DEBUG"); + if (!s) + return true; + + return strstr(s, "silent") == NULL; +} + /** \brief Find an option in an option cache with the name as key */ static uint32_t findOption(const driOptionCache *cache, const char *name) @@ -547,9 +559,11 @@ parseOptInfoAttr(struct OptInfoData *data, const XML_Char **attr) defaultVal = getenv (cache->info[opt].name); if (defaultVal != NULL) { /* don't use XML_WARNING, we want the user to see this! */ - fprintf (stderr, - "ATTENTION: default value of option %s overridden by environment.\n", - cache->info[opt].name); + if (be_verbose()) { + fprintf(stderr, + "ATTENTION: default value of option %s overridden by environment.\n", + cache->info[opt].name); + } } else defaultVal = attrVal[OA_DEFAULT]; if (!parseValue (&cache->values[opt], cache->info[opt].type, defaultVal)) @@ -701,7 +715,9 @@ struct OptConfData { const char *driverName, *execName; const char *kernelDriverName; const char *engineName; + const char *applicationName; uint32_t engineVersion; + uint32_t applicationVersion; uint32_t ignoringDevice; uint32_t ignoringApp; uint32_t inDriConf; @@ -767,13 +783,64 @@ parseAppAttr(struct OptConfData *data, const XML_Char **attr) { uint32_t i; const XML_Char *exec = NULL; + const XML_Char *sha1 = NULL; + const XML_Char *application_name_match = NULL; + const XML_Char *application_versions = NULL; + driOptionInfo version_ranges = { + .type = DRI_INT, + }; + for (i = 0; attr[i]; i += 2) { if (!strcmp (attr[i], "name")) /* not needed here */; else if (!strcmp (attr[i], "executable")) exec = attr[i+1]; + else if (!strcmp (attr[i], "sha1")) sha1 = attr[i+1]; + else if (!strcmp (attr[i], "application_name_match")) + application_name_match = attr[i+1]; + else if (!strcmp (attr[i], "application_versions")) + application_versions = attr[i+1]; else XML_WARNING("unknown application attribute: %s.", attr[i]); } - if (exec && strcmp (exec, data->execName)) + if (exec && strcmp (exec, data->execName)) { data->ignoringApp = data->inApp; + } else if (sha1) { + /* SHA1_DIGEST_STRING_LENGTH includes terminating null byte */ + if (strlen(sha1) != (SHA1_DIGEST_STRING_LENGTH - 1)) { + XML_WARNING("Incorrect sha1 application attribute"); + data->ignoringApp = data->inApp; + } else { + size_t len; + char* content; + char path[PATH_MAX]; + if (util_get_process_exec_path(path, ARRAY_SIZE(path)) > 0 && + (content = os_read_file(path, &len))) { + uint8_t sha1x[SHA1_DIGEST_LENGTH]; + char sha1s[SHA1_DIGEST_STRING_LENGTH]; + _mesa_sha1_compute(content, len, sha1x); + _mesa_sha1_format((char*) sha1s, sha1x); + free(content); + + if (strcmp(sha1, sha1s)) { + data->ignoringApp = data->inApp; + } + } else { + data->ignoringApp = data->inApp; + } + } + } else if (application_name_match) { + regex_t re; + + if (regcomp (&re, application_name_match, REG_EXTENDED|REG_NOSUB) == 0) { + if (regexec (&re, data->applicationName, 0, NULL, 0) == REG_NOMATCH) + data->ignoringApp = data->inApp; + regfree (&re); + } else + XML_WARNING ("Invalid application_name_match=\"%s\".", application_name_match); + } + if (application_versions) { + if (parseRanges (&version_ranges, application_versions) && + !valueInRanges (&version_ranges, data->applicationVersion)) + data->ignoringApp = data->inApp; + } } /** \brief Parse attributes of an application element. */ @@ -830,11 +897,14 @@ parseOptConfAttr(struct OptConfData *data, const XML_Char **attr) /* don't use XML_WARNING, drirc defines options for all drivers, * but not all drivers support them */ return; - else if (getenv (cache->info[opt].name)) + else if (getenv (cache->info[opt].name)) { /* don't use XML_WARNING, we want the user to see this! */ - fprintf (stderr, "ATTENTION: option value of option %s ignored.\n", - cache->info[opt].name); - else if (!parseValue (&cache->values[opt], cache->info[opt].type, value)) + if (be_verbose()) { + fprintf(stderr, + "ATTENTION: option value of option %s ignored.\n", + cache->info[opt].name); + } + } else if (!parseValue (&cache->values[opt], cache->info[opt].type, value)) XML_WARNING ("illegal option value: %s.", value); } } @@ -1059,6 +1129,7 @@ void driParseConfigFiles(driOptionCache *cache, const driOptionCache *info, int screenNum, const char *driverName, const char *kernelDriverName, + const char *applicationName, uint32_t applicationVersion, const char *engineName, uint32_t engineVersion) { char *home; @@ -1070,6 +1141,8 @@ driParseConfigFiles(driOptionCache *cache, const driOptionCache *info, userData.screenNum = screenNum; userData.driverName = driverName; userData.kernelDriverName = kernelDriverName; + userData.applicationName = applicationName ? applicationName : ""; + userData.applicationVersion = applicationVersion; userData.engineName = engineName ? engineName : ""; userData.engineVersion = engineVersion; userData.execName = util_get_process_name();