1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * "mailto" notifier for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2005 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <sys/wait.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <signal.h>
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker * Globals...
22*5e7646d2SAndroid Build Coastguard Worker */
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker char mailtoCc[1024]; /* Cc email address */
25*5e7646d2SAndroid Build Coastguard Worker char mailtoFrom[1024]; /* From email address */
26*5e7646d2SAndroid Build Coastguard Worker char mailtoReplyTo[1024]; /* Reply-To email address */
27*5e7646d2SAndroid Build Coastguard Worker char mailtoSubject[1024]; /* Subject prefix */
28*5e7646d2SAndroid Build Coastguard Worker char mailtoSMTPServer[1024]; /* SMTP server to use */
29*5e7646d2SAndroid Build Coastguard Worker char mailtoSendmail[1024]; /* Sendmail program to use */
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker
32*5e7646d2SAndroid Build Coastguard Worker /*
33*5e7646d2SAndroid Build Coastguard Worker * Local functions...
34*5e7646d2SAndroid Build Coastguard Worker */
35*5e7646d2SAndroid Build Coastguard Worker
36*5e7646d2SAndroid Build Coastguard Worker void email_message(const char *to, const char *subject, const char *text);
37*5e7646d2SAndroid Build Coastguard Worker int load_configuration(void);
38*5e7646d2SAndroid Build Coastguard Worker cups_file_t *pipe_sendmail(const char *to);
39*5e7646d2SAndroid Build Coastguard Worker void print_attributes(ipp_t *ipp, int indent);
40*5e7646d2SAndroid Build Coastguard Worker
41*5e7646d2SAndroid Build Coastguard Worker
42*5e7646d2SAndroid Build Coastguard Worker /*
43*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Main entry for the mailto notifier.
44*5e7646d2SAndroid Build Coastguard Worker */
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker int /* O - Exit status */
main(int argc,char * argv[])47*5e7646d2SAndroid Build Coastguard Worker main(int argc, /* I - Number of command-line arguments */
48*5e7646d2SAndroid Build Coastguard Worker char *argv[]) /* I - Command-line arguments */
49*5e7646d2SAndroid Build Coastguard Worker {
50*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
51*5e7646d2SAndroid Build Coastguard Worker ipp_t *msg; /* Event message from scheduler */
52*5e7646d2SAndroid Build Coastguard Worker ipp_state_t state; /* IPP event state */
53*5e7646d2SAndroid Build Coastguard Worker char *subject, /* Subject for notification message */
54*5e7646d2SAndroid Build Coastguard Worker *text; /* Text for notification message */
55*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *lang; /* Language info */
56*5e7646d2SAndroid Build Coastguard Worker char temp[1024]; /* Temporary string */
57*5e7646d2SAndroid Build Coastguard Worker int templen; /* Length of temporary string */
58*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
59*5e7646d2SAndroid Build Coastguard Worker struct sigaction action; /* POSIX sigaction data */
60*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
61*5e7646d2SAndroid Build Coastguard Worker
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker /*
64*5e7646d2SAndroid Build Coastguard Worker * Don't buffer stderr...
65*5e7646d2SAndroid Build Coastguard Worker */
66*5e7646d2SAndroid Build Coastguard Worker
67*5e7646d2SAndroid Build Coastguard Worker setbuf(stderr, NULL);
68*5e7646d2SAndroid Build Coastguard Worker
69*5e7646d2SAndroid Build Coastguard Worker /*
70*5e7646d2SAndroid Build Coastguard Worker * Ignore SIGPIPE signals...
71*5e7646d2SAndroid Build Coastguard Worker */
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SIGSET
74*5e7646d2SAndroid Build Coastguard Worker sigset(SIGPIPE, SIG_IGN);
75*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_SIGACTION)
76*5e7646d2SAndroid Build Coastguard Worker memset(&action, 0, sizeof(action));
77*5e7646d2SAndroid Build Coastguard Worker action.sa_handler = SIG_IGN;
78*5e7646d2SAndroid Build Coastguard Worker sigaction(SIGPIPE, &action, NULL);
79*5e7646d2SAndroid Build Coastguard Worker #else
80*5e7646d2SAndroid Build Coastguard Worker signal(SIGPIPE, SIG_IGN);
81*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SIGSET */
82*5e7646d2SAndroid Build Coastguard Worker
83*5e7646d2SAndroid Build Coastguard Worker /*
84*5e7646d2SAndroid Build Coastguard Worker * Validate command-line options...
85*5e7646d2SAndroid Build Coastguard Worker */
86*5e7646d2SAndroid Build Coastguard Worker
87*5e7646d2SAndroid Build Coastguard Worker if (argc != 3)
88*5e7646d2SAndroid Build Coastguard Worker {
89*5e7646d2SAndroid Build Coastguard Worker fputs("Usage: mailto mailto:[email protected] notify-user-data\n", stderr);
90*5e7646d2SAndroid Build Coastguard Worker return (1);
91*5e7646d2SAndroid Build Coastguard Worker }
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker if (strncmp(argv[1], "mailto:", 7))
94*5e7646d2SAndroid Build Coastguard Worker {
95*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Bad recipient \"%s\"!\n", argv[1]);
96*5e7646d2SAndroid Build Coastguard Worker return (1);
97*5e7646d2SAndroid Build Coastguard Worker }
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: argc=%d\n", argc);
100*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < argc; i ++)
101*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker /*
104*5e7646d2SAndroid Build Coastguard Worker * Load configuration data...
105*5e7646d2SAndroid Build Coastguard Worker */
106*5e7646d2SAndroid Build Coastguard Worker
107*5e7646d2SAndroid Build Coastguard Worker if ((lang = cupsLangDefault()) == NULL)
108*5e7646d2SAndroid Build Coastguard Worker return (1);
109*5e7646d2SAndroid Build Coastguard Worker
110*5e7646d2SAndroid Build Coastguard Worker if (!load_configuration())
111*5e7646d2SAndroid Build Coastguard Worker return (1);
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker /*
114*5e7646d2SAndroid Build Coastguard Worker * Get the reply-to address...
115*5e7646d2SAndroid Build Coastguard Worker */
116*5e7646d2SAndroid Build Coastguard Worker
117*5e7646d2SAndroid Build Coastguard Worker templen = sizeof(temp);
118*5e7646d2SAndroid Build Coastguard Worker httpDecode64_2(temp, &templen, argv[2]);
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(temp, "mailto:", 7))
121*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoReplyTo, temp + 7, sizeof(mailtoReplyTo));
122*5e7646d2SAndroid Build Coastguard Worker else if (temp[0])
123*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "WARNING: Bad notify-user-data value (%d bytes) ignored!\n",
124*5e7646d2SAndroid Build Coastguard Worker templen);
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker /*
127*5e7646d2SAndroid Build Coastguard Worker * Loop forever until we run out of events...
128*5e7646d2SAndroid Build Coastguard Worker */
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker for (;;)
131*5e7646d2SAndroid Build Coastguard Worker {
132*5e7646d2SAndroid Build Coastguard Worker /*
133*5e7646d2SAndroid Build Coastguard Worker * Get the next event...
134*5e7646d2SAndroid Build Coastguard Worker */
135*5e7646d2SAndroid Build Coastguard Worker
136*5e7646d2SAndroid Build Coastguard Worker msg = ippNew();
137*5e7646d2SAndroid Build Coastguard Worker while ((state = ippReadFile(0, msg)) != IPP_DATA)
138*5e7646d2SAndroid Build Coastguard Worker {
139*5e7646d2SAndroid Build Coastguard Worker if (state <= IPP_IDLE)
140*5e7646d2SAndroid Build Coastguard Worker break;
141*5e7646d2SAndroid Build Coastguard Worker }
142*5e7646d2SAndroid Build Coastguard Worker
143*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: state=%d\n", state);
144*5e7646d2SAndroid Build Coastguard Worker
145*5e7646d2SAndroid Build Coastguard Worker if (state == IPP_ERROR)
146*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr);
147*5e7646d2SAndroid Build Coastguard Worker
148*5e7646d2SAndroid Build Coastguard Worker if (state <= IPP_IDLE)
149*5e7646d2SAndroid Build Coastguard Worker {
150*5e7646d2SAndroid Build Coastguard Worker /*
151*5e7646d2SAndroid Build Coastguard Worker * Out of messages, free memory and then exit...
152*5e7646d2SAndroid Build Coastguard Worker */
153*5e7646d2SAndroid Build Coastguard Worker
154*5e7646d2SAndroid Build Coastguard Worker ippDelete(msg);
155*5e7646d2SAndroid Build Coastguard Worker return (0);
156*5e7646d2SAndroid Build Coastguard Worker }
157*5e7646d2SAndroid Build Coastguard Worker
158*5e7646d2SAndroid Build Coastguard Worker /*
159*5e7646d2SAndroid Build Coastguard Worker * Get the subject and text for the message, then email it...
160*5e7646d2SAndroid Build Coastguard Worker */
161*5e7646d2SAndroid Build Coastguard Worker
162*5e7646d2SAndroid Build Coastguard Worker subject = cupsNotifySubject(lang, msg);
163*5e7646d2SAndroid Build Coastguard Worker text = cupsNotifyText(lang, msg);
164*5e7646d2SAndroid Build Coastguard Worker
165*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: subject=\"%s\"\n", subject);
166*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: text=\"%s\"\n", text);
167*5e7646d2SAndroid Build Coastguard Worker
168*5e7646d2SAndroid Build Coastguard Worker if (subject && text)
169*5e7646d2SAndroid Build Coastguard Worker email_message(argv[1] + 7, subject, text);
170*5e7646d2SAndroid Build Coastguard Worker else
171*5e7646d2SAndroid Build Coastguard Worker {
172*5e7646d2SAndroid Build Coastguard Worker fputs("ERROR: Missing attributes in event notification!\n", stderr);
173*5e7646d2SAndroid Build Coastguard Worker print_attributes(msg, 4);
174*5e7646d2SAndroid Build Coastguard Worker }
175*5e7646d2SAndroid Build Coastguard Worker
176*5e7646d2SAndroid Build Coastguard Worker /*
177*5e7646d2SAndroid Build Coastguard Worker * Free the memory used for this event...
178*5e7646d2SAndroid Build Coastguard Worker */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker if (subject)
181*5e7646d2SAndroid Build Coastguard Worker free(subject);
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker if (text)
184*5e7646d2SAndroid Build Coastguard Worker free(text);
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker ippDelete(msg);
187*5e7646d2SAndroid Build Coastguard Worker }
188*5e7646d2SAndroid Build Coastguard Worker }
189*5e7646d2SAndroid Build Coastguard Worker
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker /*
192*5e7646d2SAndroid Build Coastguard Worker * 'email_message()' - Email a notification message.
193*5e7646d2SAndroid Build Coastguard Worker */
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker void
email_message(const char * to,const char * subject,const char * text)196*5e7646d2SAndroid Build Coastguard Worker email_message(const char *to, /* I - Recipient of message */
197*5e7646d2SAndroid Build Coastguard Worker const char *subject, /* I - Subject of message */
198*5e7646d2SAndroid Build Coastguard Worker const char *text) /* I - Text of message */
199*5e7646d2SAndroid Build Coastguard Worker {
200*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* Pipe/socket to mail server */
201*5e7646d2SAndroid Build Coastguard Worker const char *nl; /* Newline to use */
202*5e7646d2SAndroid Build Coastguard Worker char response[1024]; /* SMTP response buffer */
203*5e7646d2SAndroid Build Coastguard Worker
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker /*
206*5e7646d2SAndroid Build Coastguard Worker * Connect to the mail server...
207*5e7646d2SAndroid Build Coastguard Worker */
208*5e7646d2SAndroid Build Coastguard Worker
209*5e7646d2SAndroid Build Coastguard Worker if (mailtoSendmail[0])
210*5e7646d2SAndroid Build Coastguard Worker {
211*5e7646d2SAndroid Build Coastguard Worker /*
212*5e7646d2SAndroid Build Coastguard Worker * Use the sendmail command...
213*5e7646d2SAndroid Build Coastguard Worker */
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker fp = pipe_sendmail(to);
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker if (!fp)
218*5e7646d2SAndroid Build Coastguard Worker return;
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker nl = "\n";
221*5e7646d2SAndroid Build Coastguard Worker }
222*5e7646d2SAndroid Build Coastguard Worker else
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker /*
225*5e7646d2SAndroid Build Coastguard Worker * Use an SMTP server...
226*5e7646d2SAndroid Build Coastguard Worker */
227*5e7646d2SAndroid Build Coastguard Worker
228*5e7646d2SAndroid Build Coastguard Worker char hostbuf[1024]; /* Local hostname */
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker
231*5e7646d2SAndroid Build Coastguard Worker if (strchr(mailtoSMTPServer, ':'))
232*5e7646d2SAndroid Build Coastguard Worker {
233*5e7646d2SAndroid Build Coastguard Worker fp = cupsFileOpen(mailtoSMTPServer, "s");
234*5e7646d2SAndroid Build Coastguard Worker }
235*5e7646d2SAndroid Build Coastguard Worker else
236*5e7646d2SAndroid Build Coastguard Worker {
237*5e7646d2SAndroid Build Coastguard Worker char spec[1024]; /* Host:service spec */
238*5e7646d2SAndroid Build Coastguard Worker
239*5e7646d2SAndroid Build Coastguard Worker
240*5e7646d2SAndroid Build Coastguard Worker snprintf(spec, sizeof(spec), "%s:smtp", mailtoSMTPServer);
241*5e7646d2SAndroid Build Coastguard Worker fp = cupsFileOpen(spec, "s");
242*5e7646d2SAndroid Build Coastguard Worker }
243*5e7646d2SAndroid Build Coastguard Worker
244*5e7646d2SAndroid Build Coastguard Worker if (!fp)
245*5e7646d2SAndroid Build Coastguard Worker {
246*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Unable to connect to SMTP server \"%s\"!\n",
247*5e7646d2SAndroid Build Coastguard Worker mailtoSMTPServer);
248*5e7646d2SAndroid Build Coastguard Worker return;
249*5e7646d2SAndroid Build Coastguard Worker }
250*5e7646d2SAndroid Build Coastguard Worker
251*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: Connected to \"%s\"...\n", mailtoSMTPServer);
252*5e7646d2SAndroid Build Coastguard Worker
253*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
254*5e7646d2SAndroid Build Coastguard Worker goto smtp_error;
255*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
256*5e7646d2SAndroid Build Coastguard Worker
257*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "HELO %s\r\n",
258*5e7646d2SAndroid Build Coastguard Worker httpGetHostname(NULL, hostbuf, sizeof(hostbuf)));
259*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: >>> HELO %s\n", hostbuf);
260*5e7646d2SAndroid Build Coastguard Worker
261*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
262*5e7646d2SAndroid Build Coastguard Worker goto smtp_error;
263*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "MAIL FROM:%s\r\n", mailtoFrom);
266*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: >>> MAIL FROM:%s\n", mailtoFrom);
267*5e7646d2SAndroid Build Coastguard Worker
268*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
269*5e7646d2SAndroid Build Coastguard Worker goto smtp_error;
270*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "RCPT TO:%s\r\n", to);
273*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: >>> RCPT TO:%s\n", to);
274*5e7646d2SAndroid Build Coastguard Worker
275*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
276*5e7646d2SAndroid Build Coastguard Worker goto smtp_error;
277*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
278*5e7646d2SAndroid Build Coastguard Worker
279*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "DATA\r\n");
280*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: DATA\n", stderr);
281*5e7646d2SAndroid Build Coastguard Worker
282*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
283*5e7646d2SAndroid Build Coastguard Worker goto smtp_error;
284*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
285*5e7646d2SAndroid Build Coastguard Worker
286*5e7646d2SAndroid Build Coastguard Worker nl = "\r\n";
287*5e7646d2SAndroid Build Coastguard Worker }
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker /*
290*5e7646d2SAndroid Build Coastguard Worker * Send the message...
291*5e7646d2SAndroid Build Coastguard Worker */
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Date: %s%s", httpGetDateString(time(NULL)), nl);
294*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "From: %s%s", mailtoFrom, nl);
295*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Subject: %s %s%s", mailtoSubject, subject, nl);
296*5e7646d2SAndroid Build Coastguard Worker if (mailtoReplyTo[0])
297*5e7646d2SAndroid Build Coastguard Worker {
298*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Sender: %s%s", mailtoReplyTo, nl);
299*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Reply-To: %s%s", mailtoReplyTo, nl);
300*5e7646d2SAndroid Build Coastguard Worker }
301*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "To: %s%s", to, nl);
302*5e7646d2SAndroid Build Coastguard Worker if (mailtoCc[0])
303*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Cc: %s%s", mailtoCc, nl);
304*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Content-Type: text/plain%s", nl);
305*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, nl);
306*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "%s%s", text, nl);
307*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, ".%s", nl);
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker /*
310*5e7646d2SAndroid Build Coastguard Worker * Close the connection to the mail server...
311*5e7646d2SAndroid Build Coastguard Worker */
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker if (mailtoSendmail[0])
314*5e7646d2SAndroid Build Coastguard Worker {
315*5e7646d2SAndroid Build Coastguard Worker /*
316*5e7646d2SAndroid Build Coastguard Worker * Close the pipe and wait for the sendmail command to finish...
317*5e7646d2SAndroid Build Coastguard Worker */
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker int status; /* Exit status */
320*5e7646d2SAndroid Build Coastguard Worker
321*5e7646d2SAndroid Build Coastguard Worker
322*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
323*5e7646d2SAndroid Build Coastguard Worker
324*5e7646d2SAndroid Build Coastguard Worker while (wait(&status))
325*5e7646d2SAndroid Build Coastguard Worker {
326*5e7646d2SAndroid Build Coastguard Worker if (errno != EINTR)
327*5e7646d2SAndroid Build Coastguard Worker {
328*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: Unable to get child status: %s\n",
329*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
330*5e7646d2SAndroid Build Coastguard Worker status = 0;
331*5e7646d2SAndroid Build Coastguard Worker break;
332*5e7646d2SAndroid Build Coastguard Worker }
333*5e7646d2SAndroid Build Coastguard Worker }
334*5e7646d2SAndroid Build Coastguard Worker
335*5e7646d2SAndroid Build Coastguard Worker /*
336*5e7646d2SAndroid Build Coastguard Worker * Report any non-zero status...
337*5e7646d2SAndroid Build Coastguard Worker */
338*5e7646d2SAndroid Build Coastguard Worker
339*5e7646d2SAndroid Build Coastguard Worker if (status)
340*5e7646d2SAndroid Build Coastguard Worker {
341*5e7646d2SAndroid Build Coastguard Worker if (WIFEXITED(status))
342*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Sendmail command returned status %d!\n",
343*5e7646d2SAndroid Build Coastguard Worker WEXITSTATUS(status));
344*5e7646d2SAndroid Build Coastguard Worker else
345*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Sendmail command crashed on signal %d!\n",
346*5e7646d2SAndroid Build Coastguard Worker WTERMSIG(status));
347*5e7646d2SAndroid Build Coastguard Worker }
348*5e7646d2SAndroid Build Coastguard Worker }
349*5e7646d2SAndroid Build Coastguard Worker else
350*5e7646d2SAndroid Build Coastguard Worker {
351*5e7646d2SAndroid Build Coastguard Worker /*
352*5e7646d2SAndroid Build Coastguard Worker * Finish up the SMTP submission and close the connection...
353*5e7646d2SAndroid Build Coastguard Worker */
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
356*5e7646d2SAndroid Build Coastguard Worker goto smtp_error;
357*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
358*5e7646d2SAndroid Build Coastguard Worker
359*5e7646d2SAndroid Build Coastguard Worker /*
360*5e7646d2SAndroid Build Coastguard Worker * Process SMTP errors here...
361*5e7646d2SAndroid Build Coastguard Worker */
362*5e7646d2SAndroid Build Coastguard Worker
363*5e7646d2SAndroid Build Coastguard Worker smtp_error:
364*5e7646d2SAndroid Build Coastguard Worker
365*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "QUIT\r\n");
366*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: QUIT\n", stderr);
367*5e7646d2SAndroid Build Coastguard Worker
368*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
369*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Got \"%s\" trying to QUIT connection.\n",
370*5e7646d2SAndroid Build Coastguard Worker response);
371*5e7646d2SAndroid Build Coastguard Worker else
372*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: <<< %s\n", response);
373*5e7646d2SAndroid Build Coastguard Worker
374*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
375*5e7646d2SAndroid Build Coastguard Worker
376*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: Closed connection to \"%s\"...\n",
377*5e7646d2SAndroid Build Coastguard Worker mailtoSMTPServer);
378*5e7646d2SAndroid Build Coastguard Worker }
379*5e7646d2SAndroid Build Coastguard Worker }
380*5e7646d2SAndroid Build Coastguard Worker
381*5e7646d2SAndroid Build Coastguard Worker
382*5e7646d2SAndroid Build Coastguard Worker /*
383*5e7646d2SAndroid Build Coastguard Worker * 'load_configuration()' - Load the mailto.conf file.
384*5e7646d2SAndroid Build Coastguard Worker */
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker int /* I - 1 on success, 0 on failure */
load_configuration(void)387*5e7646d2SAndroid Build Coastguard Worker load_configuration(void)
388*5e7646d2SAndroid Build Coastguard Worker {
389*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* mailto.conf file */
390*5e7646d2SAndroid Build Coastguard Worker const char *server_root, /* CUPS_SERVERROOT environment variable */
391*5e7646d2SAndroid Build Coastguard Worker *server_admin; /* SERVER_ADMIN environment variable */
392*5e7646d2SAndroid Build Coastguard Worker char line[1024], /* Line from file */
393*5e7646d2SAndroid Build Coastguard Worker *value; /* Value for directive */
394*5e7646d2SAndroid Build Coastguard Worker int linenum; /* Line number in file */
395*5e7646d2SAndroid Build Coastguard Worker
396*5e7646d2SAndroid Build Coastguard Worker
397*5e7646d2SAndroid Build Coastguard Worker /*
398*5e7646d2SAndroid Build Coastguard Worker * Initialize defaults...
399*5e7646d2SAndroid Build Coastguard Worker */
400*5e7646d2SAndroid Build Coastguard Worker
401*5e7646d2SAndroid Build Coastguard Worker mailtoCc[0] = '\0';
402*5e7646d2SAndroid Build Coastguard Worker
403*5e7646d2SAndroid Build Coastguard Worker if ((server_admin = getenv("SERVER_ADMIN")) != NULL)
404*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoFrom, server_admin, sizeof(mailtoFrom));
405*5e7646d2SAndroid Build Coastguard Worker else
406*5e7646d2SAndroid Build Coastguard Worker snprintf(mailtoFrom, sizeof(mailtoFrom), "root@%s",
407*5e7646d2SAndroid Build Coastguard Worker httpGetHostname(NULL, line, sizeof(line)));
408*5e7646d2SAndroid Build Coastguard Worker
409*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoSendmail, "/usr/sbin/sendmail", sizeof(mailtoSendmail));
410*5e7646d2SAndroid Build Coastguard Worker
411*5e7646d2SAndroid Build Coastguard Worker mailtoSMTPServer[0] = '\0';
412*5e7646d2SAndroid Build Coastguard Worker
413*5e7646d2SAndroid Build Coastguard Worker mailtoSubject[0] = '\0';
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker /*
416*5e7646d2SAndroid Build Coastguard Worker * Try loading the config file...
417*5e7646d2SAndroid Build Coastguard Worker */
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
420*5e7646d2SAndroid Build Coastguard Worker server_root = CUPS_SERVERROOT;
421*5e7646d2SAndroid Build Coastguard Worker
422*5e7646d2SAndroid Build Coastguard Worker snprintf(line, sizeof(line), "%s/mailto.conf", server_root);
423*5e7646d2SAndroid Build Coastguard Worker
424*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpen(line, "r")) == NULL)
425*5e7646d2SAndroid Build Coastguard Worker {
426*5e7646d2SAndroid Build Coastguard Worker if (errno != ENOENT)
427*5e7646d2SAndroid Build Coastguard Worker {
428*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", line,
429*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
430*5e7646d2SAndroid Build Coastguard Worker return (1);
431*5e7646d2SAndroid Build Coastguard Worker }
432*5e7646d2SAndroid Build Coastguard Worker else
433*5e7646d2SAndroid Build Coastguard Worker return (0);
434*5e7646d2SAndroid Build Coastguard Worker }
435*5e7646d2SAndroid Build Coastguard Worker
436*5e7646d2SAndroid Build Coastguard Worker linenum = 0;
437*5e7646d2SAndroid Build Coastguard Worker
438*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
439*5e7646d2SAndroid Build Coastguard Worker {
440*5e7646d2SAndroid Build Coastguard Worker if (!value)
441*5e7646d2SAndroid Build Coastguard Worker {
442*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: No value found for %s directive on line %d!\n",
443*5e7646d2SAndroid Build Coastguard Worker line, linenum);
444*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
445*5e7646d2SAndroid Build Coastguard Worker return (0);
446*5e7646d2SAndroid Build Coastguard Worker }
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(line, "Cc"))
449*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoCc, value, sizeof(mailtoCc));
450*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "From"))
451*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoFrom, value, sizeof(mailtoFrom));
452*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Sendmail"))
453*5e7646d2SAndroid Build Coastguard Worker {
454*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoSendmail, value, sizeof(mailtoSendmail));
455*5e7646d2SAndroid Build Coastguard Worker mailtoSMTPServer[0] = '\0';
456*5e7646d2SAndroid Build Coastguard Worker }
457*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "SMTPServer"))
458*5e7646d2SAndroid Build Coastguard Worker {
459*5e7646d2SAndroid Build Coastguard Worker mailtoSendmail[0] = '\0';
460*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoSMTPServer, value, sizeof(mailtoSMTPServer));
461*5e7646d2SAndroid Build Coastguard Worker }
462*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Subject"))
463*5e7646d2SAndroid Build Coastguard Worker strlcpy(mailtoSubject, value, sizeof(mailtoSubject));
464*5e7646d2SAndroid Build Coastguard Worker else
465*5e7646d2SAndroid Build Coastguard Worker {
466*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr,
467*5e7646d2SAndroid Build Coastguard Worker "ERROR: Unknown configuration directive \"%s\" on line %d!\n",
468*5e7646d2SAndroid Build Coastguard Worker line, linenum);
469*5e7646d2SAndroid Build Coastguard Worker }
470*5e7646d2SAndroid Build Coastguard Worker }
471*5e7646d2SAndroid Build Coastguard Worker
472*5e7646d2SAndroid Build Coastguard Worker /*
473*5e7646d2SAndroid Build Coastguard Worker * Close file and return...
474*5e7646d2SAndroid Build Coastguard Worker */
475*5e7646d2SAndroid Build Coastguard Worker
476*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
477*5e7646d2SAndroid Build Coastguard Worker
478*5e7646d2SAndroid Build Coastguard Worker return (1);
479*5e7646d2SAndroid Build Coastguard Worker }
480*5e7646d2SAndroid Build Coastguard Worker
481*5e7646d2SAndroid Build Coastguard Worker
482*5e7646d2SAndroid Build Coastguard Worker /*
483*5e7646d2SAndroid Build Coastguard Worker * 'pipe_sendmail()' - Open a pipe to sendmail...
484*5e7646d2SAndroid Build Coastguard Worker */
485*5e7646d2SAndroid Build Coastguard Worker
486*5e7646d2SAndroid Build Coastguard Worker cups_file_t * /* O - CUPS file */
pipe_sendmail(const char * to)487*5e7646d2SAndroid Build Coastguard Worker pipe_sendmail(const char *to) /* I - To: address */
488*5e7646d2SAndroid Build Coastguard Worker {
489*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* CUPS file */
490*5e7646d2SAndroid Build Coastguard Worker int pid; /* Process ID */
491*5e7646d2SAndroid Build Coastguard Worker int pipefds[2]; /* Pipe file descriptors */
492*5e7646d2SAndroid Build Coastguard Worker int argc; /* Number of arguments */
493*5e7646d2SAndroid Build Coastguard Worker char *argv[100], /* Argument array */
494*5e7646d2SAndroid Build Coastguard Worker line[1024], /* Sendmail command + args */
495*5e7646d2SAndroid Build Coastguard Worker *lineptr; /* Pointer into line */
496*5e7646d2SAndroid Build Coastguard Worker
497*5e7646d2SAndroid Build Coastguard Worker
498*5e7646d2SAndroid Build Coastguard Worker /*
499*5e7646d2SAndroid Build Coastguard Worker * First break the mailtoSendmail string into arguments...
500*5e7646d2SAndroid Build Coastguard Worker */
501*5e7646d2SAndroid Build Coastguard Worker
502*5e7646d2SAndroid Build Coastguard Worker strlcpy(line, mailtoSendmail, sizeof(line));
503*5e7646d2SAndroid Build Coastguard Worker argv[0] = line;
504*5e7646d2SAndroid Build Coastguard Worker argc = 1;
505*5e7646d2SAndroid Build Coastguard Worker
506*5e7646d2SAndroid Build Coastguard Worker for (lineptr = strchr(line, ' '); lineptr; lineptr = strchr(lineptr, ' '))
507*5e7646d2SAndroid Build Coastguard Worker {
508*5e7646d2SAndroid Build Coastguard Worker while (*lineptr == ' ')
509*5e7646d2SAndroid Build Coastguard Worker *lineptr++ = '\0';
510*5e7646d2SAndroid Build Coastguard Worker
511*5e7646d2SAndroid Build Coastguard Worker if (*lineptr)
512*5e7646d2SAndroid Build Coastguard Worker {
513*5e7646d2SAndroid Build Coastguard Worker /*
514*5e7646d2SAndroid Build Coastguard Worker * Point to the next argument...
515*5e7646d2SAndroid Build Coastguard Worker */
516*5e7646d2SAndroid Build Coastguard Worker
517*5e7646d2SAndroid Build Coastguard Worker argv[argc ++] = lineptr;
518*5e7646d2SAndroid Build Coastguard Worker
519*5e7646d2SAndroid Build Coastguard Worker /*
520*5e7646d2SAndroid Build Coastguard Worker * Stop if we have too many...
521*5e7646d2SAndroid Build Coastguard Worker */
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker if (argc >= (int)(sizeof(argv) / sizeof(argv[0]) - 2))
524*5e7646d2SAndroid Build Coastguard Worker break;
525*5e7646d2SAndroid Build Coastguard Worker }
526*5e7646d2SAndroid Build Coastguard Worker }
527*5e7646d2SAndroid Build Coastguard Worker
528*5e7646d2SAndroid Build Coastguard Worker argv[argc ++] = (char *)to;
529*5e7646d2SAndroid Build Coastguard Worker argv[argc] = NULL;
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker /*
532*5e7646d2SAndroid Build Coastguard Worker * Create the pipe...
533*5e7646d2SAndroid Build Coastguard Worker */
534*5e7646d2SAndroid Build Coastguard Worker
535*5e7646d2SAndroid Build Coastguard Worker if (pipe(pipefds))
536*5e7646d2SAndroid Build Coastguard Worker {
537*5e7646d2SAndroid Build Coastguard Worker perror("ERROR: Unable to create pipe");
538*5e7646d2SAndroid Build Coastguard Worker return (NULL);
539*5e7646d2SAndroid Build Coastguard Worker }
540*5e7646d2SAndroid Build Coastguard Worker
541*5e7646d2SAndroid Build Coastguard Worker /*
542*5e7646d2SAndroid Build Coastguard Worker * Then run the command...
543*5e7646d2SAndroid Build Coastguard Worker */
544*5e7646d2SAndroid Build Coastguard Worker
545*5e7646d2SAndroid Build Coastguard Worker if ((pid = fork()) == 0)
546*5e7646d2SAndroid Build Coastguard Worker {
547*5e7646d2SAndroid Build Coastguard Worker /*
548*5e7646d2SAndroid Build Coastguard Worker * Child goes here - redirect stdin to the input side of the pipe,
549*5e7646d2SAndroid Build Coastguard Worker * redirect stdout to stderr, and exec...
550*5e7646d2SAndroid Build Coastguard Worker */
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker close(0);
553*5e7646d2SAndroid Build Coastguard Worker dup(pipefds[0]);
554*5e7646d2SAndroid Build Coastguard Worker
555*5e7646d2SAndroid Build Coastguard Worker close(1);
556*5e7646d2SAndroid Build Coastguard Worker dup(2);
557*5e7646d2SAndroid Build Coastguard Worker
558*5e7646d2SAndroid Build Coastguard Worker close(pipefds[0]);
559*5e7646d2SAndroid Build Coastguard Worker close(pipefds[1]);
560*5e7646d2SAndroid Build Coastguard Worker
561*5e7646d2SAndroid Build Coastguard Worker execvp(argv[0], argv);
562*5e7646d2SAndroid Build Coastguard Worker exit(errno);
563*5e7646d2SAndroid Build Coastguard Worker }
564*5e7646d2SAndroid Build Coastguard Worker else if (pid < 0)
565*5e7646d2SAndroid Build Coastguard Worker {
566*5e7646d2SAndroid Build Coastguard Worker /*
567*5e7646d2SAndroid Build Coastguard Worker * Unable to fork - error out...
568*5e7646d2SAndroid Build Coastguard Worker */
569*5e7646d2SAndroid Build Coastguard Worker
570*5e7646d2SAndroid Build Coastguard Worker perror("ERROR: Unable to fork command");
571*5e7646d2SAndroid Build Coastguard Worker
572*5e7646d2SAndroid Build Coastguard Worker close(pipefds[0]);
573*5e7646d2SAndroid Build Coastguard Worker close(pipefds[1]);
574*5e7646d2SAndroid Build Coastguard Worker
575*5e7646d2SAndroid Build Coastguard Worker return (NULL);
576*5e7646d2SAndroid Build Coastguard Worker }
577*5e7646d2SAndroid Build Coastguard Worker
578*5e7646d2SAndroid Build Coastguard Worker /*
579*5e7646d2SAndroid Build Coastguard Worker * Create a CUPS file using the output side of the pipe and close the
580*5e7646d2SAndroid Build Coastguard Worker * input side...
581*5e7646d2SAndroid Build Coastguard Worker */
582*5e7646d2SAndroid Build Coastguard Worker
583*5e7646d2SAndroid Build Coastguard Worker close(pipefds[0]);
584*5e7646d2SAndroid Build Coastguard Worker
585*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpenFd(pipefds[1], "w")) == NULL)
586*5e7646d2SAndroid Build Coastguard Worker {
587*5e7646d2SAndroid Build Coastguard Worker int status; /* Status of command */
588*5e7646d2SAndroid Build Coastguard Worker
589*5e7646d2SAndroid Build Coastguard Worker
590*5e7646d2SAndroid Build Coastguard Worker close(pipefds[1]);
591*5e7646d2SAndroid Build Coastguard Worker wait(&status);
592*5e7646d2SAndroid Build Coastguard Worker }
593*5e7646d2SAndroid Build Coastguard Worker
594*5e7646d2SAndroid Build Coastguard Worker return (fp);
595*5e7646d2SAndroid Build Coastguard Worker }
596*5e7646d2SAndroid Build Coastguard Worker
597*5e7646d2SAndroid Build Coastguard Worker
598*5e7646d2SAndroid Build Coastguard Worker /*
599*5e7646d2SAndroid Build Coastguard Worker * 'print_attributes()' - Print the attributes in a request...
600*5e7646d2SAndroid Build Coastguard Worker */
601*5e7646d2SAndroid Build Coastguard Worker
602*5e7646d2SAndroid Build Coastguard Worker void
print_attributes(ipp_t * ipp,int indent)603*5e7646d2SAndroid Build Coastguard Worker print_attributes(ipp_t *ipp, /* I - IPP request */
604*5e7646d2SAndroid Build Coastguard Worker int indent) /* I - Indentation */
605*5e7646d2SAndroid Build Coastguard Worker {
606*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group; /* Current group */
607*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
608*5e7646d2SAndroid Build Coastguard Worker char buffer[1024]; /* Value buffer */
609*5e7646d2SAndroid Build Coastguard Worker
610*5e7646d2SAndroid Build Coastguard Worker
611*5e7646d2SAndroid Build Coastguard Worker for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
612*5e7646d2SAndroid Build Coastguard Worker {
613*5e7646d2SAndroid Build Coastguard Worker if ((attr->group_tag == IPP_TAG_ZERO && indent <= 8) || !attr->name)
614*5e7646d2SAndroid Build Coastguard Worker {
615*5e7646d2SAndroid Build Coastguard Worker group = IPP_TAG_ZERO;
616*5e7646d2SAndroid Build Coastguard Worker fputc('\n', stderr);
617*5e7646d2SAndroid Build Coastguard Worker continue;
618*5e7646d2SAndroid Build Coastguard Worker }
619*5e7646d2SAndroid Build Coastguard Worker
620*5e7646d2SAndroid Build Coastguard Worker if (group != attr->group_tag)
621*5e7646d2SAndroid Build Coastguard Worker {
622*5e7646d2SAndroid Build Coastguard Worker group = attr->group_tag;
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", ippTagString(group));
625*5e7646d2SAndroid Build Coastguard Worker }
626*5e7646d2SAndroid Build Coastguard Worker
627*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(attr, buffer, sizeof(buffer));
628*5e7646d2SAndroid Build Coastguard Worker
629*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: %*s%s (%s%s) %s", indent, "", attr->name,
630*5e7646d2SAndroid Build Coastguard Worker attr->num_values > 1 ? "1setOf " : "",
631*5e7646d2SAndroid Build Coastguard Worker ippTagString(attr->value_tag), buffer);
632*5e7646d2SAndroid Build Coastguard Worker }
633*5e7646d2SAndroid Build Coastguard Worker }
634