#include "ipp-var.h"
void
ippGetAttributes(ipp_t *request,
const char *directory,
const char *tmpl,
const char *lang)
{
int num_attrs;
char *attrs[1000];
int i;
char filename[1024],
locale[16];
FILE *in;
int ch;
char name[255],
*nameptr;
if (lang != NULL)
{
for (i = 0; lang[i] && i < 15; i ++)
if (isalnum(lang[i]))
locale[i] = tolower(lang[i]);
else
locale[i] = '_';
locale[i] = '\0';
}
else
locale[0] = '\0';
snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
if (access(filename, 0))
{
locale[2] = '\0';
snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
if (access(filename, 0))
snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl);
}
if ((in = fopen(filename, "r")) == NULL)
return;
num_attrs = 0;
while ((ch = getc(in)) != EOF)
if (ch == '\\')
getc(in);
else if (ch == '{' && num_attrs < (sizeof(attrs) / sizeof(attrs[0])))
{
for (nameptr = name; (ch = getc(in)) != EOF;)
if (strchr("}]<>=! \t\n", ch))
break;
else if (nameptr > name && ch == '?')
break;
else if (nameptr < (name + sizeof(name) - 1))
{
if (ch == '_')
*nameptr++ = '-';
else
*nameptr++ = ch;
}
*nameptr = '\0';
for (i = 0; i < num_attrs; i ++)
if (!strcmp(attrs[i], name))
break;
if (i >= num_attrs)
{
attrs[num_attrs] = strdup(name);
num_attrs ++;
}
}
if (num_attrs > 0)
{
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes", num_attrs, NULL, (const char **)attrs);
for (i = 0; i < num_attrs; i ++)
free(attrs[i]);
}
}
char *
ippGetTemplateDir(void)
{
const char *datadir;
static char templates[1024] = "";
if (!templates[0])
{
if ((datadir = getenv("CUPS_DATADIR")) == NULL)
datadir = CUPS_DATADIR;
snprintf(templates, sizeof(templates), "%s/templates", datadir);
}
return (templates);
}
void
ippSetServerVersion(void)
{
cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME"));
cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER"));
cgiSetVariable("CUPS_VERSION", CUPS_SVERSION);
#ifdef LC_TIME
setlocale(LC_TIME, "");
#endif
}
void
ippSetCGIVars(ipp_t *response,
const char *filter_name,
const char *filter_value,
const char *prefix,
int parent_el)
{
int element;
ipp_attribute_t *attr,
*filter;
int i;
char name[1024],
*nameptr,
value[16384],
*valptr;
char method[HTTP_MAX_URI],
username[HTTP_MAX_URI],
hostname[HTTP_MAX_URI],
rawresource[HTTP_MAX_URI],
resource[HTTP_MAX_URI],
uri[HTTP_MAX_URI],
*rawptr,
*resptr;
int port;
int ishttps;
const char *server;
char servername[1024];
struct tm *date;
static const char hexchars[] = "0123456789ABCDEF";
DEBUG_printf(("<P>ippSetCGIVars(response=%p, filter_name=\"%s\", filter_value=\"%s\", prefix=\"%s\")\n",
response, filter_name, filter_value, prefix));
if (!prefix)
ippSetServerVersion();
server = getenv("SERVER_NAME");
gethostname(servername, sizeof(servername));
ishttps = getenv("HTTPS") != NULL;
attr = response->attrs;
if (!prefix)
while (attr && attr->group_tag == IPP_TAG_OPERATION)
attr = attr->next;
for (element = parent_el; attr != NULL; attr = attr->next, element ++)
{
if (filter_name)
{
for (filter = attr;
filter != NULL && filter->group_tag != IPP_TAG_ZERO;
filter = filter->next)
if (filter->name && strcmp(filter->name, filter_name) == 0 &&
(filter->value_tag == IPP_TAG_STRING ||
(filter->value_tag >= IPP_TAG_TEXTLANG &&
filter->value_tag <= IPP_TAG_MIMETYPE)) &&
filter->values[0].string.text != NULL &&
strcasecmp(filter->values[0].string.text, filter_value) == 0)
break;
if (!filter)
return;
if (filter->group_tag == IPP_TAG_ZERO)
{
attr = filter;
element --;
continue;
}
}
for (; attr != NULL && attr->group_tag != IPP_TAG_ZERO; attr = attr->next)
{
if (attr->name == NULL)
continue;
if (prefix)
{
snprintf(name, sizeof(name), "%s.", prefix);
nameptr = name + strlen(name);
}
else
nameptr = name;
for (i = 0; attr->name[i] && nameptr < (name + sizeof(name) - 1); i ++)
if (attr->name[i] == '-')
*nameptr++ = '_';
else
*nameptr++ = attr->name[i];
*nameptr = '\0';
if (strcmp(name, "job_printer_uri") == 0)
{
if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL)
valptr = "unknown";
else
valptr ++;
cgiSetArray("job_printer_name", element, valptr);
}
value[0] = '\0';
valptr = value;
for (i = 0; i < attr->num_values; i ++)
{
if (i)
strlcat(valptr, ",", sizeof(value) - (valptr - value));
valptr += strlen(valptr);
switch (attr->value_tag)
{
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
if (strncmp(name, "time_at_", 8) == 0)
{
date = localtime((time_t *)&(attr->values[i].integer));
strftime(valptr, sizeof(value) - (valptr - value),
CUPS_STRFTIME_FORMAT, date);
}
else
snprintf(valptr, sizeof(value) - (valptr - value),
"%d", attr->values[i].integer);
break;
case IPP_TAG_BOOLEAN :
snprintf(valptr, sizeof(value) - (valptr - value),
"%d", attr->values[i].boolean);
break;
case IPP_TAG_NOVALUE :
strlcat(valptr, "novalue", sizeof(value) - (valptr - value));
break;
case IPP_TAG_RANGE :
snprintf(valptr, sizeof(value) - (valptr - value),
"%d-%d", attr->values[i].range.lower,
attr->values[i].range.upper);
break;
case IPP_TAG_RESOLUTION :
snprintf(valptr, sizeof(value) - (valptr - value),
"%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
"dpi" : "dpc");
break;
case IPP_TAG_URI :
if (strchr(attr->values[i].string.text, ':') != NULL)
{
httpSeparate(attr->values[i].string.text, method, username,
hostname, &port, rawresource);
if (strcmp(method, "ipp") == 0 ||
strcmp(method, "http") == 0)
{
for (rawptr = rawresource, resptr = resource; *rawptr;)
if (*rawptr & 128 || *rawptr == '%' || *rawptr == ' ')
{
if (resptr < (resource + sizeof(resource) - 3))
{
*resptr++ = '%';
*resptr++ = hexchars[(*rawptr >> 4) & 15];
*resptr++ = hexchars[*rawptr & 15];
}
}
else if (resptr < (resource + sizeof(resource) - 1))
*resptr++ = *rawptr++;
*resptr = '\0';
if (strcasecmp(hostname, server) == 0 ||
strcasecmp(hostname, servername) == 0)
{
strlcpy(uri, resource, sizeof(uri));
}
else
{
if (username[0])
snprintf(uri, sizeof(uri), "%s://%s@%s:%d%s",
ishttps ? "https" : "http",
username, hostname, port, resource);
else
snprintf(uri, sizeof(uri), "%s://%s:%d%s",
ishttps ? "https" : "http",
hostname, port, resource);
}
strlcat(valptr, uri, sizeof(value) - (valptr - value));
break;
}
}
case IPP_TAG_STRING :
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
case IPP_TAG_KEYWORD :
case IPP_TAG_CHARSET :
case IPP_TAG_LANGUAGE :
case IPP_TAG_MIMETYPE :
strlcat(valptr, attr->values[i].string.text,
sizeof(value) - (valptr - value));
break;
case IPP_TAG_BEGIN_COLLECTION :
snprintf(value, sizeof(value), "%s%d", name, i + 1);
ippSetCGIVars(attr->values[i].collection, filter_name,
filter_value, value, element);
break;
default :
break;
}
}
if (attr->value_tag != IPP_TAG_BEGIN_COLLECTION)
{
cgiSetArray(name, element, value);
DEBUG_printf(("<P>%s[%d]=\"%s\"\n", name, element, value));
}
}
if (attr == NULL)
break;
}
DEBUG_puts("<P>Leaving ippSetCGIVars()...");
}