1 /*
2 * HTML support functions for CUPS.
3 *
4 * Copyright © 2020-2024 by OpenPrinting.
5 * Copyright © 2007-2011 by Apple Inc.
6 * Copyright © 1997-2006 by Easy Software Products.
7 *
8 * Licensed under Apache License v2.0. See the file "LICENSE" for more
9 * information.
10 */
11
12 /*
13 * Include necessary headers...
14 */
15
16 #include "cgi-private.h"
17
18
19 /*
20 * Local globals...
21 */
22
23 static const char *cgi_multipart = NULL;
24 /* Multipart separator, if any */
25
26
27 /*
28 * Local functions...
29 */
30
31 static const char *cgi_null_passwd(const char *prompt);
32
33
34 /*
35 * 'cgiEndHTML()' - End a HTML page.
36 */
37
38 void
cgiEndHTML(void)39 cgiEndHTML(void)
40 {
41 /*
42 * Send the standard trailer...
43 */
44
45 cgiCopyTemplateLang("trailer.tmpl");
46 }
47
48
49 /*
50 * 'cgiEndMultipart()' - End the delivery of a multipart web page.
51 */
52
53 void
cgiEndMultipart(void)54 cgiEndMultipart(void)
55 {
56 if (cgi_multipart)
57 {
58 printf("\n%s--\n", cgi_multipart);
59 fflush(stdout);
60 }
61 }
62
63
64 /*
65 * 'cgiFormEncode()' - Encode a string as a form variable.
66 */
67
68 char * /* O - Destination string */
cgiFormEncode(char * dst,const char * src,size_t dstsize)69 cgiFormEncode(char *dst, /* I - Destination string */
70 const char *src, /* I - Source string */
71 size_t dstsize) /* I - Size of destination string */
72 {
73 char *dstptr, /* Pointer into destination */
74 *dstend; /* End of destination */
75 static const char *hex = /* Hexadecimal characters */
76 "0123456789ABCDEF";
77
78
79 /*
80 * Mark the end of the string...
81 */
82
83 dstend = dst + dstsize - 1;
84
85 /*
86 * Loop through the source string and copy...
87 */
88
89 for (dstptr = dst; *src && dstptr < dstend;)
90 {
91 switch (*src)
92 {
93 case ' ' :
94 /*
95 * Encode spaces with a "+"...
96 */
97
98 *dstptr++ = '+';
99 src ++;
100 break;
101
102 case '&' :
103 case '%' :
104 case '+' :
105 /*
106 * Encode special characters with %XX escape...
107 */
108
109 if (dstptr < (dstend - 2))
110 {
111 *dstptr++ = '%';
112 *dstptr++ = hex[(*src & 255) >> 4];
113 *dstptr++ = hex[*src & 15];
114 src ++;
115 }
116 break;
117
118 default :
119 /*
120 * Copy other characters literally...
121 */
122
123 *dstptr++ = *src++;
124 break;
125 }
126 }
127
128 /*
129 * Nul-terminate the destination string...
130 */
131
132 *dstptr = '\0';
133
134 /*
135 * Return the encoded string...
136 */
137
138 return (dst);
139 }
140
141
142 /*
143 * 'cgiStartHTML()' - Start a HTML page.
144 */
145
146 void
cgiStartHTML(const char * title)147 cgiStartHTML(const char *title) /* I - Title of page */
148 {
149 /*
150 * Disable any further authentication attempts...
151 */
152
153 cupsSetPasswordCB(cgi_null_passwd);
154
155 /*
156 * Tell the client to expect UTF-8 encoded HTML...
157 */
158
159 if (cgi_multipart)
160 puts(cgi_multipart);
161
162 puts("Content-Type: text/html;charset=utf-8\n");
163
164 /*
165 * Send a standard header...
166 */
167
168 cgiSetVariable("TITLE", title);
169 cgiSetServerVersion();
170
171 cgiCopyTemplateLang("header.tmpl");
172 }
173
174
175 /*
176 * 'cgiStartMultipart()' - Start a multipart delivery of a web page.
177 */
178
179 void
cgiStartMultipart(void)180 cgiStartMultipart(void)
181 {
182 puts("MIME-Version: 1.0\n"
183 "Content-Type: multipart/x-mixed-replace; boundary=\"CUPS-MULTIPART\"\n");
184 fflush(stdout);
185
186 cgi_multipart = "--CUPS-MULTIPART";
187 }
188
189
190 /*
191 * 'cgiSupportsMultipart()' - Does the browser support multi-part documents?
192 */
193
194 int /* O - 1 if multi-part supported, 0 otherwise */
cgiSupportsMultipart(void)195 cgiSupportsMultipart(void)
196 {
197 /*
198 * Too many bug reports for browsers that don't support it, and too much pain
199 * to whitelist known-good browsers, so for now we just punt on multi-part
200 * support... :(
201 */
202
203 return (0);
204 }
205
206
207 /*
208 * 'cgi_null_passwd()' - Return a NULL password for authentication.
209 */
210
211 static const char * /* O - NULL */
cgi_null_passwd(const char * prompt)212 cgi_null_passwd(const char *prompt) /* I - Prompt string (unused) */
213 {
214 (void)prompt;
215
216 fprintf(stderr, "DEBUG: cgi_null_passwd(prompt=\"%s\") called!\n",
217 prompt ? prompt : "(null)");
218
219 return (NULL);
220 }
221