xref: /aosp_15_r20/external/libcups/backend/network.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Common backend network APIs for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2016 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2006-2007 by Easy Software Products, all rights reserved.
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 "backend-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include <limits.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <sys/select.h>
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker 
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker  * 'backendCheckSideChannel()' - Check the side-channel for pending requests.
22*5e7646d2SAndroid Build Coastguard Worker  */
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker void
backendCheckSideChannel(int snmp_fd,http_addr_t * addr)25*5e7646d2SAndroid Build Coastguard Worker backendCheckSideChannel(
26*5e7646d2SAndroid Build Coastguard Worker     int         snmp_fd,		/* I - SNMP socket */
27*5e7646d2SAndroid Build Coastguard Worker     http_addr_t *addr)			/* I - Address of device */
28*5e7646d2SAndroid Build Coastguard Worker {
29*5e7646d2SAndroid Build Coastguard Worker   fd_set	input;			/* Select input set */
30*5e7646d2SAndroid Build Coastguard Worker   struct timeval timeout;		/* Select timeout */
31*5e7646d2SAndroid Build Coastguard Worker 
32*5e7646d2SAndroid Build Coastguard Worker 
33*5e7646d2SAndroid Build Coastguard Worker   FD_ZERO(&input);
34*5e7646d2SAndroid Build Coastguard Worker   FD_SET(CUPS_SC_FD, &input);
35*5e7646d2SAndroid Build Coastguard Worker 
36*5e7646d2SAndroid Build Coastguard Worker   timeout.tv_sec = timeout.tv_usec = 0;
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker   if (select(CUPS_SC_FD + 1, &input, NULL, NULL, &timeout) > 0)
39*5e7646d2SAndroid Build Coastguard Worker     backendNetworkSideCB(-1, -1, snmp_fd, addr, 0);
40*5e7646d2SAndroid Build Coastguard Worker }
41*5e7646d2SAndroid Build Coastguard Worker 
42*5e7646d2SAndroid Build Coastguard Worker 
43*5e7646d2SAndroid Build Coastguard Worker /*
44*5e7646d2SAndroid Build Coastguard Worker  * 'backendLookup()' - Lookup the given host and log addresses.
45*5e7646d2SAndroid Build Coastguard Worker  */
46*5e7646d2SAndroid Build Coastguard Worker 
47*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t	*			/* O - List of addresses or NULL */
backendLookup(const char * hostname,int port,int * cancel)48*5e7646d2SAndroid Build Coastguard Worker backendLookup(const char *hostname,	/* I - Hostname */
49*5e7646d2SAndroid Build Coastguard Worker               int        port,		/* I - Port number */
50*5e7646d2SAndroid Build Coastguard Worker 	      int        *cancel)	/* I - Variable to watch for job cancel */
51*5e7646d2SAndroid Build Coastguard Worker {
52*5e7646d2SAndroid Build Coastguard Worker   char			portname[32],	/* Port number as string */
53*5e7646d2SAndroid Build Coastguard Worker 			addrname[256];	/* Address as string */
54*5e7646d2SAndroid Build Coastguard Worker   http_addrlist_t	*addrlist,	/* List of addresses */
55*5e7646d2SAndroid Build Coastguard Worker 			*current;	/* Current address */
56*5e7646d2SAndroid Build Coastguard Worker 
57*5e7646d2SAndroid Build Coastguard Worker 
58*5e7646d2SAndroid Build Coastguard Worker  /*
59*5e7646d2SAndroid Build Coastguard Worker   * Lookup the address for the named host...
60*5e7646d2SAndroid Build Coastguard Worker   */
61*5e7646d2SAndroid Build Coastguard Worker 
62*5e7646d2SAndroid Build Coastguard Worker   snprintf(portname, sizeof(portname), "%d", port);
63*5e7646d2SAndroid Build Coastguard Worker 
64*5e7646d2SAndroid Build Coastguard Worker   fputs("STATE: +connecting-to-device\n", stderr);
65*5e7646d2SAndroid Build Coastguard Worker   fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname);
66*5e7646d2SAndroid Build Coastguard Worker 
67*5e7646d2SAndroid Build Coastguard Worker   while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
68*5e7646d2SAndroid Build Coastguard Worker   {
69*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer \"%s\"."), hostname);
70*5e7646d2SAndroid Build Coastguard Worker     sleep(10);
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker     if (getenv("CLASS") != NULL)
73*5e7646d2SAndroid Build Coastguard Worker     {
74*5e7646d2SAndroid Build Coastguard Worker       fputs("STATE: -connecting-to-device\n", stderr);
75*5e7646d2SAndroid Build Coastguard Worker       exit(CUPS_BACKEND_STOP);
76*5e7646d2SAndroid Build Coastguard Worker     }
77*5e7646d2SAndroid Build Coastguard Worker 
78*5e7646d2SAndroid Build Coastguard Worker     if (cancel && *cancel)
79*5e7646d2SAndroid Build Coastguard Worker     {
80*5e7646d2SAndroid Build Coastguard Worker       fputs("STATE: -connecting-to-device\n", stderr);
81*5e7646d2SAndroid Build Coastguard Worker       exit(CUPS_BACKEND_OK);
82*5e7646d2SAndroid Build Coastguard Worker     }
83*5e7646d2SAndroid Build Coastguard Worker   }
84*5e7646d2SAndroid Build Coastguard Worker 
85*5e7646d2SAndroid Build Coastguard Worker   fputs("STATE: -connecting-to-device\n", stderr);
86*5e7646d2SAndroid Build Coastguard Worker 
87*5e7646d2SAndroid Build Coastguard Worker  /*
88*5e7646d2SAndroid Build Coastguard Worker   * Log the addresses we got...
89*5e7646d2SAndroid Build Coastguard Worker   */
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker   for (current = addrlist; current; current = current->next)
92*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "DEBUG: %s=%s\n", hostname, httpAddrString(&current->addr, addrname, sizeof(addrname)));
93*5e7646d2SAndroid Build Coastguard Worker 
94*5e7646d2SAndroid Build Coastguard Worker  /*
95*5e7646d2SAndroid Build Coastguard Worker   * Return...
96*5e7646d2SAndroid Build Coastguard Worker   */
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker   return (addrlist);
99*5e7646d2SAndroid Build Coastguard Worker }
100*5e7646d2SAndroid Build Coastguard Worker 
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker /*
103*5e7646d2SAndroid Build Coastguard Worker  * 'backendNetworkSideCB()' - Handle common network side-channel commands.
104*5e7646d2SAndroid Build Coastguard Worker  */
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker int					/* O - -1 on error, 0 on success */
backendNetworkSideCB(int print_fd,int device_fd,int snmp_fd,http_addr_t * addr,int use_bc)107*5e7646d2SAndroid Build Coastguard Worker backendNetworkSideCB(
108*5e7646d2SAndroid Build Coastguard Worker     int         print_fd,		/* I - Print file or -1 */
109*5e7646d2SAndroid Build Coastguard Worker     int         device_fd,		/* I - Device file or -1 */
110*5e7646d2SAndroid Build Coastguard Worker     int         snmp_fd,		/* I - SNMP socket */
111*5e7646d2SAndroid Build Coastguard Worker     http_addr_t *addr,			/* I - Address of device */
112*5e7646d2SAndroid Build Coastguard Worker     int         use_bc)			/* I - Use back-channel data? */
113*5e7646d2SAndroid Build Coastguard Worker {
114*5e7646d2SAndroid Build Coastguard Worker   cups_sc_command_t	command;	/* Request command */
115*5e7646d2SAndroid Build Coastguard Worker   cups_sc_status_t	status;		/* Request/response status */
116*5e7646d2SAndroid Build Coastguard Worker   char			data[65536];	/* Request/response data */
117*5e7646d2SAndroid Build Coastguard Worker   int			datalen;	/* Request/response data size */
118*5e7646d2SAndroid Build Coastguard Worker   const char		*device_id;	/* 1284DEVICEID env var */
119*5e7646d2SAndroid Build Coastguard Worker 
120*5e7646d2SAndroid Build Coastguard Worker 
121*5e7646d2SAndroid Build Coastguard Worker   datalen = sizeof(data);
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker   if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
124*5e7646d2SAndroid Build Coastguard Worker     return (-1);
125*5e7646d2SAndroid Build Coastguard Worker 
126*5e7646d2SAndroid Build Coastguard Worker   switch (command)
127*5e7646d2SAndroid Build Coastguard Worker   {
128*5e7646d2SAndroid Build Coastguard Worker     case CUPS_SC_CMD_DRAIN_OUTPUT :
129*5e7646d2SAndroid Build Coastguard Worker        /*
130*5e7646d2SAndroid Build Coastguard Worker         * Our sockets disable the Nagle algorithm and data is sent immediately.
131*5e7646d2SAndroid Build Coastguard Worker 	*/
132*5e7646d2SAndroid Build Coastguard Worker 
133*5e7646d2SAndroid Build Coastguard Worker         if (device_fd < 0)
134*5e7646d2SAndroid Build Coastguard Worker 	  status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
135*5e7646d2SAndroid Build Coastguard Worker 	else if (backendDrainOutput(print_fd, device_fd))
136*5e7646d2SAndroid Build Coastguard Worker 	  status = CUPS_SC_STATUS_IO_ERROR;
137*5e7646d2SAndroid Build Coastguard Worker 	else
138*5e7646d2SAndroid Build Coastguard Worker           status = CUPS_SC_STATUS_OK;
139*5e7646d2SAndroid Build Coastguard Worker 
140*5e7646d2SAndroid Build Coastguard Worker 	datalen = 0;
141*5e7646d2SAndroid Build Coastguard Worker         break;
142*5e7646d2SAndroid Build Coastguard Worker 
143*5e7646d2SAndroid Build Coastguard Worker     case CUPS_SC_CMD_GET_BIDI :
144*5e7646d2SAndroid Build Coastguard Worker 	status  = CUPS_SC_STATUS_OK;
145*5e7646d2SAndroid Build Coastguard Worker         data[0] = (char)use_bc;
146*5e7646d2SAndroid Build Coastguard Worker         datalen = 1;
147*5e7646d2SAndroid Build Coastguard Worker         break;
148*5e7646d2SAndroid Build Coastguard Worker 
149*5e7646d2SAndroid Build Coastguard Worker     case CUPS_SC_CMD_SNMP_GET :
150*5e7646d2SAndroid Build Coastguard Worker     case CUPS_SC_CMD_SNMP_GET_NEXT :
151*5e7646d2SAndroid Build Coastguard Worker         fprintf(stderr, "DEBUG: CUPS_SC_CMD_SNMP_%s: %d (%s)\n",
152*5e7646d2SAndroid Build Coastguard Worker 	        command == CUPS_SC_CMD_SNMP_GET ? "GET" : "GET_NEXT", datalen,
153*5e7646d2SAndroid Build Coastguard Worker 		data);
154*5e7646d2SAndroid Build Coastguard Worker 
155*5e7646d2SAndroid Build Coastguard Worker         if (datalen < 2)
156*5e7646d2SAndroid Build Coastguard Worker 	{
157*5e7646d2SAndroid Build Coastguard Worker 	  status  = CUPS_SC_STATUS_BAD_MESSAGE;
158*5e7646d2SAndroid Build Coastguard Worker 	  datalen = 0;
159*5e7646d2SAndroid Build Coastguard Worker 	  break;
160*5e7646d2SAndroid Build Coastguard Worker 	}
161*5e7646d2SAndroid Build Coastguard Worker 
162*5e7646d2SAndroid Build Coastguard Worker         if (snmp_fd >= 0)
163*5e7646d2SAndroid Build Coastguard Worker 	{
164*5e7646d2SAndroid Build Coastguard Worker 	  char		*dataptr;	/* Pointer into data */
165*5e7646d2SAndroid Build Coastguard Worker 	  cups_snmp_t	packet;		/* Packet from printer */
166*5e7646d2SAndroid Build Coastguard Worker           const char	*snmp_value;	/* CUPS_SNMP_VALUE env var */
167*5e7646d2SAndroid Build Coastguard Worker 
168*5e7646d2SAndroid Build Coastguard Worker           if ((snmp_value = getenv("CUPS_SNMP_VALUE")) != NULL)
169*5e7646d2SAndroid Build Coastguard Worker           {
170*5e7646d2SAndroid Build Coastguard Worker             const char	*snmp_count;	/* CUPS_SNMP_COUNT env var */
171*5e7646d2SAndroid Build Coastguard Worker             int		count;		/* Repetition count */
172*5e7646d2SAndroid Build Coastguard Worker 
173*5e7646d2SAndroid Build Coastguard Worker             if ((snmp_count = getenv("CUPS_SNMP_COUNT")) != NULL)
174*5e7646d2SAndroid Build Coastguard Worker             {
175*5e7646d2SAndroid Build Coastguard Worker               if ((count = atoi(snmp_count)) <= 0)
176*5e7646d2SAndroid Build Coastguard Worker                 count = 1;
177*5e7646d2SAndroid Build Coastguard Worker             }
178*5e7646d2SAndroid Build Coastguard Worker             else
179*5e7646d2SAndroid Build Coastguard Worker               count = 1;
180*5e7646d2SAndroid Build Coastguard Worker 
181*5e7646d2SAndroid Build Coastguard Worker 	    for (dataptr = data + strlen(data) + 1;
182*5e7646d2SAndroid Build Coastguard Worker 	         count > 0 && dataptr < (data + sizeof(data) - 1);
183*5e7646d2SAndroid Build Coastguard Worker 	         count --, dataptr += strlen(dataptr))
184*5e7646d2SAndroid Build Coastguard Worker 	      strlcpy(dataptr, snmp_value, sizeof(data) - (size_t)(dataptr - data));
185*5e7646d2SAndroid Build Coastguard Worker 
186*5e7646d2SAndroid Build Coastguard Worker 	    fprintf(stderr, "DEBUG: Returning %s %s\n", data,
187*5e7646d2SAndroid Build Coastguard Worker 	            data + strlen(data) + 1);
188*5e7646d2SAndroid Build Coastguard Worker 
189*5e7646d2SAndroid Build Coastguard Worker 	    status  = CUPS_SC_STATUS_OK;
190*5e7646d2SAndroid Build Coastguard Worker 	    datalen = (int)(dataptr - data);
191*5e7646d2SAndroid Build Coastguard Worker 	    break;
192*5e7646d2SAndroid Build Coastguard Worker           }
193*5e7646d2SAndroid Build Coastguard Worker 
194*5e7646d2SAndroid Build Coastguard Worker           if (!_cupsSNMPStringToOID(data, packet.object_name, CUPS_SNMP_MAX_OID))
195*5e7646d2SAndroid Build Coastguard Worker 	  {
196*5e7646d2SAndroid Build Coastguard Worker 	    status  = CUPS_SC_STATUS_BAD_MESSAGE;
197*5e7646d2SAndroid Build Coastguard Worker 	    datalen = 0;
198*5e7646d2SAndroid Build Coastguard Worker 	    break;
199*5e7646d2SAndroid Build Coastguard Worker 	  }
200*5e7646d2SAndroid Build Coastguard Worker 
201*5e7646d2SAndroid Build Coastguard Worker           status  = CUPS_SC_STATUS_IO_ERROR;
202*5e7646d2SAndroid Build Coastguard Worker 	  datalen = 0;
203*5e7646d2SAndroid Build Coastguard Worker 
204*5e7646d2SAndroid Build Coastguard Worker           if (_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
205*5e7646d2SAndroid Build Coastguard Worker 	                     _cupsSNMPDefaultCommunity(),
206*5e7646d2SAndroid Build Coastguard Worker 	                     command == CUPS_SC_CMD_SNMP_GET ?
207*5e7646d2SAndroid Build Coastguard Worker 			         CUPS_ASN1_GET_REQUEST :
208*5e7646d2SAndroid Build Coastguard Worker 				 CUPS_ASN1_GET_NEXT_REQUEST, 1,
209*5e7646d2SAndroid Build Coastguard Worker 			     packet.object_name))
210*5e7646d2SAndroid Build Coastguard Worker           {
211*5e7646d2SAndroid Build Coastguard Worker 	    if (_cupsSNMPRead(snmp_fd, &packet, 1.0))
212*5e7646d2SAndroid Build Coastguard Worker 	    {
213*5e7646d2SAndroid Build Coastguard Worker 	      size_t	i;		/* Looping var */
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker 
216*5e7646d2SAndroid Build Coastguard Worker               if (!_cupsSNMPOIDToString(packet.object_name, data, sizeof(data)))
217*5e7646d2SAndroid Build Coastguard Worker 	      {
218*5e7646d2SAndroid Build Coastguard Worker 	        fputs("DEBUG: Bad OID returned!\n", stderr);
219*5e7646d2SAndroid Build Coastguard Worker 	        break;
220*5e7646d2SAndroid Build Coastguard Worker 	      }
221*5e7646d2SAndroid Build Coastguard Worker 
222*5e7646d2SAndroid Build Coastguard Worker 	      datalen = (int)strlen(data) + 1;
223*5e7646d2SAndroid Build Coastguard Worker               dataptr = data + datalen;
224*5e7646d2SAndroid Build Coastguard Worker 
225*5e7646d2SAndroid Build Coastguard Worker 	      switch (packet.object_type)
226*5e7646d2SAndroid Build Coastguard Worker 	      {
227*5e7646d2SAndroid Build Coastguard Worker 	        case CUPS_ASN1_BOOLEAN :
228*5e7646d2SAndroid Build Coastguard Worker 		    snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%d", packet.object_value.boolean);
229*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
230*5e7646d2SAndroid Build Coastguard Worker 		    break;
231*5e7646d2SAndroid Build Coastguard Worker 
232*5e7646d2SAndroid Build Coastguard Worker 	        case CUPS_ASN1_INTEGER :
233*5e7646d2SAndroid Build Coastguard Worker 		    snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%d",
234*5e7646d2SAndroid Build Coastguard Worker 		             packet.object_value.integer);
235*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
236*5e7646d2SAndroid Build Coastguard Worker 		    break;
237*5e7646d2SAndroid Build Coastguard Worker 
238*5e7646d2SAndroid Build Coastguard Worker 	        case CUPS_ASN1_BIT_STRING :
239*5e7646d2SAndroid Build Coastguard Worker 	        case CUPS_ASN1_OCTET_STRING :
240*5e7646d2SAndroid Build Coastguard Worker 		    if (packet.object_value.string.num_bytes < (sizeof(data) - (size_t)(dataptr - data)))
241*5e7646d2SAndroid Build Coastguard Worker 		      i = packet.object_value.string.num_bytes;
242*5e7646d2SAndroid Build Coastguard Worker 		    else
243*5e7646d2SAndroid Build Coastguard Worker 		      i = sizeof(data) - (size_t)(dataptr - data);
244*5e7646d2SAndroid Build Coastguard Worker 
245*5e7646d2SAndroid Build Coastguard Worker 		    memcpy(dataptr, packet.object_value.string.bytes, i);
246*5e7646d2SAndroid Build Coastguard Worker 
247*5e7646d2SAndroid Build Coastguard Worker                     datalen += (int)i;
248*5e7646d2SAndroid Build Coastguard Worker 		    break;
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker 	        case CUPS_ASN1_OID :
251*5e7646d2SAndroid Build Coastguard Worker 		    _cupsSNMPOIDToString(packet.object_value.oid, dataptr,
252*5e7646d2SAndroid Build Coastguard Worker 		                         sizeof(data) - (size_t)(dataptr - data));
253*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
254*5e7646d2SAndroid Build Coastguard Worker 		    break;
255*5e7646d2SAndroid Build Coastguard Worker 
256*5e7646d2SAndroid Build Coastguard Worker                 case CUPS_ASN1_HEX_STRING :
257*5e7646d2SAndroid Build Coastguard Worker 		    for (i = 0;
258*5e7646d2SAndroid Build Coastguard Worker 		         i < packet.object_value.string.num_bytes &&
259*5e7646d2SAndroid Build Coastguard Worker 			     dataptr < (data + sizeof(data) - 3);
260*5e7646d2SAndroid Build Coastguard Worker 			 i ++, dataptr += 2)
261*5e7646d2SAndroid Build Coastguard Worker 		      snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%02X", packet.object_value.string.bytes[i]);
262*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
263*5e7646d2SAndroid Build Coastguard Worker 		    break;
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker                 case CUPS_ASN1_COUNTER :
266*5e7646d2SAndroid Build Coastguard Worker 		    snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%u", packet.object_value.counter);
267*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
268*5e7646d2SAndroid Build Coastguard Worker 		    break;
269*5e7646d2SAndroid Build Coastguard Worker 
270*5e7646d2SAndroid Build Coastguard Worker                 case CUPS_ASN1_GAUGE :
271*5e7646d2SAndroid Build Coastguard Worker 		    snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%u", packet.object_value.gauge);
272*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
273*5e7646d2SAndroid Build Coastguard Worker 		    break;
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker                 case CUPS_ASN1_TIMETICKS :
276*5e7646d2SAndroid Build Coastguard Worker 		    snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%u", packet.object_value.timeticks);
277*5e7646d2SAndroid Build Coastguard Worker 	            datalen += (int)strlen(dataptr);
278*5e7646d2SAndroid Build Coastguard Worker 		    break;
279*5e7646d2SAndroid Build Coastguard Worker 
280*5e7646d2SAndroid Build Coastguard Worker                 default :
281*5e7646d2SAndroid Build Coastguard Worker 	            fprintf(stderr, "DEBUG: Unknown OID value type %02X.\n", packet.object_type);
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker 		case CUPS_ASN1_NULL_VALUE :
284*5e7646d2SAndroid Build Coastguard Worker 		    dataptr[0] = '\0';
285*5e7646d2SAndroid Build Coastguard Worker 		    break;
286*5e7646d2SAndroid Build Coastguard Worker               }
287*5e7646d2SAndroid Build Coastguard Worker 
288*5e7646d2SAndroid Build Coastguard Worker 	      fprintf(stderr, "DEBUG: Returning %s %s\n", data, data + datalen);
289*5e7646d2SAndroid Build Coastguard Worker 
290*5e7646d2SAndroid Build Coastguard Worker 	      status = CUPS_SC_STATUS_OK;
291*5e7646d2SAndroid Build Coastguard Worker 	    }
292*5e7646d2SAndroid Build Coastguard Worker 	    else
293*5e7646d2SAndroid Build Coastguard Worker 	      fputs("DEBUG: SNMP read error...\n", stderr);
294*5e7646d2SAndroid Build Coastguard Worker 	  }
295*5e7646d2SAndroid Build Coastguard Worker 	  else
296*5e7646d2SAndroid Build Coastguard Worker 	    fputs("DEBUG: SNMP write error...\n", stderr);
297*5e7646d2SAndroid Build Coastguard Worker 	  break;
298*5e7646d2SAndroid Build Coastguard Worker         }
299*5e7646d2SAndroid Build Coastguard Worker 
300*5e7646d2SAndroid Build Coastguard Worker         status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
301*5e7646d2SAndroid Build Coastguard Worker 	datalen = 0;
302*5e7646d2SAndroid Build Coastguard Worker 	break;
303*5e7646d2SAndroid Build Coastguard Worker 
304*5e7646d2SAndroid Build Coastguard Worker     case CUPS_SC_CMD_GET_CONNECTED :
305*5e7646d2SAndroid Build Coastguard Worker 	status  = CUPS_SC_STATUS_OK;
306*5e7646d2SAndroid Build Coastguard Worker         data[0] = device_fd != -1;
307*5e7646d2SAndroid Build Coastguard Worker         datalen = 1;
308*5e7646d2SAndroid Build Coastguard Worker         break;
309*5e7646d2SAndroid Build Coastguard Worker 
310*5e7646d2SAndroid Build Coastguard Worker     case CUPS_SC_CMD_GET_DEVICE_ID :
311*5e7646d2SAndroid Build Coastguard Worker         if (snmp_fd >= 0)
312*5e7646d2SAndroid Build Coastguard Worker 	{
313*5e7646d2SAndroid Build Coastguard Worker 	  cups_snmp_t	packet;		/* Packet from printer */
314*5e7646d2SAndroid Build Coastguard Worker 	  static const int ppmPrinterIEEE1284DeviceId[] =
315*5e7646d2SAndroid Build Coastguard Worker 	  		{ CUPS_OID_ppmPrinterIEEE1284DeviceId,1,-1 };
316*5e7646d2SAndroid Build Coastguard Worker 
317*5e7646d2SAndroid Build Coastguard Worker 
318*5e7646d2SAndroid Build Coastguard Worker           status  = CUPS_SC_STATUS_IO_ERROR;
319*5e7646d2SAndroid Build Coastguard Worker 	  datalen = 0;
320*5e7646d2SAndroid Build Coastguard Worker 
321*5e7646d2SAndroid Build Coastguard Worker           if (_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
322*5e7646d2SAndroid Build Coastguard Worker 	                     _cupsSNMPDefaultCommunity(),
323*5e7646d2SAndroid Build Coastguard Worker 	                     CUPS_ASN1_GET_REQUEST, 1,
324*5e7646d2SAndroid Build Coastguard Worker 			     ppmPrinterIEEE1284DeviceId))
325*5e7646d2SAndroid Build Coastguard Worker           {
326*5e7646d2SAndroid Build Coastguard Worker 	    if (_cupsSNMPRead(snmp_fd, &packet, 1.0) &&
327*5e7646d2SAndroid Build Coastguard Worker 	        packet.object_type == CUPS_ASN1_OCTET_STRING)
328*5e7646d2SAndroid Build Coastguard Worker 	    {
329*5e7646d2SAndroid Build Coastguard Worker 	      strlcpy(data, (char *)packet.object_value.string.bytes,
330*5e7646d2SAndroid Build Coastguard Worker 	              sizeof(data));
331*5e7646d2SAndroid Build Coastguard Worker 	      datalen = (int)strlen(data);
332*5e7646d2SAndroid Build Coastguard Worker 	      status  = CUPS_SC_STATUS_OK;
333*5e7646d2SAndroid Build Coastguard Worker 	    }
334*5e7646d2SAndroid Build Coastguard Worker 	  }
335*5e7646d2SAndroid Build Coastguard Worker 
336*5e7646d2SAndroid Build Coastguard Worker 	  break;
337*5e7646d2SAndroid Build Coastguard Worker         }
338*5e7646d2SAndroid Build Coastguard Worker 
339*5e7646d2SAndroid Build Coastguard Worker 	if ((device_id = getenv("1284DEVICEID")) != NULL)
340*5e7646d2SAndroid Build Coastguard Worker 	{
341*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(data, device_id, sizeof(data));
342*5e7646d2SAndroid Build Coastguard Worker 	  datalen = (int)strlen(data);
343*5e7646d2SAndroid Build Coastguard Worker 	  status  = CUPS_SC_STATUS_OK;
344*5e7646d2SAndroid Build Coastguard Worker 	  break;
345*5e7646d2SAndroid Build Coastguard Worker 	}
346*5e7646d2SAndroid Build Coastguard Worker 
347*5e7646d2SAndroid Build Coastguard Worker     default :
348*5e7646d2SAndroid Build Coastguard Worker         status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
349*5e7646d2SAndroid Build Coastguard Worker 	datalen = 0;
350*5e7646d2SAndroid Build Coastguard Worker 	break;
351*5e7646d2SAndroid Build Coastguard Worker   }
352*5e7646d2SAndroid Build Coastguard Worker 
353*5e7646d2SAndroid Build Coastguard Worker   return (cupsSideChannelWrite(command, status, data, datalen, 1.0));
354*5e7646d2SAndroid Build Coastguard Worker }
355