• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * IPP data file parsing functions.
3  *
4  * Copyright © 2007-2019 by Apple Inc.
5  * Copyright © 1997-2007 by Easy Software Products.
6  *
7  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8  * information.
9  */
10 
11 /*
12  * Include necessary headers...
13  */
14 
15 #include <cups/cups.h>
16 #include "ipp-private.h"
17 #include "string-private.h"
18 #include "debug-internal.h"
19 
20 
21 /*
22  * '_ippVarsDeinit()' - Free all memory associated with the IPP variables.
23  */
24 
25 void
_ippVarsDeinit(_ipp_vars_t * v)26 _ippVarsDeinit(_ipp_vars_t *v)		/* I - IPP variables */
27 {
28   if (v->uri)
29   {
30     free(v->uri);
31     v->uri = NULL;
32   }
33 
34   cupsFreeOptions(v->num_vars, v->vars);
35   v->num_vars = 0;
36   v->vars     = NULL;
37 }
38 
39 
40 /*
41  * '_ippVarsExpand()' - Expand variables in the source string.
42  */
43 
44 void
_ippVarsExpand(_ipp_vars_t * v,char * dst,const char * src,size_t dstsize)45 _ippVarsExpand(_ipp_vars_t *v,		/* I - IPP variables */
46                char        *dst,	/* I - Destination buffer */
47                const char  *src,	/* I - Source string */
48                size_t      dstsize)	/* I - Destination buffer size */
49 {
50   char		*dstptr,		/* Pointer into destination */
51 		*dstend,		/* End of destination */
52 		temp[256],		/* Temporary string */
53 		*tempptr;		/* Pointer into temporary string */
54   const char	*value;			/* Value to substitute */
55 
56 
57   dstptr = dst;
58   dstend = dst + dstsize - 1;
59 
60   while (*src && dstptr < dstend)
61   {
62     if (*src == '$')
63     {
64      /*
65       * Substitute a string/number...
66       */
67 
68       if (!strncmp(src, "$$", 2))
69       {
70         value = "$";
71 	src   += 2;
72       }
73       else if (!strncmp(src, "$ENV[", 5))
74       {
75 	strlcpy(temp, src + 5, sizeof(temp));
76 
77 	for (tempptr = temp; *tempptr; tempptr ++)
78 	  if (*tempptr == ']')
79 	    break;
80 
81         if (*tempptr)
82 	  *tempptr++ = '\0';
83 
84 	value = getenv(temp);
85         src   += tempptr - temp + 5;
86       }
87       else
88       {
89         if (src[1] == '{')
90 	{
91 	  src += 2;
92 	  strlcpy(temp, src, sizeof(temp));
93 	  if ((tempptr = strchr(temp, '}')) != NULL)
94 	    *tempptr = '\0';
95 	  else
96 	    tempptr = temp + strlen(temp);
97 	}
98 	else
99 	{
100 	  strlcpy(temp, src + 1, sizeof(temp));
101 
102 	  for (tempptr = temp; *tempptr; tempptr ++)
103 	    if (!isalnum(*tempptr & 255) && *tempptr != '-' && *tempptr != '_')
104 	      break;
105 
106 	  if (*tempptr)
107 	    *tempptr = '\0';
108         }
109 
110         value = _ippVarsGet(v, temp);
111 
112         src += tempptr - temp + 1;
113       }
114 
115       if (value)
116       {
117         strlcpy(dstptr, value, (size_t)(dstend - dstptr + 1));
118 	dstptr += strlen(dstptr);
119       }
120     }
121     else
122       *dstptr++ = *src++;
123   }
124 
125   *dstptr = '\0';
126 }
127 
128 
129 /*
130  * '_ippVarsGet()' - Get a variable string.
131  */
132 
133 const char *				/* O - Value or @code NULL@ if not set */
_ippVarsGet(_ipp_vars_t * v,const char * name)134 _ippVarsGet(_ipp_vars_t *v,		/* I - IPP variables */
135             const char  *name)		/* I - Variable name */
136 {
137   if (!v)
138     return (NULL);
139   else if (!strcmp(name, "uri"))
140     return (v->uri);
141   else if (!strcmp(name, "uriuser") || !strcmp(name, "username"))
142     return (v->username[0] ? v->username : NULL);
143   else if (!strcmp(name, "scheme") || !strcmp(name, "method"))
144     return (v->scheme);
145   else if (!strcmp(name, "hostname"))
146     return (v->host);
147   else if (!strcmp(name, "port"))
148     return (v->portstr);
149   else if (!strcmp(name, "resource"))
150     return (v->resource);
151   else if (!strcmp(name, "user"))
152     return (cupsUser());
153   else
154     return (cupsGetOption(name, v->num_vars, v->vars));
155 }
156 
157 
158 /*
159  * '_ippVarsInit()' - Initialize .
160  */
161 
162 void
_ippVarsInit(_ipp_vars_t * v,_ipp_fattr_cb_t attrcb,_ipp_ferror_cb_t errorcb,_ipp_ftoken_cb_t tokencb)163 _ippVarsInit(_ipp_vars_t      *v,	/* I - IPP variables */
164              _ipp_fattr_cb_t  attrcb,	/* I - Attribute (filter) callback */
165              _ipp_ferror_cb_t errorcb,	/* I - Error callback */
166              _ipp_ftoken_cb_t tokencb)	/* I - Token callback */
167 {
168   memset(v, 0, sizeof(_ipp_vars_t));
169 
170   v->attrcb  = attrcb;
171   v->errorcb = errorcb;
172   v->tokencb = tokencb;
173 }
174 
175 
176 /*
177  * '_ippVarsPasswordCB()' - Password callback using the IPP variables.
178  */
179 
180 const char *				/* O - Password string or @code NULL@ */
_ippVarsPasswordCB(const char * prompt,http_t * http,const char * method,const char * resource,void * user_data)181 _ippVarsPasswordCB(
182     const char *prompt,			/* I - Prompt string (not used) */
183     http_t     *http,			/* I - HTTP connection (not used) */
184     const char *method,			/* I - HTTP method (not used) */
185     const char *resource,		/* I - Resource path (not used) */
186     void       *user_data)		/* I - IPP variables */
187 {
188   _ipp_vars_t	*v = (_ipp_vars_t *)user_data;
189 					/* I - IPP variables */
190 
191 
192   (void)prompt;
193   (void)http;
194   (void)method;
195   (void)resource;
196 
197   if (v->username[0] && v->password && v->password_tries < 3)
198   {
199     v->password_tries ++;
200 
201     cupsSetUser(v->username);
202 
203     return (v->password);
204   }
205   else
206   {
207     return (NULL);
208   }
209 }
210 
211 
212 /*
213  * '_ippVarsSet()' - Set an IPP variable.
214  */
215 
216 int					/* O - 1 on success, 0 on failure */
_ippVarsSet(_ipp_vars_t * v,const char * name,const char * value)217 _ippVarsSet(_ipp_vars_t *v,		/* I - IPP variables */
218             const char  *name,		/* I - Variable name */
219             const char  *value)		/* I - Variable value */
220 {
221   if (!strcmp(name, "uri"))
222   {
223     char		uri[1024];	/* New printer URI */
224     http_uri_status_t	uri_status;	/* URI status */
225 
226     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)
227       return (0);
228 
229     if (v->username[0])
230     {
231       if ((v->password = strchr(v->username, ':')) != NULL)
232 	*(v->password)++ = '\0';
233     }
234 
235     snprintf(v->portstr, sizeof(v->portstr), "%d", v->port);
236 
237     if (v->uri)
238       free(v->uri);
239 
240     httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), v->scheme, NULL, v->host, v->port, v->resource);
241     v->uri = strdup(uri);
242 
243     return (v->uri != NULL);
244   }
245   else
246   {
247     v->num_vars = cupsAddOption(name, value, v->num_vars, &v->vars);
248     return (1);
249   }
250 }
251