#include <cups/cups.h>
#include "ipp-private.h"
#include "string-private.h"
#include "debug-internal.h"
void
_ippVarsDeinit(_ipp_vars_t *v)
{
if (v->uri)
{
free(v->uri);
v->uri = NULL;
}
cupsFreeOptions(v->num_vars, v->vars);
v->num_vars = 0;
v->vars = NULL;
}
void
_ippVarsExpand(_ipp_vars_t *v,
char *dst,
const char *src,
size_t dstsize)
{
char *dstptr,
*dstend,
temp[256],
*tempptr;
const char *value;
dstptr = dst;
dstend = dst + dstsize - 1;
while (*src && dstptr < dstend)
{
if (*src == '$')
{
if (!strncmp(src, "$$", 2))
{
value = "$";
src += 2;
}
else if (!strncmp(src, "$ENV[", 5))
{
strlcpy(temp, src + 5, sizeof(temp));
for (tempptr = temp; *tempptr; tempptr ++)
if (*tempptr == ']')
break;
if (*tempptr)
*tempptr++ = '\0';
value = getenv(temp);
src += tempptr - temp + 5;
}
else
{
if (src[1] == '{')
{
src += 2;
strlcpy(temp, src, sizeof(temp));
if ((tempptr = strchr(temp, '}')) != NULL)
*tempptr = '\0';
else
tempptr = temp + strlen(temp);
}
else
{
strlcpy(temp, src + 1, sizeof(temp));
for (tempptr = temp; *tempptr; tempptr ++)
if (!isalnum(*tempptr & 255) && *tempptr != '-' && *tempptr != '_')
break;
if (*tempptr)
*tempptr = '\0';
}
value = _ippVarsGet(v, temp);
src += tempptr - temp + 1;
}
if (value)
{
strlcpy(dstptr, value, (size_t)(dstend - dstptr + 1));
dstptr += strlen(dstptr);
}
}
else
*dstptr++ = *src++;
}
*dstptr = '\0';
}
const char *
_ippVarsGet(_ipp_vars_t *v,
const char *name)
{
if (!v)
return (NULL);
else if (!strcmp(name, "uri"))
return (v->uri);
else if (!strcmp(name, "uriuser") || !strcmp(name, "username"))
return (v->username[0] ? v->username : NULL);
else if (!strcmp(name, "scheme") || !strcmp(name, "method"))
return (v->scheme);
else if (!strcmp(name, "hostname"))
return (v->host);
else if (!strcmp(name, "port"))
return (v->portstr);
else if (!strcmp(name, "resource"))
return (v->resource);
else if (!strcmp(name, "user"))
return (cupsUser());
else
return (cupsGetOption(name, v->num_vars, v->vars));
}
void
_ippVarsInit(_ipp_vars_t *v,
_ipp_fattr_cb_t attrcb,
_ipp_ferror_cb_t errorcb,
_ipp_ftoken_cb_t tokencb)
{
memset(v, 0, sizeof(_ipp_vars_t));
v->attrcb = attrcb;
v->errorcb = errorcb;
v->tokencb = tokencb;
}
const char *
_ippVarsPasswordCB(
const char *prompt,
http_t *http,
const char *method,
const char *resource,
void *user_data)
{
_ipp_vars_t *v = (_ipp_vars_t *)user_data;
(void)prompt;
(void)http;
(void)method;
(void)resource;
if (v->username[0] && v->password && v->password_tries < 3)
{
v->password_tries ++;
cupsSetUser(v->username);
return (v->password);
}
else
{
return (NULL);
}
}
int
_ippVarsSet(_ipp_vars_t *v,
const char *name,
const char *value)
{
if (!strcmp(name, "uri"))
{
char uri[1024];
http_uri_status_t uri_status;
if ((uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, value, v->scheme, sizeof(v->scheme), v->username, sizeof(v->username), v->host, sizeof(v->host), &(v->port), v->resource, sizeof(v->resource))) < HTTP_URI_STATUS_OK)
return (0);
if (v->username[0])
{
if ((v->password = strchr(v->username, ':')) != NULL)
*(v->password)++ = '\0';
}
snprintf(v->portstr, sizeof(v->portstr), "%d", v->port);
if (v->uri)
free(v->uri);
httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), v->scheme, NULL, v->host, v->port, v->resource);
v->uri = strdup(uri);
return (v->uri != NULL);
}
else
{
v->num_vars = cupsAddOption(name, value, v->num_vars, &v->vars);
return (1);
}
}