From: jlovell
Date: Mon, 24 Apr 2006 18:03:36 +0000 (+0000)
Subject: Load cups into easysw/current.
X-Git-Tag: release-1.6.3~238
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89d46774ee527faaaf27d1b696554f4508bf105b;p=thirdparty%2Fcups.git
Load cups into easysw/current.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@136 a1ca3aef-8c08-0410-bb20-df032aa958be
---
diff --git a/CHANGES.txt b/CHANGES.txt
index 604557f50c..64fc2de688 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,7 +1,70 @@
-CHANGES.txt - 2006-04-07
+CHANGES.txt - 2006-04-24
------------------------
-CHANGES IN CUPS V1.2
+CHANGES IN CUPS V1.2rc3
+
+ - The cups-lpd program always did reverse lookups on the
+ client address, which could be a performance problem.
+ Added a "-n" option to disable lookups.
+ - When configured with SSL support, require encryption by
+ default when displaying the /admin location (STR #1592)
+ - The next job ID was not computed correctly if the job
+ cache file got out of sync with the spool directory
+ (STR #1582)
+ - The PNG image handling code used deprecated functions
+ from libpng (STR #1587)
+ - Added a Polish translation (STR #1584, STR #1586)
+ - More changes to the scheduler to improve battery life
+ on portable devices (STR #1583)
+ - Changed the default log level for status messages back
+ to "DEBUG" to be consistent with CUPS 1.1.x (STR #1579)
+ - The error string was not set properly when
+ cupsDoFileRequest() was given the name of a directory
+ (STR #1578)
+ - Fixed handling of job-hold-until (STR #1581)
+ - Added explicit notes to the cupsaddsmb man page
+ explaining that the driver filenames are case-sensitive
+ under UNIX and that they must be all lowercase (Windows
+ 2000) or all UPPERCASE (Windows 95/98/Me) to work (STR
+ #1568)
+ - The USB backend incorrectly split the manufacturer name
+ if it contained spaces (STR #1566)
+ - The scheduler would hang when listing PPD files for a
+ manufacturer whose name contained spaces (STR #1567)
+ - Added the SNMP backend for network printer discovery
+ (STR #1555)
+ - cupstestppd now fails PPD files with 1284DeviceId
+ instead of 1284DeviceID, and cups-driverd uses a
+ case-insensitive comparison when looking for it (STR
+ #1573)
+ - cupsDoFileRequest() and cupsDoRequest() now work
+ properly with non-blocking HTTP connections.
+ - Added Swedish translation (STR #1569)
+ - "make install" now installs the MIME files with world
+ read permissions (STR #1565)
+ - More CDSA encryption support fixes (STR #1563)
+ - Updated the default mime.types file to support printing
+ of files that do not have a locally-recognized MIME
+ media type to raw or System V queues.
+ - Updated the serial port detection code on Linux (STR
+ #1562)
+ - Added some more error checking to httpGetHostname()
+ (STR #1561)
+ - The title of some administration pages was not
+ localized (STR #1548)
+ - The edit-config.tmpl file was not generated or
+ installed for the Spanish or Japanese localizations
+ (STR #1547)
+ - The mimeDelete() function freed the types before the
+ filters, but the filters needed the type data (STR #1558)
+ - The scheduler didn't keep track of the status pipes
+ properly, leading to a bad select() for multi-file jobs
+ (STR #1559)
+ - The cupstestdsc program didn't validate the ordinal
+ page number value for %%Page: comments.
+
+
+CHANGES IN CUPS V1.2rc2
- The scheduler was not always using the string pool,
causing random crashes.
@@ -99,7 +162,7 @@ CHANGES IN CUPS V1.2rc1
#1488)
- ppdOpen2() now converts the NickName and all UI text to
UTF-8 (STR #1475)
- - The Set Allows Users web page did not work (STR #1486)
+ - The Set Allowed Users web page did not work (STR #1486)
- When the default policy was not set or set to a non-
existing policy, the scheduler did not set the default
policy name to "default" (STR #1484)
diff --git a/CREDITS.txt b/CREDITS.txt
index fec1c02140..27722e2327 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -1,4 +1,4 @@
-CREDITS.txt - 2006-02-23
+CREDITS.txt - 2006-04-17
------------------------
Few projects are completed by one person, and CUPS is no exception. We'd
@@ -24,10 +24,10 @@ like to thank the following individuals for their contributions:
Jeff Licquia - Bug fixes, beta testing, evangelism.
Jason McMullan - Original CUPS RPM distributions.
Wes Morgan - *BSD fixes.
- Ulrich Oldendorf - German locale.
+ Daniel Nylander - Swedish localization.
Giulio Orsero - Bug fixes and testing.
+ Michal Osowiecki - Polish localization.
Kurt Pfeifle - Bug fixes, beta testing, evangelism.
- Gilles QUERRET - French man pages.
Petter Reinholdtsen - HP-UX compiler stuff.
Juan Pablo González Riopedre - Spanish localization
Stuart Stevens - HP JetDirect IPP information.
diff --git a/backend/Dependencies b/backend/Dependencies
index 42ce66029a..aed4364253 100644
--- a/backend/Dependencies
+++ b/backend/Dependencies
@@ -19,6 +19,11 @@ scsi.o: ../cups/language.h ../cups/string.h ../config.h
serial.o: ../cups/backend.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
serial.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h
serial.o: ../cups/language.h ../cups/string.h ../config.h
+snmp.o: ../cups/backend.h ../cups/http-private.h ../config.h ../cups/http.h
+snmp.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h
+snmp.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
+snmp.o: ../cups/string.h ../cups/array.h ../cups/file.h ieee1284.c
+snmp.o: ../cups/debug.h
socket.o: ../cups/backend.h ../cups/http-private.h ../config.h ../cups/http.h
socket.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h
socket.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
diff --git a/backend/Makefile b/backend/Makefile
index 4267f21e50..807a78efd4 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $"
+# "$Id: Makefile 5429 2006-04-18 21:18:51Z mike $"
#
# Backend makefile for the Common UNIX Printing System (CUPS).
#
@@ -27,10 +27,10 @@
include ../Makedefs
RBACKENDS = ipp lpd
-UBACKENDS = parallel scsi serial socket usb
+UBACKENDS = parallel scsi serial snmp socket usb
TARGETS = betest test1284 $(RBACKENDS) $(UBACKENDS)
OBJS = betest.o ipp.o lpd.o parallel.o scsi.o \
- serial.o socket.o test1284.o usb.o
+ serial.o snmp.o socket.o test1284.o usb.o
#
@@ -165,6 +165,15 @@ serial: serial.o ../cups/$(LIBCUPS)
$(CC) $(LDFLAGS) -o serial serial.o $(BACKLIBS) $(LIBS)
+#
+# snmp
+#
+
+snmp: snmp.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o snmp snmp.o $(LIBS)
+
+
#
# socket
#
@@ -192,5 +201,5 @@ include Dependencies
#
-# End of "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $".
+# End of "$Id: Makefile 5429 2006-04-18 21:18:51Z mike $".
#
diff --git a/backend/ieee1284.c b/backend/ieee1284.c
index 52f27db18d..a6f8b26495 100644
--- a/backend/ieee1284.c
+++ b/backend/ieee1284.c
@@ -1,5 +1,5 @@
/*
- * "$Id: ieee1284.c 5198 2006-02-27 21:58:43Z mike $"
+ * "$Id: ieee1284.c 5440 2006-04-19 21:36:43Z mike $"
*
* IEEE-1284 support functions for the Common UNIX Printing System (CUPS).
*
@@ -25,8 +25,9 @@
*
* Contents:
*
- * get_device_id() - Get the IEEE-1284 device ID string and corresponding
- * URI.
+ * get_device_id() - Get the IEEE-1284 device ID string and corresponding
+ * URI.
+ * get_make_model() - Get the make and model string from the device ID.
*/
/*
@@ -34,21 +35,14 @@
*/
#include
-#ifdef __linux
-# include
-# include
-# define IOCNR_GET_DEVICE_ID 1
-# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
-#endif /* __linux */
-#ifdef __sun
-# ifdef __sparc
-# include
-# else
-# include
-# include
-# endif /* __sparc */
-#endif /* __sun */
+
+/*
+ * Prototypes...
+ */
+
+static int get_make_model(const char *device_id, char *make_model,
+ int make_model_size);
/*
@@ -56,6 +50,24 @@
* corresponding URI.
*/
+#ifndef SNMP_BACKEND
+# ifdef __linux
+# include
+# include
+# define IOCNR_GET_DEVICE_ID 1
+# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
+# endif /* __linux */
+
+# ifdef __sun
+# ifdef __sparc
+# include
+# else
+# include
+# include
+# endif /* __sparc */
+# endif /* __sun */
+
+
int /* O - 0 on success, -1 on failure */
get_device_id(
int fd, /* I - File descriptor */
@@ -70,9 +82,9 @@ get_device_id(
char *attr, /* 1284 attribute */
*delim, /* 1284 delimiter */
*uriptr, /* Pointer into URI */
- *mfg, /* Manufacturer string */
- *mdl, /* Model string */
+ manufacturer[256], /* Manufacturer string */
serial_number[1024]; /* Serial number string */
+ int manulen; /* Length of manufacturer string */
#ifdef __linux
int length; /* Length of device ID info */
#endif /* __linux */
@@ -80,6 +92,7 @@ get_device_id(
struct ecpp_device_id did; /* Device ID buffer */
#endif /* __sun && ECPPIOC_GETDEVID */
+
DEBUG_printf(("get_device_id(fd=%d, device_id=%p, device_id_size=%d, "
"make_model=%p, make_model_size=%d, scheme=\"%s\", "
"uri=%p, uri_size=%d)\n", fd, device_id, device_id_size,
@@ -174,6 +187,157 @@ get_device_id(
if (!*device_id)
return (-1);
+ /*
+ * Get the make and model...
+ */
+
+ get_make_model(device_id, make_model, make_model_size);
+
+ /*
+ * Then generate a device URI...
+ */
+
+ if (scheme && uri && uri_size > 32)
+ {
+ /*
+ * Look for the serial number field...
+ */
+
+ if ((attr = strstr(device_id, "SERN:")) != NULL)
+ attr += 5;
+ else if ((attr = strstr(device_id, "SERIALNUMBER:")) != NULL)
+ attr += 13;
+ else if ((attr = strstr(device_id, ";SN:")) != NULL)
+ attr += 4;
+
+ if (attr)
+ {
+ strlcpy(serial_number, attr, sizeof(serial_number));
+
+ if ((delim = strchr(serial_number, ';')) != NULL)
+ *delim = '\0';
+ }
+ else
+ serial_number[0] = '\0';
+
+ /*
+ * Generate the device URI from the manufacturer, make_model, and
+ * serial number strings.
+ */
+
+ snprintf(uri, uri_size, "%s://", scheme);
+
+ if ((attr = strstr(device_id, "MANUFACTURER:")) != NULL)
+ attr += 13;
+ else if ((attr = strstr(device_id, "Manufacturer:")) != NULL)
+ attr += 13;
+ else if ((attr = strstr(device_id, "MFG:")) != NULL)
+ attr += 4;
+
+ if (attr)
+ {
+ strlcpy(manufacturer, attr, sizeof(manufacturer));
+
+ if ((delim = strchr(manufacturer, ';')) != NULL)
+ *delim = '\0';
+
+ if (!strcasecmp(manufacturer, "Hewlett-Packard"))
+ strcpy(manufacturer, "HP");
+ }
+ else
+ {
+ strlcpy(manufacturer, make_model, sizeof(manufacturer));
+
+ if ((delim = strchr(manufacturer, ' ')) != NULL)
+ *delim = '\0';
+ }
+
+ manulen = strlen(manufacturer);
+
+ for (uriptr = uri + strlen(uri), delim = manufacturer;
+ *delim && uriptr < (uri + uri_size - 3);
+ delim ++)
+ if (*delim == ' ')
+ {
+ *uriptr++ = '%';
+ *uriptr++ = '2';
+ *uriptr++ = '0';
+ }
+ else
+ *uriptr++ = *delim;
+
+ *uriptr++ = '/';
+
+ if (!strncasecmp(make_model, manufacturer, manulen))
+ {
+ delim = make_model + manulen;
+
+ while (isspace(*delim & 255))
+ delim ++;
+ }
+ else
+ delim = make_model;
+
+ for (; *delim && uriptr < (uri + uri_size - 3); delim ++)
+ if (*delim == ' ')
+ {
+ *uriptr++ = '%';
+ *uriptr++ = '2';
+ *uriptr++ = '0';
+ }
+ else
+ *uriptr++ = *delim;
+
+ if (serial_number[0])
+ {
+ /*
+ * Add the serial number to the URI...
+ */
+
+ strlcpy(uriptr, "?serial=", uri_size - (uriptr - uri));
+ strlcat(uriptr, serial_number, uri_size - (uriptr - uri));
+ }
+ else
+ *uriptr = '\0';
+ }
+
+ return (0);
+}
+#endif /* !SNMP_BACKEND */
+
+
+/*
+ * 'get_make_model()' - Get the make and model string from the device ID.
+ */
+
+int /* O - 0 on success, -1 on failure */
+get_make_model(
+ const char *device_id, /* O - 1284 device ID */
+ char *make_model, /* O - Make/model */
+ int make_model_size) /* I - Size of buffer */
+{
+ char *attr, /* 1284 attribute */
+ *delim, /* 1284 delimiter */
+ *mfg, /* Manufacturer string */
+ *mdl; /* Model string */
+
+
+ DEBUG_printf(("get_make_model(device_id=\"%s\", "
+ "make_model=%p, make_model_size=%d)\n", device_id,
+ make_model, make_model_size));
+
+ /*
+ * Range check input...
+ */
+
+ if (!device_id || !*device_id || !make_model || make_model_size < 32)
+ {
+ DEBUG_puts("get_make_model: Bad args!");
+ return (-1);
+ }
+
+ *make_model = '\0';
+
/*
* Look for the description field...
*/
@@ -224,69 +388,84 @@ get_device_id(
if ((mfg = strstr(device_id, "MANUFACTURER:")) != NULL)
mfg += 13;
+ else if ((mfg = strstr(device_id, "Manufacturer:")) != NULL)
+ mfg += 13;
else if ((mfg = strstr(device_id, "MFG:")) != NULL)
mfg += 4;
if ((mdl = strstr(device_id, "MODEL:")) != NULL)
mdl += 6;
+ else if ((mdl = strstr(device_id, "Model:")) != NULL)
+ mdl += 6;
else if ((mdl = strstr(device_id, "MDL:")) != NULL)
mdl += 4;
- if (attr)
+ if (mdl)
{
/*
- * Use description...
+ * Build a make-model string from the manufacturer and model attributes...
*/
- if (!strncasecmp(attr, "Hewlett-Packard hp ", 19))
+ if (mfg)
{
- /*
- * Check for a common HP bug...
- */
+ if (!strncasecmp(mfg, "Hewlett-Packard", 15))
+ strlcpy(make_model, "HP", make_model_size);
+ else
+ strlcpy(make_model, mfg, make_model_size);
- strlcpy(make_model, "HP ", make_model_size);
- strlcpy(make_model + 3, attr + 19, make_model_size - 3);
- }
- else if (!strncasecmp(attr, "Hewlett-Packard ", 16))
- {
- strlcpy(make_model, "HP ", make_model_size);
- strlcpy(make_model + 3, attr + 16, make_model_size - 3);
+ if ((delim = strchr(make_model, ';')) != NULL)
+ *delim = '\0';
+
+ if (!strncasecmp(make_model, mdl, strlen(make_model)))
+ {
+ /*
+ * Just copy model string, since it has the manufacturer...
+ */
+
+ strlcpy(make_model, mdl, make_model_size);
+ }
+ else
+ {
+ /*
+ * Concatenate the make and model...
+ */
+
+ strlcat(make_model, " ", make_model_size);
+ strlcat(make_model, mdl, make_model_size);
+ }
}
else
{
- strlcpy(make_model, attr, make_model_size);
+ /*
+ * Just copy model string, since it has the manufacturer...
+ */
+
+ strlcpy(make_model, mdl, make_model_size);
}
}
- else if (mfg && mdl)
+ else if (attr)
{
/*
- * Build a make-model string from the manufacturer and model attributes...
+ * Use description...
*/
- if (!strncasecmp(mfg, "Hewlett-Packard", 15))
- strlcpy(make_model, "HP", make_model_size);
- else
- strlcpy(make_model, mfg, make_model_size);
-
- if ((delim = strchr(make_model, ';')) != NULL)
- *delim = '\0';
-
- if (!strncasecmp(make_model, mdl, strlen(make_model)))
+ if (!strncasecmp(attr, "Hewlett-Packard hp ", 19))
{
/*
- * Just copy model string, since it has the manufacturer...
+ * Check for a common HP bug...
*/
- strlcpy(make_model, mdl, make_model_size);
+ strlcpy(make_model, "HP ", make_model_size);
+ strlcpy(make_model + 3, attr + 19, make_model_size - 3);
+ }
+ else if (!strncasecmp(attr, "Hewlett-Packard ", 16))
+ {
+ strlcpy(make_model, "HP ", make_model_size);
+ strlcpy(make_model + 3, attr + 16, make_model_size - 3);
}
else
{
- /*
- * Concatenate the make and model...
- */
-
- strlcat(make_model, " ", make_model_size);
- strlcat(make_model, mdl, make_model_size);
+ strlcpy(make_model, attr, make_model_size);
}
}
else
@@ -298,76 +477,34 @@ get_device_id(
strlcpy(make_model, "Unknown", make_model_size);
}
+ /*
+ * Strip trailing data...
+ */
+
if ((delim = strchr(make_model, ';')) != NULL)
*delim = '\0';
- if (scheme && uri && uri_size > 32)
- {
- /*
- * Look for the serial number field...
- */
-
- if ((attr = strstr(device_id, "SERN:")) != NULL)
- attr += 5;
- else if ((attr = strstr(device_id, "SERIALNUMBER:")) != NULL)
- attr += 13;
- else if ((attr = strstr(device_id, ";SN:")) != NULL)
- attr += 4;
-
- if (attr)
- {
- strlcpy(serial_number, attr, sizeof(serial_number));
+ /*
+ * Strip trailing whitespace...
+ */
- if ((delim = strchr(serial_number, ';')) != NULL)
- *delim = '\0';
- }
+ for (delim = make_model + strlen(make_model) - 1; delim >= make_model; delim --)
+ if (isspace(*delim & 255))
+ *delim = '\0';
else
- serial_number[0] = '\0';
-
- /*
- * Generate the device URI from the make_model and serial number strings.
- */
+ break;
- snprintf(uri, uri_size, "%s://", scheme);
- for (uriptr = uri + strlen(uri), delim = make_model;
- *delim && uriptr < (uri + uri_size - 1);
- delim ++)
- if (*delim == ' ')
- {
- delim ++;
- *uriptr++ = '/';
- break;
- }
- else
- *uriptr++ = *delim;
-
- for (; *delim && uriptr < (uri + uri_size - 3); delim ++)
- if (*delim == ' ')
- {
- *uriptr++ = '%';
- *uriptr++ = '2';
- *uriptr++ = '0';
- }
- else
- *uriptr++ = *delim;
-
- *uriptr = '\0';
-
- if (serial_number[0])
- {
- /*
- * Add the serial number to the URI...
- */
-
- strlcat(uri, "?serial=", uri_size);
- strlcat(uri, serial_number, uri_size);
- }
- }
+ /*
+ * Return...
+ */
- return (0);
+ if (make_model[0])
+ return (0);
+ else
+ return (-1);
}
/*
- * End of "$Id: ieee1284.c 5198 2006-02-27 21:58:43Z mike $".
+ * End of "$Id: ieee1284.c 5440 2006-04-19 21:36:43Z mike $".
*/
diff --git a/backend/parallel.c b/backend/parallel.c
index 6acb8134fd..d846c82a35 100644
--- a/backend/parallel.c
+++ b/backend/parallel.c
@@ -1,5 +1,5 @@
/*
- * "$Id: parallel.c 5241 2006-03-07 22:07:44Z mike $"
+ * "$Id: parallel.c 5387 2006-04-10 02:51:12Z mike $"
*
* Parallel port backend for the Common UNIX Printing System (CUPS).
*
@@ -466,8 +466,6 @@ list_devices(void)
strcpy(basedevice, "/dev/parallel/");
else if (!access("/dev/printers/", 0))
strcpy(basedevice, "/dev/printers/");
- else if (!access("/dev/par0", 0))
- strcpy(basedevice, "/dev/par");
else
strcpy(basedevice, "/dev/lp");
@@ -737,5 +735,5 @@ list_devices(void)
/*
- * End of "$Id: parallel.c 5241 2006-03-07 22:07:44Z mike $".
+ * End of "$Id: parallel.c 5387 2006-04-10 02:51:12Z mike $".
*/
diff --git a/backend/serial.c b/backend/serial.c
index 17de8d8d31..86093682cf 100644
--- a/backend/serial.c
+++ b/backend/serial.c
@@ -1,5 +1,5 @@
/*
- * "$Id: serial.c 5241 2006-03-07 22:07:44Z mike $"
+ * "$Id: serial.c 5400 2006-04-14 19:04:02Z mike $"
*
* Serial port backend for the Common UNIX Printing System (CUPS).
*
@@ -87,6 +87,11 @@
# include
#endif /* __APPLE__ */
+#if defined(__linux) && defined(TIOCGSERIAL)
+# include
+# include
+#endif /* __linux && TIOCGSERIAL */
+
/*
* Local functions...
@@ -663,21 +668,48 @@ list_devices(void)
{
#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
- /* Funky hex numbering used for some devices */
+ /* Funky hex numbering used for some *
+ * devices */
#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ */
-#if defined(__linux) || defined(linux) || defined(__linux__)
- int i, j; /* Looping vars */
- int fd; /* File descriptor */
- char device[255]; /* Device filename */
+#ifdef __linux
+ int i, j; /* Looping vars */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+# ifdef TIOCGSERIAL
+ struct serial_struct serinfo; /* serial port info */
+# endif /* TIOCGSERIAL */
for (i = 0; i < 100; i ++)
{
sprintf(device, "/dev/ttyS%d", i);
+
if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
{
+# ifdef TIOCGSERIAL
+ /*
+ * See if this port exists...
+ */
+
+ serinfo.reserved_char[0] = 0;
+
+ if (!ioctl(fd, TIOCGSERIAL, &serinfo))
+ {
+ if (serinfo.type == PORT_UNKNOWN)
+ {
+ /*
+ * Nope...
+ */
+
+ close(fd);
+ continue;
+ }
+ }
+# endif /* TIOCGSERIAL */
+
close(fd);
+
# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc)
printf("serial serial:%s?baud=230400 \"Unknown\" \"Serial Port #%d\"\n",
device, i + 1);
@@ -824,13 +856,13 @@ list_devices(void)
{
sprintf(device, "/dev/cua/%c", 'a' + i);
if (access(device, 0) == 0)
-#ifdef B115200
+# ifdef B115200
printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
device, i + 1);
-#else
+# else
printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
device, i + 1);
-#endif /* B115200 */
+# endif /* B115200 */
}
/*
@@ -1063,7 +1095,6 @@ list_devices(void)
CFMutableDictionaryRef classesToMatch;
io_object_t serialService;
- printf("serial serial \"Unknown\" \"Serial Printer (serial)\"\n");
kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
if (KERN_SUCCESS != kernResult)
@@ -1117,8 +1148,8 @@ list_devices(void)
CFRelease(bsdPathAsCFString);
if (result)
- printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", bsdPath,
- serialName);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n",
+ bsdPath, serialName);
}
}
}
@@ -1126,7 +1157,11 @@ list_devices(void)
IOObjectRelease(serialService);
}
- IOObjectRelease(serialPortIterator); /* Release the iterator. */
+ /*
+ * Release the iterator.
+ */
+
+ IOObjectRelease(serialPortIterator);
}
}
#endif
@@ -1134,5 +1169,5 @@ list_devices(void)
/*
- * End of "$Id: serial.c 5241 2006-03-07 22:07:44Z mike $".
+ * End of "$Id: serial.c 5400 2006-04-14 19:04:02Z mike $".
*/
diff --git a/backend/snmp.c b/backend/snmp.c
new file mode 100644
index 0000000000..d571bf1059
--- /dev/null
+++ b/backend/snmp.c
@@ -0,0 +1,2206 @@
+/*
+ * "$Id: snmp.c 5453 2006-04-23 12:08:18Z mike $"
+ *
+ * SNMP discovery backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2006 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Discover printers via SNMP.
+ * add_array() - Add a string to an array.
+ * add_cache() - Add a cached device...
+ * alarm_handler() - Handle alarm signals...
+ * asn1_decode_snmp() - Decode a SNMP packet.
+ * asn1_debug() - Decode an ASN1-encoded message.
+ * asn1_encode_snmp() - Encode a SNMP packet.
+ * asn1_get_integer() - Get an integer value.
+ * asn1_get_length() - Get a value length.
+ * asn1_get_oid() - Get an OID value.
+ * asn1_get_packed() - Get a packed integer value.
+ * asn1_get_string() - Get a string value.
+ * asn1_get_type() - Get a value type.
+ * asn1_set_integer() - Set an integer value.
+ * asn1_set_length() - Set a value length.
+ * asn1_set_oid() - Set an OID value.
+ * asn1_set_packed() - Set a packed integer value.
+ * asn1_size_integer() - Figure out the number of bytes needed for an
+ * integer value.
+ * asn1_size_length() - Figure out the number of bytes needed for a
+ * length value.
+ * asn1_size_oid() - Figure out the numebr of bytes needed for an
+ * OID value.
+ * asn1_size_packed() - Figure out the number of bytes needed for a
+ * packed integer value.
+ * compare_cache() - Compare two cache entries.
+ * debug_printf() - Display some debugging information.
+ * fix_make_model() - Fix common problems in the make-and-model
+ * string.
+ * free_array() - Free an array of strings.
+ * free_cache() - Free the array of cached devices.
+ * get_interface_addresses() - Get the broadcast address(es) associated
+ * with an interface.
+ * hex_debug() - Output hex debugging data...
+ * list_devices() - List all of the devices we found...
+ * open_snmp_socket() - Open the SNMP broadcast socket.
+ * password_cb() - Handle authentication requests.
+ * probe_device() - Probe a device to discover whether it is a
+ * printer.
+ * read_snmp_conf() - Read the snmp.conf file.
+ * read_snmp_response() - Read and parse a SNMP response...
+ * run_time() - Return the total running time...
+ * scan_devices() - Scan for devices using SNMP.
+ * send_snmp_query() - Send an SNMP query packet.
+ * try_connect() - Try connecting on a port...
+ * update_cache() - Update a cached device...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define SNMP_BACKEND
+#include "ieee1284.c"
+
+
+/*
+ * This backend implements SNMP printer discovery. It uses a broadcast-
+ * based approach to get SNMP response packets from potential printers
+ * and then interrogates each responder by trying to connect on port
+ * 631, 9100, and 515.
+ *
+ * The current focus is on printers with internal network cards, although
+ * the code also works with many external print servers as well. Future
+ * versions will support scanning for vendor-specific SNMP OIDs and the
+ * new PWG Port Monitor MIB and not just the Host MIB OIDs.
+ *
+ * The backend reads the snmp.conf file from the CUPS_SERVERROOT directory
+ * which can contain comments, blank lines, or any number of the following
+ * directives:
+ *
+ * Address ip-address
+ * Address @LOCAL
+ * Address @IF(name)
+ * Community name
+ * DebugLevel N
+ * HostNameLookups on
+ * HostNameLookups off
+ *
+ * The default is to use:
+ *
+ * Address @LOCAL
+ * Community public
+ * DebugLevel 0
+ * HostNameLookups off
+ *
+ * This backend is known to work with the following network printers and
+ * print servers:
+ *
+ * Axis OfficeBasic, 5400, 5600
+ * EPSON
+ * Genicom
+ * HP JetDirect
+ * Lexmark
+ * Sharp
+ * Tektronix
+ * Xerox
+ *
+ * It does not currently work with:
+ *
+ * DLink
+ * Linksys
+ * Netgear
+ * Okidata
+ *
+ * (for all of these, they do not support the Host MIB)
+ */
+
+/*
+ * Constants...
+ */
+
+#define SNMP_PORT 161 /* SNMP well-known port */
+#define SNMP_MAX_OID 64 /* Maximum number of OID numbers */
+#define SNMP_MAX_PACKET 1472 /* Maximum size of SNMP packet */
+#define SNMP_MAX_STRING 512 /* Maximum size of string */
+#define SNMP_VERSION_1 0 /* SNMPv1 */
+
+#define ASN1_END_OF_CONTENTS 0x00 /* End-of-contents */
+#define ASN1_BOOLEAN 0x01 /* BOOLEAN */
+#define ASN1_INTEGER 0x02 /* INTEGER or ENUMERATION */
+#define ASN1_BIT_STRING 0x03 /* BIT STRING */
+#define ASN1_OCTET_STRING 0x04 /* OCTET STRING */
+#define ASN1_NULL_VALUE 0x05 /* NULL VALUE */
+#define ASN1_OID 0x06 /* OBJECT IDENTIFIER */
+#define ASN1_SEQUENCE 0x30 /* SEQUENCE */
+#define ASN1_GET_REQUEST 0xa0 /* Get-Request-PDU */
+#define ASN1_GET_RESPONSE 0xa2 /* Get-Response-PDU */
+
+
+/*
+ * Types...
+ */
+
+typedef struct snmp_cache_s /**** SNMP scan cache ****/
+{
+ http_addr_t address; /* Address of device */
+ char *addrname, /* Name of device */
+ *uri, /* device-uri */
+ *id, /* device-id */
+ *make_and_model; /* device-make-and-model */
+} snmp_cache_t;
+
+typedef struct snmp_packet_s /**** SNMP packet ****/
+{
+ const char *error; /* Encode/decode error */
+ int version; /* Version number */
+ char community[SNMP_MAX_STRING];
+ /* Community name */
+ int request_type; /* Request type */
+ int request_id; /* request-id value */
+ int error_status; /* error-status value */
+ int error_index; /* error-index value */
+ int object_name[SNMP_MAX_OID];
+ /* object-name value */
+ int object_type; /* object-value type */
+ union
+ {
+ int boolean; /* Boolean value */
+ int integer; /* Integer value */
+ int oid[SNMP_MAX_OID]; /* OID value */
+ char string[SNMP_MAX_STRING];/* String value */
+ } object_value; /* object-value value */
+} snmp_packet_t;
+
+
+/*
+ * Local functions...
+ */
+
+static char *add_array(cups_array_t *a, const char *s);
+static void add_cache(http_addr_t *addr, const char *addrname,
+ const char *uri, const char *id,
+ const char *make_and_model);
+static void alarm_handler(int sig);
+static int asn1_decode_snmp(unsigned char *buffer, size_t len,
+ snmp_packet_t *packet);
+static void asn1_debug(unsigned char *buffer, size_t len,
+ int indent);
+static int asn1_encode_snmp(unsigned char *buffer, size_t len,
+ snmp_packet_t *packet);
+static int asn1_get_integer(unsigned char **buffer,
+ unsigned char *bufend,
+ int length);
+static int asn1_get_oid(unsigned char **buffer,
+ unsigned char *bufend,
+ int length, int *oid, int oidsize);
+static int asn1_get_packed(unsigned char **buffer,
+ unsigned char *bufend);
+static char *asn1_get_string(unsigned char **buffer,
+ unsigned char *bufend,
+ int length, char *string,
+ int strsize);
+static int asn1_get_length(unsigned char **buffer,
+ unsigned char *bufend);
+static int asn1_get_type(unsigned char **buffer,
+ unsigned char *bufend);
+static void asn1_set_integer(unsigned char **buffer,
+ int integer);
+static void asn1_set_length(unsigned char **buffer,
+ int length);
+static void asn1_set_oid(unsigned char **buffer,
+ const int *oid);
+static void asn1_set_packed(unsigned char **buffer,
+ int integer);
+static int asn1_size_integer(int integer);
+static int asn1_size_length(int length);
+static int asn1_size_oid(const int *oid);
+static int asn1_size_packed(int integer);
+static int compare_cache(snmp_cache_t *a, snmp_cache_t *b);
+static void debug_printf(const char *format, ...);
+static void fix_make_model(char *make_model,
+ const char *old_make_model,
+ int make_model_size);
+static void free_array(cups_array_t *a);
+static void free_cache(void);
+static http_addrlist_t *get_interface_addresses(const char *ifname);
+static void hex_debug(unsigned char *buffer, size_t len);
+static void list_devices(void);
+static int open_snmp_socket(void);
+static const char *password_cb(const char *prompt);
+static void probe_device(snmp_cache_t *device);
+static void read_snmp_conf(const char *address);
+static void read_snmp_response(int fd);
+static double run_time(void);
+static void scan_devices(int fd);
+static void send_snmp_query(int fd, http_addr_t *addr, int version,
+ const char *community,
+ const unsigned request_id,
+ const int *oid);
+static int try_connect(http_addr_t *addr, const char *addrname,
+ int port);
+static void update_cache(snmp_cache_t *device, const char *uri,
+ const char *id, const char *make_model);
+
+
+/*
+ * Local globals...
+ */
+
+static cups_array_t *Addresses = NULL;
+static cups_array_t *Communities = NULL;
+static cups_array_t *Devices = NULL;
+static int DebugLevel = 0;
+static int DeviceTypeOID[] = { 1, 3, 6, 1, 2, 1, 25, 3,
+ 2, 1, 2, 1, 0 };
+static int DeviceDescOID[] = { 1, 3, 6, 1, 2, 1, 25, 3,
+ 2, 1, 3, 1, 0 };
+static unsigned DeviceTypeRequest;
+static unsigned DeviceDescRequest;
+static int HostNameLookups = 0;
+static struct timeval StartTime;
+
+
+/*
+ * 'main()' - Discover printers via SNMP.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int fd; /* SNMP socket */
+
+
+ /*
+ * Check command-line options...
+ */
+
+ if (argc > 2)
+ {
+ fputs("Usage: snmp [host-or-ip-address]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Set the password callback for IPP operations...
+ */
+
+ cupsSetPasswordCB(password_cb);
+
+ /*
+ * Open the SNMP socket...
+ */
+
+ if ((fd = open_snmp_socket()) < 0)
+ return (1);
+
+ /*
+ * Read the configuration file and any cache data...
+ */
+
+ read_snmp_conf(argv[1]);
+
+ Devices = cupsArrayNew((cups_array_func_t)compare_cache, NULL);
+
+ /*
+ * Scan for devices...
+ */
+
+ scan_devices(fd);
+
+ /*
+ * Display the results...
+ */
+
+ list_devices();
+
+ /*
+ * Close, free, and return with no errors...
+ */
+
+ close(fd);
+
+ free_array(Addresses);
+ free_array(Communities);
+ free_cache();
+
+ return (0);
+}
+
+
+/*
+ * 'add_array()' - Add a string to an array.
+ */
+
+static char * /* O - New string */
+add_array(cups_array_t *a, /* I - Array */
+ const char *s) /* I - String to add */
+{
+ char *dups; /* New string */
+
+
+ dups = strdup(s);
+
+ cupsArrayAdd(a, dups);
+
+ return (dups);
+}
+
+
+/*
+ * 'add_cache()' - Add a cached device...
+ */
+
+static void
+add_cache(http_addr_t *addr, /* I - Device IP address */
+ const char *addrname, /* I - IP address or name string */
+ const char *uri, /* I - Device URI */
+ const char *id, /* I - 1284 device ID */
+ const char *make_and_model) /* I - Make and model */
+{
+ snmp_cache_t *temp; /* New device entry */
+
+
+ debug_printf("DEBUG: add_cache(addr=%p, addrname=\"%s\", uri=\"%s\", "
+ "id=\"%s\", make_and_model=\"%s\")\n",
+ addr, addrname, uri, id ? id : "(null)",
+ make_and_model ? make_and_model : "(null)");
+
+ temp = calloc(1, sizeof(snmp_cache_t));
+ memcpy(&(temp->address), addr, sizeof(temp->address));
+
+ temp->addrname = strdup(addrname);
+
+ if (uri)
+ temp->uri = strdup(uri);
+
+ if (id)
+ temp->id = strdup(id);
+
+ if (make_and_model)
+ temp->make_and_model = strdup(make_and_model);
+
+ cupsArrayAdd(Devices, temp);
+}
+
+
+/*
+ * 'alarm_handler()' - Handle alarm signals...
+ */
+
+static void
+alarm_handler(int sig) /* I - Signal number */
+{
+ /*
+ * Do nothing...
+ */
+
+ (void)sig;
+
+ if (DebugLevel)
+ write(2, "DEBUG: ALARM!\n", 14);
+}
+
+
+/*
+ * 'asn1_decode_snmp()' - Decode a SNMP packet.
+ */
+
+static int /* O - 0 on success, -1 on error */
+asn1_decode_snmp(unsigned char *buffer, /* I - Buffer */
+ size_t len, /* I - Size of buffer */
+ snmp_packet_t *packet) /* I - SNMP packet */
+{
+ unsigned char *bufptr, /* Pointer into the data */
+ *bufend; /* End of data */
+ int length; /* Length of value */
+
+
+ /*
+ * Initialize the decoding...
+ */
+
+ memset(packet, 0, sizeof(snmp_packet_t));
+
+ bufptr = buffer;
+ bufend = buffer + len;
+
+ if (asn1_get_type(&bufptr, bufend) != ASN1_SEQUENCE)
+ packet->error = "Packet does not start with SEQUENCE";
+ else if (asn1_get_length(&bufptr, bufend) == 0)
+ packet->error = "SEQUENCE uses indefinite length";
+ else if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
+ packet->error = "No version number";
+ else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
+ packet->error = "Version uses indefinite length";
+ else if ((packet->version = asn1_get_integer(&bufptr, bufend, length))
+ != SNMP_VERSION_1)
+ packet->error = "Bad SNMP version number";
+ else if (asn1_get_type(&bufptr, bufend) != ASN1_OCTET_STRING)
+ packet->error = "No community name";
+ else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
+ packet->error = "Community name uses indefinite length";
+ else
+ {
+ asn1_get_string(&bufptr, bufend, length, packet->community,
+ sizeof(packet->community));
+
+ if ((packet->request_type = asn1_get_type(&bufptr, bufend))
+ != ASN1_GET_RESPONSE)
+ packet->error = "Packet does not contain a Get-Response-PDU";
+ else if (asn1_get_length(&bufptr, bufend) == 0)
+ packet->error = "Get-Response-PDU uses indefinite length";
+ else if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
+ packet->error = "No request-id";
+ else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
+ packet->error = "request-id uses indefinite length";
+ else
+ {
+ packet->request_id = asn1_get_integer(&bufptr, bufend, length);
+
+ if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
+ packet->error = "No error-status";
+ else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
+ packet->error = "error-status uses indefinite length";
+ else
+ {
+ packet->error_status = asn1_get_integer(&bufptr, bufend, length);
+
+ if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
+ packet->error = "No error-index";
+ else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
+ packet->error = "error-index uses indefinite length";
+ else
+ {
+ packet->error_index = asn1_get_integer(&bufptr, bufend, length);
+
+ if (asn1_get_type(&bufptr, bufend) != ASN1_SEQUENCE)
+ packet->error = "No variable-bindings SEQUENCE";
+ else if (asn1_get_length(&bufptr, bufend) == 0)
+ packet->error = "variable-bindings uses indefinite length";
+ else if (asn1_get_type(&bufptr, bufend) != ASN1_SEQUENCE)
+ packet->error = "No VarBind SEQUENCE";
+ else if (asn1_get_length(&bufptr, bufend) == 0)
+ packet->error = "VarBind uses indefinite length";
+ else if (asn1_get_type(&bufptr, bufend) != ASN1_OID)
+ packet->error = "No name OID";
+ else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
+ packet->error = "Name OID uses indefinite length";
+ else
+ {
+ asn1_get_oid(&bufptr, bufend, length, packet->object_name,
+ SNMP_MAX_OID);
+
+ packet->object_type = asn1_get_type(&bufptr, bufend);
+
+ if ((length = asn1_get_length(&bufptr, bufend)) == 0 &&
+ packet->object_type != ASN1_NULL_VALUE &&
+ packet->object_type != ASN1_OCTET_STRING)
+ packet->error = "Value uses indefinite length";
+ else
+ {
+ switch (packet->object_type)
+ {
+ case ASN1_BOOLEAN :
+ packet->object_value.boolean =
+ asn1_get_integer(&bufptr, bufend, length);
+ break;
+
+ case ASN1_INTEGER :
+ packet->object_value.integer =
+ asn1_get_integer(&bufptr, bufend, length);
+ break;
+
+ case ASN1_NULL_VALUE :
+ break;
+
+ case ASN1_OCTET_STRING :
+ asn1_get_string(&bufptr, bufend, length,
+ packet->object_value.string,
+ SNMP_MAX_STRING);
+ break;
+
+ case ASN1_OID :
+ asn1_get_oid(&bufptr, bufend, length,
+ packet->object_value.oid, SNMP_MAX_OID);
+ break;
+
+ default :
+ packet->error = "Unsupported value type";
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return (packet->error ? -1 : 0);
+}
+
+
+/*
+ * 'asn1_debug()' - Decode an ASN1-encoded message.
+ */
+
+static void
+asn1_debug(unsigned char *buffer, /* I - Buffer */
+ size_t len, /* I - Length of buffer */
+ int indent) /* I - Indentation */
+{
+ int i; /* Looping var */
+ unsigned char *bufend; /* End of buffer */
+ int integer; /* Number value */
+ int oid[SNMP_MAX_OID]; /* OID value */
+ char string[SNMP_MAX_STRING];/* String value */
+ unsigned char value_type; /* Type of value */
+ int value_length; /* Length of value */
+
+
+ bufend = buffer + len;
+
+ while (buffer < bufend)
+ {
+ /*
+ * Get value type...
+ */
+
+ value_type = asn1_get_type(&buffer, bufend);
+ value_length = asn1_get_length(&buffer, bufend);
+
+ switch (value_type)
+ {
+ case ASN1_BOOLEAN :
+ integer = asn1_get_integer(&buffer, bufend, value_length);
+
+ fprintf(stderr, "DEBUG: %*sBOOLEAN %d bytes %d\n", indent, "",
+ value_length, integer);
+ break;
+
+ case ASN1_INTEGER :
+ integer = asn1_get_integer(&buffer, bufend, value_length);
+
+ fprintf(stderr, "DEBUG: %*sINTEGER %d bytes %d\n", indent, "",
+ value_length, integer);
+ break;
+
+ case ASN1_OCTET_STRING :
+ fprintf(stderr, "DEBUG: %*sOCTET STRING %d bytes \"%s\"\n", indent, "",
+ value_length, asn1_get_string(&buffer, bufend,
+ value_length, string,
+ sizeof(string)));
+ break;
+
+ case ASN1_NULL_VALUE :
+ fprintf(stderr, "DEBUG: %*sNULL VALUE %d bytes\n", indent, "",
+ value_length);
+
+ buffer += value_length;
+ break;
+
+ case ASN1_OID :
+ asn1_get_oid(&buffer, bufend, value_length, oid, SNMP_MAX_OID);
+
+ fprintf(stderr, "DEBUG: %*sOID %d bytes ", indent, "",
+ value_length);
+ for (i = 0; oid[i]; i ++)
+ fprintf(stderr, ".%d", oid[i]);
+ putc('\n', stderr);
+ break;
+
+ case ASN1_SEQUENCE :
+ fprintf(stderr, "DEBUG: %*sSEQUENCE %d bytes\n", indent, "",
+ value_length);
+ asn1_debug(buffer, value_length, indent + 4);
+
+ buffer += value_length;
+ break;
+
+ case ASN1_GET_REQUEST :
+ fprintf(stderr, "DEBUG: %*sGet-Request-PDU %d bytes\n", indent, "",
+ value_length);
+ asn1_debug(buffer, value_length, indent + 4);
+
+ buffer += value_length;
+ break;
+
+ case ASN1_GET_RESPONSE :
+ fprintf(stderr, "DEBUG: %*sGet-Response-PDU %d bytes\n", indent, "",
+ value_length);
+ asn1_debug(buffer, value_length, indent + 4);
+
+ buffer += value_length;
+ break;
+
+ default :
+ fprintf(stderr, "DEBUG: %*sUNKNOWN(%x) %d bytes\n", indent, "",
+ value_type, value_length);
+
+ buffer += value_length;
+ break;
+ }
+ }
+}
+
+
+/*
+ * 'asn1_encode_snmp()' - Encode a SNMP packet.
+ */
+
+static int /* O - Length on success, -1 on error */
+asn1_encode_snmp(unsigned char *buffer, /* I - Buffer */
+ size_t bufsize, /* I - Size of buffer */
+ snmp_packet_t *packet) /* I - SNMP packet */
+{
+ unsigned char *bufptr; /* Pointer into buffer */
+ int total, /* Total length */
+ msglen, /* Length of entire message */
+ commlen, /* Length of community string */
+ reqlen, /* Length of request */
+ listlen, /* Length of variable list */
+ varlen, /* Length of variable */
+ namelen, /* Length of object name OID */
+ valuelen; /* Length of object value */
+
+
+ /*
+ * Get the lengths of the community string, OID, and message...
+ */
+
+ namelen = asn1_size_oid(packet->object_name);
+
+ switch (packet->object_type)
+ {
+ case ASN1_NULL_VALUE :
+ valuelen = 0;
+ break;
+
+ case ASN1_BOOLEAN :
+ valuelen = asn1_size_integer(packet->object_value.boolean);
+ break;
+
+ case ASN1_INTEGER :
+ valuelen = asn1_size_integer(packet->object_value.integer);
+ break;
+
+ case ASN1_OCTET_STRING :
+ valuelen = strlen(packet->object_value.string);
+ break;
+
+ case ASN1_OID :
+ valuelen = asn1_size_oid(packet->object_value.oid);
+ break;
+
+ default :
+ packet->error = "Unknown object type";
+ return (-1);
+ }
+
+ varlen = 1 + asn1_size_length(namelen) + namelen +
+ 1 + asn1_size_length(valuelen) + valuelen;
+ listlen = 1 + asn1_size_length(varlen) + varlen;
+ reqlen = 2 + asn1_size_integer(packet->request_id) +
+ 2 + asn1_size_integer(packet->error_status) +
+ 2 + asn1_size_integer(packet->error_index) +
+ 1 + asn1_size_length(listlen) + listlen;
+ commlen = strlen(packet->community);
+ msglen = 2 + asn1_size_integer(packet->version) +
+ 1 + asn1_size_length(commlen) + commlen +
+ 1 + asn1_size_length(reqlen) + reqlen;
+ total = 1 + asn1_size_length(msglen) + msglen;
+
+ if (total > bufsize)
+ {
+ packet->error = "Message too large for buffer";
+ return (-1);
+ }
+
+ /*
+ * Then format the message...
+ */
+
+ bufptr = buffer;
+
+ *bufptr++ = ASN1_SEQUENCE; /* SNMPv1 message header */
+ asn1_set_length(&bufptr, msglen);
+
+ asn1_set_integer(&bufptr, packet->version);
+ /* version */
+
+ *bufptr++ = ASN1_OCTET_STRING; /* community */
+ asn1_set_length(&bufptr, commlen);
+ memcpy(bufptr, packet->community, commlen);
+ bufptr += commlen;
+
+ *bufptr++ = packet->request_type; /* Get-Request-PDU */
+ asn1_set_length(&bufptr, reqlen);
+
+ asn1_set_integer(&bufptr, packet->request_id);
+
+ asn1_set_integer(&bufptr, packet->error_status);
+
+ asn1_set_integer(&bufptr, packet->error_index);
+
+ *bufptr++ = ASN1_SEQUENCE; /* variable-bindings */
+ asn1_set_length(&bufptr, listlen);
+
+ *bufptr++ = ASN1_SEQUENCE; /* variable */
+ asn1_set_length(&bufptr, varlen);
+
+ asn1_set_oid(&bufptr, packet->object_name);
+ /* ObjectName */
+
+ switch (packet->object_type)
+ {
+ case ASN1_NULL_VALUE :
+ *bufptr++ = ASN1_NULL_VALUE; /* ObjectValue */
+ *bufptr++ = 0; /* Length */
+ break;
+
+ case ASN1_BOOLEAN :
+ asn1_set_integer(&bufptr, packet->object_value.boolean);
+ break;
+
+ case ASN1_INTEGER :
+ asn1_set_integer(&bufptr, packet->object_value.integer);
+ break;
+
+ case ASN1_OCTET_STRING :
+ *bufptr++ = ASN1_OCTET_STRING;
+ asn1_set_length(&bufptr, valuelen);
+ memcpy(bufptr, packet->object_value.string, valuelen);
+ bufptr += valuelen;
+ break;
+
+ case ASN1_OID :
+ asn1_set_oid(&bufptr, packet->object_value.oid);
+ break;
+ }
+
+ return (bufptr - buffer);
+}
+
+
+/*
+ * 'asn1_get_integer()' - Get an integer value.
+ */
+
+static int /* O - Integer value */
+asn1_get_integer(
+ unsigned char **buffer, /* IO - Pointer in buffer */
+ unsigned char *bufend, /* I - End of buffer */
+ int length) /* I - Length of value */
+{
+ int value; /* Integer value */
+
+
+ for (value = 0;
+ length > 0 && *buffer < bufend;
+ length --, (*buffer) ++)
+ value = (value << 8) | **buffer;
+
+ return (value);
+}
+
+
+/*
+ * 'asn1_get_length()' - Get a value length.
+ */
+
+static int /* O - Length */
+asn1_get_length(unsigned char **buffer, /* IO - Pointer in buffer */
+ unsigned char *bufend) /* I - End of buffer */
+{
+ int length; /* Length */
+
+
+ length = **buffer;
+ (*buffer) ++;
+
+ if (length & 128)
+ length = asn1_get_integer(buffer, bufend, length & 127);
+
+ return (length);
+}
+
+
+/*
+ * 'asn1_get_oid()' - Get an OID value.
+ */
+
+static int /* O - Last OID number */
+asn1_get_oid(
+ unsigned char **buffer, /* IO - Pointer in buffer */
+ unsigned char *bufend, /* I - End of buffer */
+ int length, /* I - Length of value */
+ int *oid, /* I - OID buffer */
+ int oidsize) /* I - Size of OID buffer */
+{
+ unsigned char *valend; /* End of value */
+ int *oidend; /* End of OID buffer */
+ int number; /* OID number */
+
+
+ valend = *buffer + length;
+ oidend = oid + oidsize - 1;
+
+ if (valend > bufend)
+ valend = bufend;
+
+ number = asn1_get_packed(buffer, bufend);
+
+ if (number < 80)
+ {
+ *oid++ = number / 40;
+ number = number % 40;
+ *oid++ = number;
+ }
+ else
+ {
+ *oid++ = 2;
+ number -= 80;
+ *oid++ = number;
+ }
+
+ while (*buffer < valend)
+ {
+ number = asn1_get_packed(buffer, bufend);
+
+ if (oid < oidend)
+ *oid++ = number;
+ }
+
+ *oid = 0;
+
+ return (number);
+}
+
+
+/*
+ * 'asn1_get_packed()' - Get a packed integer value.
+ */
+
+static int /* O - Value */
+asn1_get_packed(
+ unsigned char **buffer, /* IO - Pointer in buffer */
+ unsigned char *bufend) /* I - End of buffer */
+{
+ int value; /* Value */
+
+
+ value = 0;
+
+ while ((**buffer & 128) && *buffer < bufend)
+ {
+ value = (value << 7) | (**buffer & 127);
+ (*buffer) ++;
+ }
+
+ if (*buffer < bufend)
+ {
+ value = (value << 7) | **buffer;
+ (*buffer) ++;
+ }
+
+ return (value);
+}
+
+
+/*
+ * 'asn1_get_string()' - Get a string value.
+ */
+
+static char * /* O - String */
+asn1_get_string(
+ unsigned char **buffer, /* IO - Pointer in buffer */
+ unsigned char *bufend, /* I - End of buffer */
+ int length, /* I - Value length */
+ char *string, /* I - String buffer */
+ int strsize) /* I - String buffer size */
+{
+ if (length < strsize)
+ {
+ memcpy(string, *buffer, length);
+ string[length] = '\0';
+ }
+ else
+ {
+ memcpy(string, buffer, strsize - 1);
+ string[strsize - 1] = '\0';
+ }
+
+ (*buffer) += length;
+
+ return (string);
+}
+
+
+/*
+ * 'asn1_get_type()' - Get a value type.
+ */
+
+static int /* O - Type */
+asn1_get_type(unsigned char **buffer, /* IO - Pointer in buffer */
+ unsigned char *bufend) /* I - End of buffer */
+{
+ int type; /* Type */
+
+
+ type = **buffer;
+ (*buffer) ++;
+
+ if ((type & 31) == 31)
+ type = asn1_get_packed(buffer, bufend);
+
+ return (type);
+}
+
+
+/*
+ * 'asn1_set_integer()' - Set an integer value.
+ */
+
+static void
+asn1_set_integer(unsigned char **buffer,/* IO - Pointer in buffer */
+ int integer) /* I - Integer value */
+{
+ **buffer = ASN1_INTEGER;
+ (*buffer) ++;
+
+ if (integer > 0x7fffff || integer < -0x800000)
+ {
+ **buffer = 4;
+ (*buffer) ++;
+ **buffer = integer >> 24;
+ (*buffer) ++;
+ **buffer = integer >> 16;
+ (*buffer) ++;
+ **buffer = integer >> 8;
+ (*buffer) ++;
+ **buffer = integer;
+ (*buffer) ++;
+ }
+ else if (integer > 0x7fff || integer < -0x8000)
+ {
+ **buffer = 3;
+ (*buffer) ++;
+ **buffer = integer >> 16;
+ (*buffer) ++;
+ **buffer = integer >> 8;
+ (*buffer) ++;
+ **buffer = integer;
+ (*buffer) ++;
+ }
+ else if (integer > 0x7f || integer < -0x80)
+ {
+ **buffer = 2;
+ (*buffer) ++;
+ **buffer = integer >> 8;
+ (*buffer) ++;
+ **buffer = integer;
+ (*buffer) ++;
+ }
+ else
+ {
+ **buffer = 1;
+ (*buffer) ++;
+ **buffer = integer;
+ (*buffer) ++;
+ }
+}
+
+
+/*
+ * 'asn1_set_length()' - Set a value length.
+ */
+
+static void
+asn1_set_length(unsigned char **buffer, /* IO - Pointer in buffer */
+ int length) /* I - Length value */
+{
+ if (length > 255)
+ {
+ **buffer = 0x82; /* 2-byte length */
+ (*buffer) ++;
+ **buffer = length >> 8;
+ (*buffer) ++;
+ **buffer = length;
+ (*buffer) ++;
+ }
+ else if (length > 127)
+ {
+ **buffer = 0x81; /* 1-byte length */
+ (*buffer) ++;
+ **buffer = length;
+ (*buffer) ++;
+ }
+ else
+ {
+ **buffer = length; /* Length */
+ (*buffer) ++;
+ }
+}
+
+
+/*
+ * 'asn1_set_oid()' - Set an OID value.
+ */
+
+static void
+asn1_set_oid(unsigned char **buffer, /* IO - Pointer in buffer */
+ const int *oid) /* I - OID value */
+{
+ **buffer = ASN1_OID;
+ (*buffer) ++;
+
+ asn1_set_length(buffer, asn1_size_oid(oid));
+
+ asn1_set_packed(buffer, oid[0] * 40 + oid[1]);
+
+ for (oid += 2; *oid; oid ++)
+ asn1_set_packed(buffer, *oid);
+}
+
+
+/*
+ * 'asn1_set_packed()' - Set a packed integer value.
+ */
+
+static void
+asn1_set_packed(unsigned char **buffer, /* IO - Pointer in buffer */
+ int integer) /* I - Integer value */
+{
+ if (integer > 0xfffffff)
+ {
+ **buffer = (integer >> 14) & 0x7f;
+ (*buffer) ++;
+ }
+
+ if (integer > 0x1fffff)
+ {
+ **buffer = (integer >> 21) & 0x7f;
+ (*buffer) ++;
+ }
+
+ if (integer > 0x3fff)
+ {
+ **buffer = (integer >> 14) & 0x7f;
+ (*buffer) ++;
+ }
+
+ if (integer > 0x7f)
+ {
+ **buffer = (integer >> 7) & 0x7f;
+ (*buffer) ++;
+ }
+
+ **buffer = integer & 0x7f;
+ (*buffer) ++;
+}
+
+/*
+ * 'asn1_size_integer()' - Figure out the number of bytes needed for an
+ * integer value.
+ */
+
+static int /* O - Size in bytes */
+asn1_size_integer(int integer) /* I - Integer value */
+{
+ if (integer > 0x7fffff || integer < -0x800000)
+ return (4);
+ else if (integer > 0x7fff || integer < -0x8000)
+ return (3);
+ else if (integer > 0x7f || integer < -0x80)
+ return (2);
+ else
+ return (1);
+}
+
+
+/*
+ * 'asn1_size_length()' - Figure out the number of bytes needed for a
+ * length value.
+ */
+
+static int /* O - Size in bytes */
+asn1_size_length(int length) /* I - Length value */
+{
+ if (length > 0xff)
+ return (3);
+ else if (length > 0x7f)
+ return (2);
+ else
+ return (1);
+}
+
+
+/*
+ * 'asn1_size_oid()' - Figure out the numebr of bytes needed for an
+ * OID value.
+ */
+
+static int /* O - Size in bytes */
+asn1_size_oid(const int *oid) /* I - OID value */
+{
+ int length; /* Length of value */
+
+
+ for (length = asn1_size_packed(oid[0] * 40 + oid[1]), oid += 2; *oid; oid ++)
+ length += asn1_size_packed(*oid);
+
+ return (length);
+}
+
+
+/*
+ * 'asn1_size_packed()' - Figure out the number of bytes needed for a
+ * packed integer value.
+ */
+
+static int /* O - Size in bytes */
+asn1_size_packed(int integer) /* I - Integer value */
+{
+ if (integer > 0xfffffff)
+ return (5);
+ else if (integer > 0x1fffff)
+ return (4);
+ else if (integer > 0x3fff)
+ return (3);
+ else if (integer > 0x7f)
+ return (2);
+ else
+ return (1);
+}
+
+
+/*
+ * 'compare_cache()' - Compare two cache entries.
+ */
+
+static int /* O - Result of comparison */
+compare_cache(snmp_cache_t *a, /* I - First cache entry */
+ snmp_cache_t *b) /* I - Second cache entry */
+{
+ return (a->address.ipv4.sin_addr.s_addr - b->address.ipv4.sin_addr.s_addr);
+}
+
+
+/*
+ * 'debug_printf()' - Display some debugging information.
+ */
+
+static void
+debug_printf(const char *format, /* I - Printf-style format string */
+ ...) /* I - Additional arguments as needed */
+{
+ va_list ap; /* Pointer to arguments */
+
+
+ if (!DebugLevel)
+ return;
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+
+/*
+ * 'fix_make_model()' - Fix common problems in the make-and-model string.
+ */
+
+static void
+fix_make_model(
+ char *make_model, /* I - New make-and-model string */
+ const char *old_make_model, /* I - Old make-and-model string */
+ int make_model_size) /* I - Size of new string buffer */
+{
+ const char *mmptr; /* Pointer into make-and-model string */
+
+
+ /*
+ * Fix some common problems with the make-and-model string so
+ * that printer driver detection works better...
+ */
+
+ if (!strncasecmp(old_make_model, "Hewlett-Packard", 15))
+ {
+ /*
+ * Strip leading Hewlett-Packard and hp prefixes and replace
+ * with a single HP manufacturer prefix...
+ */
+
+ mmptr = old_make_model + 15;
+
+ while (isspace(*mmptr & 255))
+ mmptr ++;
+
+ if (!strncasecmp(mmptr, "hp", 2))
+ {
+ mmptr += 2;
+
+ while (isspace(*mmptr & 255))
+ mmptr ++;
+ }
+
+ make_model[0] = 'H';
+ make_model[1] = 'P';
+ make_model[2] = ' ';
+ strlcpy(make_model + 3, mmptr, make_model_size - 3);
+ }
+ else if (!strncasecmp(old_make_model, "deskjet", 7))
+ snprintf(make_model, make_model_size, "HP DeskJet%s", old_make_model + 7);
+ else if (!strncasecmp(old_make_model, "stylus_pro_", 11))
+ snprintf(make_model, make_model_size, "EPSON Stylus Pro %s",
+ old_make_model + 11);
+ else
+ strlcpy(make_model, old_make_model, make_model_size);
+
+ if ((mmptr = strstr(make_model, ", Inc.,")) != NULL)
+ {
+ /*
+ * Strip inc. from name, e.g. "Tektronix, Inc., Phaser 560"
+ * becomes "Tektronix Phaser 560"...
+ */
+
+ _cups_strcpy((char *)mmptr, mmptr + 7);
+ }
+}
+
+
+/*
+ * 'free_array()' - Free an array of strings.
+ */
+
+static void
+free_array(cups_array_t *a) /* I - Array */
+{
+ char *s; /* Current string */
+
+
+ for (s = (char *)cupsArrayFirst(a); s; s = (char *)cupsArrayNext(a))
+ free(s);
+
+ cupsArrayDelete(a);
+}
+
+
+/*
+ * 'free_cache()' - Free the array of cached devices.
+ */
+
+static void
+free_cache(void)
+{
+ snmp_cache_t *cache; /* Cached device */
+
+
+ for (cache = (snmp_cache_t *)cupsArrayFirst(Devices);
+ cache;
+ cache = (snmp_cache_t *)cupsArrayNext(Devices))
+ {
+ free(cache->addrname);
+
+ if (cache->uri)
+ free(cache->uri);
+
+ if (cache->id)
+ free(cache->id);
+
+ if (cache->make_and_model)
+ free(cache->make_and_model);
+
+ free(cache);
+ }
+
+ cupsArrayDelete(Devices);
+ Devices = NULL;
+}
+
+
+/*
+ * 'get_interface_addresses()' - Get the broadcast address(es) associated
+ * with an interface.
+ */
+
+static http_addrlist_t * /* O - List of addresses */
+get_interface_addresses(
+ const char *ifname) /* I - Interface name */
+{
+ struct ifaddrs *addrs, /* Interface address list */
+ *addr; /* Current interface address */
+ http_addrlist_t *first, /* First address in list */
+ *last, /* Last address in list */
+ *current; /* Current address */
+
+
+ if (getifaddrs(&addrs) < 0)
+ return (NULL);
+
+ for (addr = addrs, first = NULL, last = NULL; addr; addr = addr->ifa_next)
+ if ((addr->ifa_flags & IFF_BROADCAST) && addr->ifa_broadaddr &&
+ addr->ifa_broadaddr->sa_family == AF_INET &&
+ (!ifname || !strcmp(ifname, addr->ifa_name)))
+ {
+ current = calloc(1, sizeof(http_addrlist_t));
+
+ memcpy(&(current->addr), addr->ifa_broadaddr,
+ sizeof(struct sockaddr_in));
+
+ if (!last)
+ first = current;
+ else
+ last->next = current;
+
+ last = current;
+ }
+
+ freeifaddrs(addrs);
+
+ return (first);
+}
+
+
+/*
+ * 'hex_debug()' - Output hex debugging data...
+ */
+
+static void
+hex_debug(unsigned char *buffer, /* I - Buffer */
+ size_t len) /* I - Number of bytes */
+{
+ int col; /* Current column */
+
+
+ fputs("DEBUG: Hex dump of packet:\n", stderr);
+
+ for (col = 0; len > 0; col ++, buffer ++, len --)
+ {
+ if ((col & 15) == 0)
+ fprintf(stderr, "DEBUG: %04X ", col);
+
+ fprintf(stderr, " %02X", *buffer);
+
+ if ((col & 15) == 15)
+ putc('\n', stderr);
+ }
+
+ if (col & 15)
+ putc('\n', stderr);
+}
+
+
+/*
+ * 'list_devices()' - List all of the devices we found...
+ */
+
+static void
+list_devices(void)
+{
+ snmp_cache_t *cache; /* Cached device */
+
+
+ for (cache = (snmp_cache_t *)cupsArrayFirst(Devices);
+ cache;
+ cache = (snmp_cache_t *)cupsArrayNext(Devices))
+ if (cache->uri)
+ printf("network %s \"%s\" \"%s\" \"%s\"\n",
+ cache->uri,
+ cache->make_and_model ? cache->make_and_model : "Unknown",
+ cache->addrname, cache->id ? cache->id : "");
+}
+
+
+/*
+ * 'open_snmp_socket()' - Open the SNMP broadcast socket.
+ */
+
+static int /* O - SNMP socket file descriptor */
+open_snmp_socket(void)
+{
+ int fd; /* SNMP socket file descriptor */
+ int val; /* Socket option value */
+
+
+ /*
+ * Create the SNMP socket...
+ */
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to create SNMP socket - %s\n",
+ strerror(errno));
+
+ return (-1);
+ }
+
+ /*
+ * Set the "broadcast" flag...
+ */
+
+ val = 1;
+
+ if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
+ {
+ fprintf(stderr, "ERROR: Unable to set broadcast mode - %s\n",
+ strerror(errno));
+
+ close(fd);
+
+ return (-1);
+ }
+
+ return (fd);
+}
+
+
+/*
+ * 'password_cb()' - Handle authentication requests.
+ *
+ * All we do right now is return NULL, indicating that no authentication
+ * is possible.
+ */
+
+static const char * /* O - Password (NULL) */
+password_cb(const char *prompt) /* I - Prompt message */
+{
+ (void)prompt; /* Anti-compiler-warning-code */
+
+ return (NULL);
+}
+
+
+/*
+ * 'probe_device()' - Probe a device to discover whether it is a printer.
+ *
+ * TODO: Try using the Port Monitor MIB to discover the correct protocol
+ * to use - first need a commercially-available printer that supports
+ * it, though...
+ */
+
+static void
+probe_device(snmp_cache_t *device) /* I - Device */
+{
+ int i, j; /* Looping vars */
+ http_t *http; /* HTTP connection for IPP */
+ char uri[1024]; /* Full device URI */
+
+
+ /*
+ * Try connecting via IPP first...
+ */
+
+ debug_printf("DEBUG: %.3f Probing %s...\n", run_time(), device->addrname);
+
+ if ((http = httpConnect(device->addrname, 631)) != NULL)
+ {
+ /*
+ * IPP is supported...
+ */
+
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *model, /* printer-make-and-model attribute */
+ *info, /* printer-info attribute */
+ *supported; /* printer-uri-supported attribute */
+ char make_model[256],/* Make and model string to use */
+ temp[256]; /* Temporary make/model string */
+ int num_uris; /* Number of good URIs */
+ static const char * const resources[] =
+ { /* Common resource paths for IPP */
+ "/ipp",
+ "/ipp/port2",
+ "/ipp/port3",
+ "/EPSON_IPP_Printer",
+ "/LPT1",
+ "/LPT2",
+ "/COM1",
+ "/"
+ };
+
+
+ debug_printf("DEBUG: %s supports IPP!\n", device->addrname);
+
+ /*
+ * Use non-blocking IO...
+ */
+
+ httpBlocking(http, 0);
+
+ /*
+ * Loop through a list of common resources that covers 99% of the
+ * IPP-capable printers on the market today...
+ */
+
+ for (i = 0, num_uris = 0;
+ i < (int)(sizeof(resources) / sizeof(resources[0]));
+ i ++)
+ {
+ /*
+ * Don't look past /ipp if we have found a working URI...
+ */
+
+ if (num_uris > 0 && strncmp(resources[i], "/ipp", 4))
+ break;
+
+ httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ device->addrname, 631, resources[i]);
+
+ debug_printf("DEBUG: Trying %s (num_uris=%d)\n", uri, num_uris);
+
+ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ response = cupsDoRequest(http, request, resources[i]);
+
+ debug_printf("DEBUG: %s %s (%s)\n", uri,
+ ippErrorString(cupsLastError()), cupsLastErrorString());
+
+ if (response && response->request.status.status_code == IPP_OK)
+ {
+ model = ippFindAttribute(response, "printer-make-and-model",
+ IPP_TAG_TEXT);
+ info = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT);
+ supported = ippFindAttribute(response, "printer-uri-supported",
+ IPP_TAG_URI);
+
+ if (!supported)
+ {
+ fprintf(stderr, "ERROR: Missing printer-uri-supported from %s!\n",
+ device->addrname);
+
+ httpClose(http);
+ return;
+ }
+
+ debug_printf("DEBUG: printer-info=\"%s\"\n",
+ info ? info->values[0].string.text : "(null)");
+ debug_printf("DEBUG: printer-make-and-model=\"%s\"\n",
+ model ? model->values[0].string.text : "(null)");
+
+ /*
+ * Don't advertise this port if the printer actually only supports
+ * a more generic version...
+ */
+
+ if (!strncmp(resources[i], "/ipp/", 5))
+ {
+ for (j = 0; j < supported->num_values; j ++)
+ if (strstr(supported->values[j].string.text, "/ipp/"))
+ break;
+
+ if (j >= supported->num_values)
+ {
+ ippDelete(response);
+ break;
+ }
+ }
+
+ /*
+ * Don't use the printer-info attribute if it does not contain the
+ * IEEE-1284 device ID data...
+ */
+
+ if (info &&
+ (!strchr(info->values[0].string.text, ':') ||
+ !strchr(info->values[0].string.text, ';')))
+ info = NULL;
+
+ /*
+ * If we don't have a printer-make-and-model string from the printer
+ * but do have the 1284 device ID string, generate a make-and-model
+ * string from the device ID info...
+ */
+
+ if (model)
+ strlcpy(temp, model->values[0].string.text, sizeof(temp));
+ else if (info)
+ get_make_model(info->values[0].string.text, temp, sizeof(temp));
+
+ fix_make_model(make_model, temp, sizeof(make_model));
+
+ /*
+ * Update the current device or add a new printer to the cache...
+ */
+
+ if (num_uris == 0)
+ update_cache(device, uri,
+ info ? info->values[0].string.text : NULL,
+ make_model[0] ? make_model : NULL);
+ else
+ add_cache(&(device->address), device->addrname, uri,
+ info ? info->values[0].string.text : NULL,
+ make_model[0] ? make_model : NULL);
+
+ num_uris ++;
+ }
+
+ ippDelete(response);
+
+ if (num_uris > 0 && cupsLastError() != IPP_OK)
+ break;
+ }
+
+ httpClose(http);
+
+ if (num_uris > 0)
+ return;
+ }
+
+ /*
+ * OK, now try the standard ports...
+ */
+
+ if (!try_connect(&(device->address), device->addrname, 9100))
+ {
+ debug_printf("DEBUG: %s supports AppSocket!\n", device->addrname);
+
+ snprintf(uri, sizeof(uri), "socket://%s", device->addrname);
+ update_cache(device, uri, NULL, NULL);
+ }
+ else if (!try_connect(&(device->address), device->addrname, 515))
+ {
+ debug_printf("DEBUG: %s supports LPD!\n", device->addrname);
+
+ snprintf(uri, sizeof(uri), "lpd://%s/", device->addrname);
+ update_cache(device, uri, NULL, NULL);
+ }
+}
+
+
+/*
+ * 'read_snmp_conf()' - Read the snmp.conf file.
+ */
+
+static void
+read_snmp_conf(const char *address) /* I - Single address to probe */
+{
+ cups_file_t *fp; /* File pointer */
+ char filename[1024], /* Filename */
+ line[1024], /* Line from file */
+ *value; /* Value on line */
+ int linenum; /* Line number */
+ const char *cups_serverroot; /* CUPS_SERVERROOT env var */
+ const char *debug; /* CUPS_DEBUG_LEVEL env var */
+
+
+ /*
+ * Initialize the global address and community lists...
+ */
+
+ Addresses = cupsArrayNew(NULL, NULL);
+ Communities = cupsArrayNew(NULL, NULL);
+
+ if (address)
+ add_array(Addresses, address);
+
+ if ((debug = getenv("CUPS_DEBUG_LEVEL")) != NULL)
+ DebugLevel = atoi(debug);
+
+ /*
+ * Find the snmp.conf file...
+ */
+
+ if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
+ cups_serverroot = CUPS_SERVERROOT;
+
+ snprintf(filename, sizeof(filename), "%s/snmp.conf", cups_serverroot);
+
+ if ((fp = cupsFileOpen(filename, "r")) != NULL)
+ {
+ /*
+ * Read the snmp.conf file...
+ */
+
+ linenum = 0;
+
+ while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+ {
+ if (!value)
+ fprintf(stderr, "ERROR: Missing value on line %d of %s!\n", linenum,
+ filename);
+ else if (!strcasecmp(line, "Address"))
+ {
+ if (!address)
+ add_array(Addresses, value);
+ }
+ else if (!strcasecmp(line, "Community"))
+ add_array(Communities, value);
+ else if (!strcasecmp(line, "DebugLevel"))
+ DebugLevel = atoi(value);
+ else if (!strcasecmp(line, "HostNameLookups"))
+ HostNameLookups = !strcasecmp(value, "on") ||
+ !strcasecmp(value, "yes") ||
+ !strcasecmp(value, "true") ||
+ !strcasecmp(value, "double");
+ else
+ fprintf(stderr, "ERROR: Unknown directive %s on line %d of %s!\n",
+ line, linenum, filename);
+ }
+
+ cupsFileClose(fp);
+ }
+
+ /*
+ * Use defaults if parameters are undefined...
+ */
+
+ if (cupsArrayCount(Addresses) == 0)
+ {
+ fputs("INFO: Using default SNMP Address @LOCAL\n", stderr);
+ add_array(Addresses, "@LOCAL");
+ }
+
+ if (cupsArrayCount(Communities) == 0)
+ {
+ fputs("INFO: Using default SNMP Community public\n", stderr);
+ add_array(Communities, "public");
+ }
+}
+
+
+/*
+ * 'read_snmp_response()' - Read and parse a SNMP response...
+ */
+
+static void
+read_snmp_response(int fd) /* I - SNMP socket file descriptor */
+{
+ unsigned char buffer[SNMP_MAX_PACKET];/* Data packet */
+ int bytes; /* Number of bytes received */
+ http_addr_t addr; /* Source address */
+ socklen_t addrlen; /* Source address length */
+ char addrname[256]; /* Source address name */
+ snmp_packet_t packet; /* Decoded packet */
+ snmp_cache_t key, /* Search key */
+ *device; /* Matching device */
+
+
+ /*
+ * Read the response data...
+ */
+
+ addrlen = sizeof(addr);
+
+ if ((bytes = recvfrom(fd, buffer, sizeof(buffer), 0, (void *)&addr,
+ &addrlen)) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to read data from socket: %s\n",
+ strerror(errno));
+ return;
+ }
+
+ if (HostNameLookups)
+ httpAddrLookup(&addr, addrname, sizeof(addrname));
+ else
+ httpAddrString(&addr, addrname, sizeof(addrname));
+
+ debug_printf("DEBUG: %.3f Received %d bytes from %s...\n", run_time(),
+ bytes, addrname);
+
+ /*
+ * Look for the response status code in the SNMP message header...
+ */
+
+ if (asn1_decode_snmp(buffer, bytes, &packet))
+ {
+ fprintf(stderr, "ERROR: Bad SNMP packet from %s: %s\n", addrname,
+ packet.error);
+
+ asn1_debug(buffer, bytes, 0);
+ hex_debug(buffer, bytes);
+
+ return;
+ }
+
+ debug_printf("DEBUG: community=\"%s\"\n", packet.community);
+ debug_printf("DEBUG: request-id=%d\n", packet.request_id);
+ debug_printf("DEBUG: error-status=%d\n", packet.error_status);
+
+ if (DebugLevel > 1)
+ asn1_debug(buffer, bytes, 0);
+
+ if (DebugLevel > 2)
+ hex_debug(buffer, bytes);
+
+ if (packet.error_status)
+ return;
+
+ /*
+ * Find a matching device in the cache...
+ */
+
+ key.address = addr;
+ device = (snmp_cache_t *)cupsArrayFind(Devices, &key);
+
+ /*
+ * Process the message...
+ */
+
+ if (packet.request_id == DeviceTypeRequest)
+ {
+ /*
+ * Got the device type response...
+ */
+
+ if (device)
+ {
+ debug_printf("DEBUG: Discarding duplicate device type for \"%s\"...\n",
+ addrname);
+ return;
+ }
+
+ /*
+ * Add the device and request the device description...
+ */
+
+ add_cache(&addr, addrname, NULL, NULL, NULL);
+
+ send_snmp_query(fd, &addr, SNMP_VERSION_1, packet.community,
+ DeviceDescRequest, DeviceDescOID);
+ }
+ else if (packet.request_id == DeviceDescRequest &&
+ packet.object_type == ASN1_OCTET_STRING)
+ {
+ /*
+ * Update an existing cache entry...
+ */
+
+ char make_model[256]; /* Make and model */
+
+
+ if (!device)
+ {
+ debug_printf("DEBUG: Discarding device description for \"%s\"...\n",
+ addrname);
+ return;
+ }
+
+ /*
+ * Convert the description to a make and model string...
+ */
+
+ if (strchr(packet.object_value.string, ':') &&
+ strchr(packet.object_value.string, ';'))
+ {
+ /*
+ * Description is the IEEE-1284 device ID...
+ */
+
+ get_make_model(packet.object_value.string, make_model,
+ sizeof(make_model));
+ }
+ else
+ {
+ /*
+ * Description is plain text...
+ */
+
+ fix_make_model(make_model, packet.object_value.string,
+ sizeof(make_model));
+ }
+
+ if (device->make_and_model)
+ free(device->make_and_model);
+
+ device->make_and_model = strdup(make_model);
+ }
+}
+
+
+/*
+ * 'run_time()' - Return the total running time...
+ */
+
+static double /* O - Number of seconds */
+run_time(void)
+{
+ struct timeval curtime; /* Current time */
+
+
+ gettimeofday(&curtime, NULL);
+
+ return (curtime.tv_sec - StartTime.tv_sec +
+ 0.000001 * (curtime.tv_usec - StartTime.tv_usec));
+}
+
+
+/*
+ * 'scan_devices()' - Scan for devices using SNMP.
+ */
+
+static void
+scan_devices(int fd) /* I - SNMP socket */
+{
+ char *address, /* Current address */
+ *community; /* Current community */
+ fd_set input; /* Input set for select() */
+ struct timeval timeout; /* Timeout for select() */
+ time_t endtime; /* End time for scan */
+ http_addrlist_t *addrs, /* List of addresses */
+ *addr; /* Current address */
+ snmp_cache_t *device; /* Current device */
+
+
+ /*
+ * Setup the request IDs...
+ */
+
+ gettimeofday(&StartTime, NULL);
+
+ DeviceTypeRequest = StartTime.tv_sec;
+ DeviceDescRequest = StartTime.tv_sec + 1;
+
+ /*
+ * First send all of the broadcast queries...
+ */
+
+ for (address = (char *)cupsArrayFirst(Addresses);
+ address;
+ address = (char *)cupsArrayNext(Addresses))
+ {
+ if (!strcmp(address, "@LOCAL"))
+ addrs = get_interface_addresses(NULL);
+ else if (!strncmp(address, "@IF(", 4))
+ {
+ char ifname[255]; /* Interface name */
+
+
+ strlcpy(ifname, address + 4, sizeof(ifname));
+ if (ifname[0])
+ ifname[strlen(ifname) - 1] = '\0';
+
+ addrs = get_interface_addresses(ifname);
+ }
+ else
+ addrs = httpAddrGetList(address, AF_INET, NULL);
+
+ if (!addrs)
+ {
+ fprintf(stderr, "ERROR: Unable to scan \"%s\"!\n", address);
+ continue;
+ }
+
+ for (community = (char *)cupsArrayFirst(Communities);
+ community;
+ community = (char *)cupsArrayNext(Communities))
+ {
+ debug_printf("DEBUG: Scanning for devices in \"%s\" via \"%s\"...\n",
+ community, address);
+
+ for (addr = addrs; addr; addr = addr->next)
+ send_snmp_query(fd, &(addr->addr), SNMP_VERSION_1, community,
+ DeviceTypeRequest, DeviceTypeOID);
+ }
+
+ httpAddrFreeList(addrs);
+ }
+
+ /*
+ * Then read any responses that come in over the next 3 seconds...
+ */
+
+ endtime = time(NULL) + 3;
+
+ FD_ZERO(&input);
+
+ while (time(NULL) < endtime)
+ {
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ FD_SET(fd, &input);
+ if (select(fd + 1, &input, NULL, NULL, &timeout) < 0)
+ {
+ fprintf(stderr, "ERROR: %.3f select() for %d failed: %s\n", run_time(),
+ fd, strerror(errno));
+ break;
+ }
+
+ if (FD_ISSET(fd, &input))
+ read_snmp_response(fd);
+ else
+ break;
+ }
+
+ /*
+ * Finally, probe all of the printers we discovered to see how they are
+ * connected...
+ */
+
+ for (device = (snmp_cache_t *)cupsArrayFirst(Devices);
+ device;
+ device = (snmp_cache_t *)cupsArrayNext(Devices))
+ if (!device->uri)
+ probe_device(device);
+
+ debug_printf("DEBUG: %.3f Scan complete!\n", run_time());
+}
+
+
+/*
+ * 'send_snmp_query()' - Send an SNMP query packet.
+ */
+
+static void
+send_snmp_query(
+ int fd, /* I - SNMP socket */
+ http_addr_t *addr, /* I - Address to send to */
+ int version, /* I - SNMP version */
+ const char *community, /* I - Community name */
+ const unsigned request_id, /* I - Request ID */
+ const int *oid) /* I - OID */
+{
+ int i; /* Looping var */
+ snmp_packet_t packet; /* SNMP message packet */
+ unsigned char buffer[SNMP_MAX_PACKET];/* SNMP message buffer */
+ int bytes; /* Size of message */
+ char addrname[32]; /* Address name */
+
+
+ /*
+ * Create the SNMP message...
+ */
+
+ memset(&packet, 0, sizeof(packet));
+
+ packet.version = version;
+ packet.request_type = ASN1_GET_REQUEST;
+ packet.request_id = request_id;
+ packet.object_type = ASN1_NULL_VALUE;
+
+ strlcpy(packet.community, community, sizeof(packet.community));
+
+ for (i = 0; oid[i]; i ++)
+ packet.object_name[i] = oid[i];
+
+ bytes = asn1_encode_snmp(buffer, sizeof(buffer), &packet);
+
+ if (bytes < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to send SNMP query: %s\n", packet.error);
+ return;
+ }
+
+ /*
+ * Send the message...
+ */
+
+ debug_printf("DEBUG: %.3f Sending %d bytes to %s...\n", run_time(),
+ bytes, httpAddrString(addr, addrname, sizeof(addrname)));
+ if (DebugLevel > 1)
+ asn1_debug(buffer, bytes, 0);
+ if (DebugLevel > 2)
+ hex_debug(buffer, bytes);
+
+ addr->ipv4.sin_port = htons(SNMP_PORT);
+
+ if (sendto(fd, buffer, bytes, 0, (void *)addr, sizeof(addr->ipv4)) < bytes)
+ fprintf(stderr, "ERROR: Unable to send %d bytes to %s: %s\n",
+ bytes, addrname, strerror(errno));
+}
+
+
+/*
+ * 'try_connect()' - Try connecting on a port...
+ */
+
+static int /* O - 0 on success or -1 on error */
+try_connect(http_addr_t *addr, /* I - Socket address */
+ const char *addrname, /* I - Hostname or IP address */
+ int port) /* I - Port number */
+{
+ int fd; /* Socket */
+ int status; /* Connection status */
+
+
+ debug_printf("DEBUG: %.3f Trying %s://%s:%d...\n", run_time(),
+ port == 515 ? "lpd" : "socket", addrname, port);
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to create socket: %s\n", strerror(errno));
+ return (-1);
+ }
+
+ addr->ipv4.sin_port = htons(port);
+
+ signal(SIGALRM, alarm_handler);
+ alarm(1);
+
+ status = connect(fd, (void *)addr, httpAddrLength(addr));
+
+ close(fd);
+ alarm(0);
+
+ return (status);
+}
+
+
+/*
+ * 'update_cache()' - Update a cached device...
+ */
+
+static void
+update_cache(snmp_cache_t *device, /* I - Device */
+ const char *uri, /* I - Device URI */
+ const char *id, /* I - Device ID */
+ const char *make_model) /* I - Device make and model */
+{
+ if (device->uri)
+ free(device->uri);
+
+ device->uri = strdup(uri);
+
+ if (id)
+ {
+ if (device->id)
+ free(device->id);
+
+ device->id = strdup(id);
+ }
+
+ if (make_model)
+ {
+ if (device->make_and_model)
+ free(device->make_and_model);
+
+ device->make_and_model = strdup(make_model);
+ }
+}
+
+
+/*
+ * End of "$Id: snmp.c 5453 2006-04-23 12:08:18Z mike $".
+ */
diff --git a/backend/snmp.txt b/backend/snmp.txt
new file mode 100644
index 0000000000..77a38c498d
--- /dev/null
+++ b/backend/snmp.txt
@@ -0,0 +1,172 @@
+snmp.txt - 2006-04-19
+---------------------
+
+This file lists the "interesting" bits from the command:
+
+ snmpwalk -v 1 -c public HOST .1
+
+for many network print servers and internal cards. It is mainly here
+for SNMP documentation and development purposes.
+
+
+AXIS 5600
+
+SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM J.sp.00,JETDIRECT EX,JD28,EEPROM 6.16.5
+SNMPv2-MIB::sysName.0 = STRING:
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceType.3 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: Hewlett-Packard hp LaserJet 3380
+HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: Axis AXIS 5600
+HOST-RESOURCES-MIB::hrDeviceDescr.3 = STRING: Axis AXIS 5600
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero
+HOST-RESOURCES-MIB::hrDeviceID.2 = OID: SNMPv2-SMI::zeroDotZero
+HOST-RESOURCES-MIB::hrDeviceID.3 = OID: SNMPv2-SMI::zeroDotZero
+SNMPv2-SMI::enterprises.11.2.4.3.10.8.0 = STRING: "AXIS433AE8"
+SNMPv2-SMI::enterprises.368.2.3.2.601.0 = INTEGER: 9100
+SNMPv2-SMI::enterprises.368.2.3.2.602.0 = INTEGER: 9101
+SNMPv2-SMI::enterprises.368.2.3.2.603.0 = INTEGER: 9102
+SNMPv2-SMI::enterprises.368.2.3.10.901.0 = STRING: "AXIS433AE8"
+
+
+AXIS OfficeBasic
+
+SNMPv2-MIB::sysDescr.0 = STRING: AXIS OfficeBasic Parallel Network Print Server V6.43 Sep 4 2003
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: EPSON Stylus Photo 870
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero
+
+
+DLink DP-301P+
+
+SNMPv2-MIB::sysDescr.0 = STRING: D-Link DP-301P+ Print Server
+
+
+Genicom ML280
+
+SNMPv2-MIB::sysDescr.0 = STRING: GENICOM microLaser 280
+SNMPv2-MIB::sysName.0 = STRING: PRQ_004F75
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: MANUFACTURER:GENICOM;MODEL:microLaser 280;
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.3369.1.1.2.4
+
+
+EPSON Type-B Network Card
+
+SNMPv2-MIB::sysDescr.0 = STRING: EPSON Type-B 10Base-T/100Base-TX Print Server
+SNMPv2-MIB::sysName.0 = STRING: StylusPro7600-BB87A8
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: EPSON Stylus Pro 7600
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.1248.1.2.1.22.69.109.117.108.97.116.101.83.116.121.108.117.115.32.80.114.111.32.55.54.48.48
+SNMPv2-SMI::enterprises.11.2.3.9.1.1.7.0 = STRING: "MFG:EPSON;CMD:ESCPL2,BDC;MDL:Stylus Pro 7600;CLS:PRINTER;DES:EPSON Stylus Pro 7600;"
+SNMPv2-SMI::enterprises.1248.1.2.2.1.1.1.1.1 = STRING: "MFG:EPSON;CMD:ESCPL2,BDC;MDL:Stylus Pro 7600;CLS:PRINTER;DES:EPSON Stylus Pro 7600;"
+
+
+EPSON Wireless 802.11b Print Server
+
+SNMPv2-MIB::sysDescr.0 = STRING: EPSON Wireless LAN Print Interface compatible with an HP JETDIRECT EX
+SNMPv2-MIB::sysName.0 = STRING: EAI_0F550B
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING:
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero
+
+
+HP JetDirect EX3plus
+
+SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM D.04.03,JETDIRECT EX,JD26,EEPROM D.05.22
+SNMPv2-MIB::sysName.0 = STRING: NPID1EC0F
+
+
+HP LJ4000
+
+SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM G.05.34,JETDIRECT,JD30,EEPROM G.08.32
+SNMPv2-MIB::sysName.0 = STRING:
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: HP LaserJet 4000 Series
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.11.2.3.9.1.2.5
+
+
+HP CLJ4550
+
+SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM L.20.07,JETDIRECT,JD84,EEPROM L.21.22,CIDATE 07/06/2001
+SNMPv2-MIB::sysName.0 = STRING: NPI02FDE7
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: HP Color LaserJet 4550
+HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: Hewlett-Packard Dynamic RAM Disk
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.11.2.3.9.1.2.14
+
+
+Lexmark C522
+
+SNMPv2-MIB::sysDescr.0 = STRING: Lexmark C522 version NS.NP.N212 kernel 2.6.6 All-N-1
+SNMPv2-MIB::sysName.0 = STRING: ET0004000D0CCA
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDeviceNonVolatileMemory
+HOST-RESOURCES-MIB::hrDeviceType.3 = OID: HOST-RESOURCES-TYPES::hrDeviceProcessor
+HOST-RESOURCES-MIB::hrDeviceType.4 = OID: HOST-RESOURCES-TYPES::hrDeviceSerialPort
+HOST-RESOURCES-MIB::hrDeviceType.5 = OID: HOST-RESOURCES-TYPES::hrDeviceNetwork
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: Lexmark C522 9421TTV LS.FA.P129
+HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: Nonvolatile RAM
+HOST-RESOURCES-MIB::hrDeviceDescr.3 = STRING: IBM 750 Rev CXr
+HOST-RESOURCES-MIB::hrDeviceDescr.4 = STRING: USB Interface
+HOST-RESOURCES-MIB::hrDeviceDescr.5 = STRING: Network Interface
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero
+HOST-RESOURCES-MIB::hrDeviceID.2 = OID: SNMPv2-SMI::zeroDotZero
+HOST-RESOURCES-MIB::hrDeviceID.3 = OID: SNMPv2-SMI::zeroDotZero
+HOST-RESOURCES-MIB::hrDeviceID.4 = OID: SNMPv2-SMI::zeroDotZero
+HOST-RESOURCES-MIB::hrDeviceID.5 = OID: SNMPv2-SMI::enterprises.641.1
+SNMPv2-SMI::enterprises.641.2.1.2.1.2.1 = STRING: "Lexmark C522"
+SNMPv2-SMI::enterprises.641.2.1.2.1.3.1 = STRING: "MANUFACTURER:Lexmark International;COMMAND SET:;MODEL:Lexmark C522"
+
+
+Linksys EPSX3
+
+SNMPv2-MIB::sysDescr.0 = STRING: ETHERNET MULTI-ENVIRONMENT.ROM, JETDIRECT EX, EEPROM 6016
+
+
+NetGear PS113
+
+SNMPv2-MIB::sysDescr.0 = STRING: A SNMP proxy agent.
+
+
+Okidata C7200
+
+SNMPv2-MIB::sysDescr.0 = STRING: OkiLAN 6200e
+SNMPv2-MIB::sysName.0 = STRING: OKI7009715
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDeviceNonVolat
+ileMemory
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: C7200
+HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: FLASH0
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.2001.1.1.1.1
+HOST-RESOURCES-MIB::hrDeviceID.2 = OID: SNMPv2-SMI::zeroDotZero
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.1 = STRING: "IEEE 1284"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.2 = STRING: "EtherTalk Phase 2"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.3 = STRING: "LPD"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.4 = STRING: "Netware Rprinter"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.5 = STRING: "Netware Bindery or NDS Pserver"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.6 = STRING: "Raw TCP Port 9100"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.7 = STRING: "FTP"
+SNMPv2-SMI::mib-2.43.14.1.1.3.1.8 = STRING: "DLC/LLC"
+SNMPv2-SMI::enterprises.2001.1.1.1.1.1.3530.0 = STRING: "C7200"
+
+
+Xerox N2025
+
+SNMPv2-MIB::sysDescr.0 = STRING: Xerox DocuPrint N2025 Network Laser Printer - 2.12-02
+SNMPv2-MIB::sysName.0 = STRING:
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDeviceParallelPort
+HOST-RESOURCES-MIB::hrDeviceType.3 = OID: HOST-RESOURCES-TYPES::hrDeviceNetwork
+HOST-RESOURCES-MIB::hrDeviceType.6 = OID: HOST-RESOURCES-TYPES::hrDeviceProcessor
+HOST-RESOURCES-MIB::hrDeviceType.7 = OID: HOST-RESOURCES-TYPES::hrDeviceOther
+HOST-RESOURCES-MIB::hrDeviceType.9 = OID: HOST-RESOURCES-TYPES::hrDeviceVolatileMemory
+HOST-RESOURCES-MIB::hrDeviceType.10 = OID: HOST-RESOURCES-TYPES::hrDeviceNonVolatileMemory
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: Xerox DocuPrint N2025 Network Laser Printer - 2.12-02
+HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: IEEE 1284 port
+HOST-RESOURCES-MIB::hrDeviceDescr.3 = STRING: Ethernet port
+HOST-RESOURCES-MIB::hrDeviceDescr.6 = STRING: Motorola Power PC
+HOST-RESOURCES-MIB::hrDeviceDescr.7 = STRING: USB Port
+HOST-RESOURCES-MIB::hrDeviceDescr.9 = STRING: RAM Memory
+HOST-RESOURCES-MIB::hrDeviceDescr.10 = STRING: ROM Memory
+HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.253.8.62.1.3.2.17.1
+
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
index a3d4d7f3b9..aac69d973b 100644
--- a/cgi-bin/admin.c
+++ b/cgi-bin/admin.c
@@ -1,5 +1,5 @@
/*
- * "$Id: admin.c 5360 2006-03-30 17:02:17Z mike $"
+ * "$Id: admin.c 5425 2006-04-18 19:59:05Z mike $"
*
* Administration CGI for the Common UNIX Printing System (CUPS).
*
@@ -506,9 +506,7 @@ do_am_printer(http_t *http, /* I - HTTP connection */
int modify) /* I - Modify the printer? */
{
int i; /* Looping var */
- int element; /* Element number */
- ipp_attribute_t *attr, /* Current attribute */
- *last; /* Last attribute */
+ ipp_attribute_t *attr; /* Current attribute */
ipp_t *request, /* IPP request */
*response, /* IPP response */
*oldinfo; /* Old printer information */
@@ -855,27 +853,31 @@ do_am_printer(http_t *http, /* I - HTTP connection */
* Got the list of PPDs, see if the user has selected a make...
*/
- cgiSetIPPVars(response, NULL, NULL, NULL, 0);
-
- if (var == NULL)
+ if (cgiSetIPPVars(response, NULL, NULL, NULL, 0) == 0)
{
/*
- * Let the user choose a make...
+ * No PPD files with this make, try again with all makes...
*/
- for (element = 0, attr = response->attrs, last = NULL;
- attr != NULL;
- attr = attr->next)
- if (attr->name && strcmp(attr->name, "ppd-make") == 0)
- if (last == NULL ||
- strcasecmp(last->values[0].string.text,
- attr->values[0].string.text) != 0)
- {
- cgiSetArray("PPD_MAKE", element, attr->values[0].string.text);
- element ++;
- last = attr;
- }
+ ippDelete(response);
+
+ request = ippNewRequest(CUPS_GET_PPDS);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/printers/");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "ppd-make");
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("choose-make.tmpl");
+ cgiEndHTML();
+ }
+ else if (!var)
+ {
cgiStartHTML(title);
cgiCopyTemplateLang("choose-make.tmpl");
cgiEndHTML();
@@ -931,7 +933,6 @@ do_am_printer(http_t *http, /* I - HTTP connection */
cgiEndHTML();
}
-
ippDelete(response);
}
else
@@ -1182,7 +1183,7 @@ do_config_printer(http_t *http) /* I - HTTP connection */
ppdLocalize(ppd);
- cgiStartHTML("Set Printer Options");
+ cgiStartHTML(cgiText(_("Set Printer Options")));
cgiCopyTemplateLang("set-printer-options-header.tmpl");
if (ppdConflicts(ppd))
@@ -1451,7 +1452,7 @@ do_config_printer(http_t *http) /* I - HTTP connection */
if (!in || !out)
{
cgiSetVariable("ERROR", strerror(errno));
- cgiStartHTML("Set Printer Options");
+ cgiStartHTML(cgiText(_("Set Printer Options")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
@@ -1814,7 +1815,7 @@ do_config_server(http_t *http) /* I - HTTP connection */
* Show the current config file...
*/
- cgiStartHTML("Edit Configuration File");
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
printf("\n", filename);
@@ -1837,10 +1838,13 @@ do_delete_class(http_t *http) /* I - HTTP connection */
const char *pclass; /* Printer class name */
- cgiStartHTML(cgiText(_("Delete Class")));
+ /*
+ * Get form variables...
+ */
if (cgiGetVariable("CONFIRM") == NULL)
{
+ cgiStartHTML(cgiText(_("Delete Class")));
cgiCopyTemplateLang("class-confirm.tmpl");
cgiEndHTML();
return;
@@ -1851,6 +1855,7 @@ do_delete_class(http_t *http) /* I - HTTP connection */
"localhost", 0, "/classes/%s", pclass);
else
{
+ cgiStartHTML(cgiText(_("Delete Class")));
cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
@@ -1877,6 +1882,12 @@ do_delete_class(http_t *http) /* I - HTTP connection */
ippDelete(cupsDoRequest(http, request, "/admin/"));
+ /*
+ * Show the results...
+ */
+
+ cgiStartHTML(cgiText(_("Delete Class")));
+
if (cupsLastError() > IPP_OK_CONFLICT)
cgiShowIPPError(_("Unable to delete class:"));
else
@@ -1898,10 +1909,13 @@ do_delete_printer(http_t *http) /* I - HTTP connection */
const char *printer; /* Printer printer name */
- cgiStartHTML(cgiText(_("Delete Printer")));
+ /*
+ * Get form variables...
+ */
if (cgiGetVariable("CONFIRM") == NULL)
{
+ cgiStartHTML(cgiText(_("Delete Printer")));
cgiCopyTemplateLang("printer-confirm.tmpl");
cgiEndHTML();
return;
@@ -1912,6 +1926,7 @@ do_delete_printer(http_t *http) /* I - HTTP connection */
"localhost", 0, "/printers/%s", printer);
else
{
+ cgiStartHTML(cgiText(_("Delete Printer")));
cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
@@ -1938,6 +1953,12 @@ do_delete_printer(http_t *http) /* I - HTTP connection */
ippDelete(cupsDoRequest(http, request, "/admin/"));
+ /*
+ * Show the results...
+ */
+
+ cgiStartHTML(cgiText(_("Delete Printer")));
+
if (cupsLastError() > IPP_OK_CONFLICT)
cgiShowIPPError(_("Unable to delete printer:"));
else
@@ -2867,5 +2888,5 @@ match_string(const char *a, /* I - First string */
/*
- * End of "$Id: admin.c 5360 2006-03-30 17:02:17Z mike $".
+ * End of "$Id: admin.c 5425 2006-04-18 19:59:05Z mike $".
*/
diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
index 274c8e9b8d..583a9f7455 100644
--- a/cgi-bin/ipp-var.c
+++ b/cgi-bin/ipp-var.c
@@ -1,5 +1,5 @@
/*
- * "$Id: ipp-var.c 5235 2006-03-06 13:02:23Z mike $"
+ * "$Id: ipp-var.c 5425 2006-04-18 19:59:05Z mike $"
*
* CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS).
*
@@ -1035,9 +1035,9 @@ cgiSetIPPVars(ipp_t *response, /* I - Response data to be copied... */
attr = cgiSetIPPObjectVars(attr, prefix, element);
}
- fprintf(stderr, "DEBUG2: Returing %d from cgiSetIPPVars()...\n", element + 1);
+ fprintf(stderr, "DEBUG2: Returing %d from cgiSetIPPVars()...\n", element);
- return (element + 1);
+ return (element);
}
@@ -1277,5 +1277,5 @@ cgiText(const char *message) /* I - Message */
/*
- * End of "$Id: ipp-var.c 5235 2006-03-06 13:02:23Z mike $".
+ * End of "$Id: ipp-var.c 5425 2006-04-18 19:59:05Z mike $".
*/
diff --git a/conf/Makefile b/conf/Makefile
index e806900af7..968e66004b 100644
--- a/conf/Makefile
+++ b/conf/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $"
+# "$Id: Makefile 5412 2006-04-17 14:30:53Z mike $"
#
# Configuration file makefile for the Common UNIX Printing System (CUPS).
#
@@ -74,8 +74,7 @@ install: all
if test -r $(SERVERROOT)/$$file ; then \
$(MV) $(SERVERROOT)/$$file $(SERVERROOT)/$$file.O ; \
fi ; \
- $(INSTALL_CONFIG) $$file $(SERVERROOT) ; \
- chgrp $(CUPS_GROUP) $(SERVERROOT)/$$file || true; \
+ $(INSTALL_DATA) $$file $(SERVERROOT) ; \
done
-if test x$(PAMDIR) != x; then \
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(PAMDIR); \
@@ -103,5 +102,5 @@ uninstall:
#
-# End of "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $".
+# End of "$Id: Makefile 5412 2006-04-17 14:30:53Z mike $".
#
diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in
index 426077b1bc..21f43b2cc1 100644
--- a/conf/cupsd.conf.in
+++ b/conf/cupsd.conf.in
@@ -1,5 +1,5 @@
#
-# "$Id: cupsd.conf.in 5114 2006-02-16 12:28:29Z mike $"
+# "$Id: cupsd.conf.in 5454 2006-04-23 21:46:38Z mike $"
#
# Sample configuration file for the Common UNIX Printing System (CUPS)
# scheduler. See "man cupsd.conf" for a complete description of this
@@ -33,6 +33,7 @@ DefaultAuthType Basic
# Restrict access to the admin pages...
+@ENCRYPTION_REQUIRED@
Order allow,deny
Allow localhost
@@ -72,5 +73,5 @@ DefaultAuthType Basic
#
-# End of "$Id: cupsd.conf.in 5114 2006-02-16 12:28:29Z mike $".
+# End of "$Id: cupsd.conf.in 5454 2006-04-23 21:46:38Z mike $".
#
diff --git a/conf/mime.convs b/conf/mime.convs
index b6c7004bac..f07342df80 100644
--- a/conf/mime.convs
+++ b/conf/mime.convs
@@ -1,5 +1,5 @@
#
-# "$Id: mime.convs 4559 2005-08-04 18:40:13Z mike $"
+# "$Id: mime.convs 5402 2006-04-14 19:21:03Z mike $"
#
# MIME converts file for the Common UNIX Printing System (CUPS).
#
@@ -107,13 +107,12 @@ image/x-sun-raster application/vnd.cups-raster 100 imagetoraster
#
# Raw filter...
#
-# Uncomment the following filter and the application/octet-stream type
-# in mime.types to allow printing of arbitrary files without the -oraw
-# option.
+# Uncomment the following filter to allow printing of arbitrary files
+# without the -oraw option.
#
#application/octet-stream application/vnd.cups-raw 0 -
#
-# End of "$Id: mime.convs 4559 2005-08-04 18:40:13Z mike $".
+# End of "$Id: mime.convs 5402 2006-04-14 19:21:03Z mike $".
#
diff --git a/conf/mime.types b/conf/mime.types
index c063fa6ce3..6f3d0467a7 100644
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -1,5 +1,5 @@
#
-# "$Id: mime.types 5375 2006-04-06 20:10:55Z mike $"
+# "$Id: mime.types 5402 2006-04-14 19:21:03Z mike $"
#
# MIME types file for the Common UNIX Printing System (CUPS).
#
@@ -147,7 +147,9 @@ text/css css
application/vnd.cups-command string(0,'#CUPS-COMMAND')
application/vnd.cups-form string(0,"")
+application/vnd.cups-pdf
application/vnd.cups-postscript
+application/vnd.cups-ppd ppd string(0,"*PPD-Adobe:")
application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR")
application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \
string(0,<1B>@) \
@@ -159,13 +161,11 @@ application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \
#
# Raw print file support...
#
-# Uncomment the following type and the application/octet-stream
-# filter line in mime.convs to allow raw file printing without the
-# -oraw option.
+# Comment the following type to prevent raw file printing.
#
-#application/octet-stream
+application/octet-stream
#
-# End of "$Id: mime.types 5375 2006-04-06 20:10:55Z mike $".
+# End of "$Id: mime.types 5402 2006-04-14 19:21:03Z mike $".
#
diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4
index 50394fa312..e327fe28cb 100644
--- a/config-scripts/cups-defaults.m4
+++ b/config-scripts/cups-defaults.m4
@@ -26,7 +26,7 @@ dnl
dnl Default langugages...
AC_ARG_WITH(languages, [ --with-languages set installed languages, default="es ja" ],
LANGUAGES="$withval",
- LANGUAGES="es ja")
+ LANGUAGES="es ja pl sv")
AC_SUBST(LANGUAGES)
dnl Default ConfigFilePerm
diff --git a/config-scripts/cups-image.m4 b/config-scripts/cups-image.m4
index 2d5607fcd5..e6f9644bbe 100644
--- a/config-scripts/cups-image.m4
+++ b/config-scripts/cups-image.m4
@@ -1,5 +1,5 @@
dnl
-dnl "$Id: cups-image.m4 5311 2006-03-19 13:21:42Z mike $"
+dnl "$Id: cups-image.m4 5451 2006-04-22 21:54:49Z mike $"
dnl
dnl Image library/filter stuff for the Common UNIX Printing System (CUPS).
dnl
@@ -78,7 +78,7 @@ AC_CHECK_LIB(m, pow)
if test x$enable_png != xno; then
AC_CHECK_HEADER(png.h,
- AC_CHECK_LIB(png, png_set_tRNS_to_alpha,
+ AC_CHECK_LIB(png, png_create_read_struct,
AC_DEFINE(HAVE_LIBPNG)
LIBPNG="-lpng -lm"))
else
@@ -110,5 +110,5 @@ AC_SUBST(EXPORT_LIBZ)
AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H))
dnl
-dnl End of "$Id: cups-image.m4 5311 2006-03-19 13:21:42Z mike $".
+dnl End of "$Id: cups-image.m4 5451 2006-04-22 21:54:49Z mike $".
dnl
diff --git a/config-scripts/cups-ssl.m4 b/config-scripts/cups-ssl.m4
index ebffe0ef66..22ab754d58 100644
--- a/config-scripts/cups-ssl.m4
+++ b/config-scripts/cups-ssl.m4
@@ -1,9 +1,9 @@
dnl
-dnl "$Id: cups-ssl.m4 5264 2006-03-10 01:10:36Z mike $"
+dnl "$Id: cups-ssl.m4 5457 2006-04-24 15:36:12Z mike $"
dnl
dnl OpenSSL/GNUTLS stuff for the Common UNIX Printing System (CUPS).
dnl
-dnl Copyright 1997-2005 by Easy Software Products, all rights reserved.
+dnl Copyright 1997-2006 by Easy Software Products, all rights reserved.
dnl
dnl These coded instructions, statements, and computer programs are the
dnl property of Easy Software Products and are protected by Federal
@@ -36,6 +36,7 @@ AC_ARG_WITH(openssl-includes, [ --with-openssl-includes set directory for OpenS
SSLFLAGS=""
SSLLIBS=""
+ENCRYPTION_REQUIRED=""
if test x$enable_ssl != xno; then
dnl Look for CDSA...
@@ -43,6 +44,10 @@ if test x$enable_ssl != xno; then
if test $uname = Darwin; then
AC_CHECK_HEADER(Security/SecureTransport.h,
[SSLLIBS="-framework CoreFoundation -framework Security"
+ # MacOS X doesn't (yet) come with pre-installed encryption
+ # certificates for CUPS, so don't enable encryption on
+ # /admin just yet...
+ #ENCRYPTION_REQUIRED=" Encryption Required"
AC_DEFINE(HAVE_SSL)
AC_DEFINE(HAVE_CDSASSL)])
fi
@@ -57,6 +62,7 @@ if test x$enable_ssl != xno; then
AC_CHECK_LIB(gnutls, gnutls_x509_crt_set_dn_by_oid,
[SSLLIBS="-lgnutls"
+ ENCRYPTION_REQUIRED=" Encryption Required"
AC_DEFINE(HAVE_SSL)
AC_DEFINE(HAVE_GNUTLS)])
@@ -84,6 +90,7 @@ if test x$enable_ssl != xno; then
AC_CHECK_LIB(ssl,SSL_new,
[SSLFLAGS="-DOPENSSL_DISABLE_OLD_DES_SUPPORT"
SSLLIBS="-lssl $libcrypto"
+ ENCRYPTION_REQUIRED=" Encryption Required"
AC_DEFINE(HAVE_SSL)
AC_DEFINE(HAVE_LIBSSL)],,
$libcrypto)
@@ -99,11 +106,12 @@ fi
AC_SUBST(SSLFLAGS)
AC_SUBST(SSLLIBS)
+AC_SUBST(ENCRYPTION_REQUIRED)
EXPORT_SSLLIBS="$SSLLIBS"
AC_SUBST(EXPORT_SSLLIBS)
dnl
-dnl End of "$Id: cups-ssl.m4 5264 2006-03-10 01:10:36Z mike $".
+dnl End of "$Id: cups-ssl.m4 5457 2006-04-24 15:36:12Z mike $".
dnl
diff --git a/configure.in b/configure.in
index 299ca6a44e..eb1137f24d 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
dnl
-dnl "$Id: configure.in 5377 2006-04-06 20:39:41Z mike $"
+dnl "$Id: configure.in 5413 2006-04-17 14:50:45Z mike $"
dnl
dnl Configuration script for the Common UNIX Printing System (CUPS).
dnl
@@ -46,18 +46,26 @@ sinclude(config-scripts/cups-defaults.m4)
sinclude(config-scripts/cups-pdf.m4)
sinclude(config-scripts/cups-scripting.m4)
+LANGFILES=""
+if test "x$LANGUAGES" != x; then
+ for lang in $LANGUAGES; do
+ LANGFILES="$LANGFILES doc/$lang/index.html"
+ LANGFILES="$LANGFILES templates/$lang/edit-config.tmpl"
+ LANGFILES="$LANGFILES templates/$lang/header.tmpl"
+ done
+fi
+
AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh init/cups-lpd cups-config
conf/cupsd.conf conf/pam.std doc/index.html
- doc/es/index.html doc/ja/index.html
doc/help/standard.html man/client.conf.man
man/cups-deviced.man man/cups-driverd.man
man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man
man/cupsd.conf.man man/lpoptions.man
templates/edit-config.tmpl templates/header.tmpl
- templates/es/header.tmpl templates/ja/header.tmpl)
+ $LANGFILES)
chmod +x cups-config
dnl
-dnl End of "$Id: configure.in 5377 2006-04-06 20:39:41Z mike $".
+dnl End of "$Id: configure.in 5413 2006-04-17 14:50:45Z mike $".
dnl
diff --git a/cups/Dependencies b/cups/Dependencies
index 74abad0801..4cb7cb37f6 100644
--- a/cups/Dependencies
+++ b/cups/Dependencies
@@ -20,11 +20,12 @@ encode.o: ipp-private.h string.h ../config.h debug.h
file.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h
file.o: string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h
file.o: debug.h
+getifaddrs.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h
getputfile.o: cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h
getputfile.o: string.h ../config.h debug.h
globals.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h
globals.o: globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h
-globals.o: transcode.h
+globals.o: transcode.h debug.h
http.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h
http.o: string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h
http.o: debug.h
@@ -60,8 +61,7 @@ ppd.o: file.h language.h i18n.h transcode.h debug.h
request.o: globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
request.o: array.h file.h language.h i18n.h transcode.h debug.h
snprintf.o: string.h ../config.h
-string.o: debug.h string.h ../config.h globals.h cups.h ipp.h http.h md5.h
-string.o: ppd.h array.h file.h language.h i18n.h transcode.h
+string.o: array.h debug.h string.h ../config.h
tempfile.o: globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
tempfile.o: array.h file.h language.h i18n.h transcode.h debug.h
transcode.o: globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
@@ -102,11 +102,12 @@ encode.32.o: encode.c ipp-private.h string.h ../config.h debug.h
file.32.o: file.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h
file.32.o: file.c string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h
file.32.o: file.c debug.h
+getifaddrs.32.o: getifaddrs.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h
getputfile.32.o: getputfile.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h
getputfile.32.o: getputfile.c string.h ../config.h debug.h
globals.32.o: globals.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h
globals.32.o: globals.c globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h
-globals.32.o: globals.c transcode.h
+globals.32.o: globals.c transcode.h debug.h
http.32.o: http.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h
http.32.o: http.c string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h
http.32.o: http.c debug.h
@@ -142,8 +143,7 @@ ppd.32.o: ppd.c file.h language.h i18n.h transcode.h debug.h
request.32.o: request.c globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
request.32.o: request.c array.h file.h language.h i18n.h transcode.h debug.h
snprintf.32.o: snprintf.c string.h ../config.h
-string.32.o: string.c debug.h string.h ../config.h globals.h cups.h ipp.h http.h md5.h
-string.32.o: string.c ppd.h array.h file.h language.h i18n.h transcode.h
+string.32.o: string.c array.h debug.h string.h ../config.h
tempfile.32.o: tempfile.c globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
tempfile.32.o: tempfile.c array.h file.h language.h i18n.h transcode.h debug.h
transcode.32.o: transcode.c globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
@@ -184,11 +184,12 @@ encode.64.o: encode.c ipp-private.h string.h ../config.h debug.h
file.64.o: file.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h
file.64.o: file.c string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h
file.64.o: file.c debug.h
+getifaddrs.64.o: getifaddrs.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h
getputfile.64.o: getputfile.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h
getputfile.64.o: getputfile.c string.h ../config.h debug.h
globals.64.o: globals.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h
globals.64.o: globals.c globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h
-globals.64.o: globals.c transcode.h
+globals.64.o: globals.c transcode.h debug.h
http.64.o: http.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h
http.64.o: http.c string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h
http.64.o: http.c debug.h
@@ -224,8 +225,7 @@ ppd.64.o: ppd.c file.h language.h i18n.h transcode.h debug.h
request.64.o: request.c globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
request.64.o: request.c array.h file.h language.h i18n.h transcode.h debug.h
snprintf.64.o: snprintf.c string.h ../config.h
-string.64.o: string.c debug.h string.h ../config.h globals.h cups.h ipp.h http.h md5.h
-string.64.o: string.c ppd.h array.h file.h language.h i18n.h transcode.h
+string.64.o: string.c array.h debug.h string.h ../config.h
tempfile.64.o: tempfile.c globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
tempfile.64.o: tempfile.c array.h file.h language.h i18n.h transcode.h debug.h
transcode.64.o: transcode.c globals.h string.h ../config.h cups.h ipp.h http.h md5.h ppd.h
diff --git a/cups/Makefile b/cups/Makefile
index 5951bb1253..1570e18612 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile 5354 2006-03-29 20:55:15Z mike $"
+# "$Id: Makefile 5428 2006-04-18 20:45:30Z mike $"
#
# API library Makefile for the Common UNIX Printing System (CUPS).
#
@@ -43,6 +43,7 @@ LIBOBJS = \
emit.o \
encode.o \
file.o \
+ getifaddrs.o \
getputfile.o \
globals.o \
http.o \
@@ -421,7 +422,7 @@ apihelp:
file.h file.c dir.h dir.c >../doc/help/api-filedir.html
mxmldoc --section "Programming" --title "PPD API" \
--intro api-ppd.shtml \
- ppd.h attr.c emit.c mark.c page.c \
+ ppd.h attr.c custom.c emit.c localize.c mark.c page.c \
ppd.c >../doc/help/api-ppd.html
mxmldoc --section "Programming" --title "HTTP and IPP APIs" \
--intro api-httpipp.shtml \
@@ -441,5 +442,5 @@ include Dependencies
#
-# End of "$Id: Makefile 5354 2006-03-29 20:55:15Z mike $".
+# End of "$Id: Makefile 5428 2006-04-18 20:45:30Z mike $".
#
diff --git a/cups/custom.c b/cups/custom.c
index 1d44826654..23008e93c6 100644
--- a/cups/custom.c
+++ b/cups/custom.c
@@ -1,5 +1,5 @@
/*
- * "$Id: custom.c 4938 2006-01-17 15:11:15Z mike $"
+ * "$Id: custom.c 5391 2006-04-14 12:26:50Z mike $"
*
* PPD custom option routines for the Common UNIX Printing System (CUPS).
*
@@ -34,6 +34,10 @@
*
* Contents:
*
+ * ppdFindCustomOption() - Find a custom option.
+ * ppdFindCustomParam() - Find a parameter for a custom option.
+ * ppdFirstCustomParam() - Return the first parameter for a custom option.
+ * ppdNextCustomParam() - Return the next parameter for a custom option.
*/
/*
@@ -46,6 +50,8 @@
/*
* 'ppdFindCustomOption()' - Find a custom option.
+ *
+ * @since CUPS 1.2@
*/
ppd_coption_t * /* O - Custom option or NULL */
@@ -65,6 +71,8 @@ ppdFindCustomOption(ppd_file_t *ppd, /* I - PPD file */
/*
* 'ppdFindCustomParam()' - Find a parameter for a custom option.
+ *
+ * @since CUPS 1.2@
*/
ppd_cparam_t * /* O - Custom parameter or NULL */
@@ -84,6 +92,8 @@ ppdFindCustomParam(ppd_coption_t *opt, /* I - Custom option */
/*
* 'ppdFirstCustomParam()' - Return the first parameter for a custom option.
+ *
+ * @since CUPS 1.2@
*/
ppd_cparam_t * /* O - Custom parameter or NULL */
@@ -98,6 +108,8 @@ ppdFirstCustomParam(ppd_coption_t *opt) /* I - Custom option */
/*
* 'ppdNextCustomParam()' - Return the next parameter for a custom option.
+ *
+ * @since CUPS 1.2@
*/
ppd_cparam_t * /* O - Custom parameter or NULL */
@@ -111,5 +123,5 @@ ppdNextCustomParam(ppd_coption_t *opt) /* I - Custom option */
/*
- * End of "$Id: custom.c 4938 2006-01-17 15:11:15Z mike $".
+ * End of "$Id: custom.c 5391 2006-04-14 12:26:50Z mike $".
*/
diff --git a/cups/getifaddrs.c b/cups/getifaddrs.c
new file mode 100644
index 0000000000..6cb448d613
--- /dev/null
+++ b/cups/getifaddrs.c
@@ -0,0 +1,275 @@
+/*
+ * "$Id: getifaddrs.c 5428 2006-04-18 20:45:30Z mike $"
+ *
+ * Network interface functions for the Common UNIX Printing System
+ * (CUPS) scheduler.
+ *
+ * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * _cups_getifaddrs() - Get a list of network interfaces on the system.
+ * _cups_freeifaddrs() - Free an interface list...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "http-private.h"
+
+
+#ifndef HAVE_GETIFADDRS
+/*
+ * '_cups_getifaddrs()' - Get a list of network interfaces on the system.
+ */
+
+static int /* O - 0 on success, -1 on error */
+_cups_getifaddrs(struct ifaddrs **addrs)/* O - List of interfaces */
+{
+ int sock; /* Socket */
+ char buffer[65536], /* Buffer for address info */
+ *bufptr, /* Pointer into buffer */
+ *bufend; /* End of buffer */
+ struct ifconf conf; /* Interface configurations */
+ struct sockaddr addr; /* Address data */
+ struct ifreq *ifp; /* Interface data */
+ int ifpsize; /* Size of interface data */
+ struct ifaddrs *temp; /* Pointer to current interface */
+ struct ifreq request; /* Interface request */
+
+
+ /*
+ * Start with an empty list...
+ */
+
+ if (addrs == NULL)
+ return (-1);
+
+ *addrs = NULL;
+
+ /*
+ * Create a UDP socket to get the interface data...
+ */
+
+ memset (&addr, 0, sizeof(addr));
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return (-1);
+
+ /*
+ * Try to get the list of interfaces...
+ */
+
+ conf.ifc_len = sizeof(buffer);
+ conf.ifc_buf = buffer;
+
+ if (ioctl(sock, SIOCGIFCONF, &conf) < 0)
+ {
+ /*
+ * Couldn't get the list of interfaces...
+ */
+
+ close(sock);
+ return (-1);
+ }
+
+ /*
+ * OK, got the list of interfaces, now lets step through the
+ * buffer to pull them out...
+ */
+
+# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+# define sockaddr_len(a) ((a)->sa_len)
+# else
+# define sockaddr_len(a) (sizeof(struct sockaddr))
+# endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+ for (bufptr = buffer, bufend = buffer + conf.ifc_len;
+ bufptr < bufend;
+ bufptr += ifpsize)
+ {
+ /*
+ * Get the current interface information...
+ */
+
+ ifp = (struct ifreq *)bufptr;
+ ifpsize = sizeof(ifp->ifr_name) + sockaddr_len(&(ifp->ifr_addr));
+
+ if (ifpsize < sizeof(struct ifreq))
+ ifpsize = sizeof(struct ifreq);
+
+ memset(&request, 0, sizeof(request));
+ memcpy(request.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name));
+
+ /*
+ * Check the status of the interface...
+ */
+
+ if (ioctl(sock, SIOCGIFFLAGS, &request) < 0)
+ continue;
+
+ /*
+ * Allocate memory for a single interface record...
+ */
+
+ if ((temp = calloc(1, sizeof(struct ifaddrs))) == NULL)
+ {
+ /*
+ * Unable to allocate memory...
+ */
+
+ close(sock);
+ return (-1);
+ }
+
+ /*
+ * Add this record to the front of the list and copy the name, flags,
+ * and network address...
+ */
+
+ temp->ifa_next = *addrs;
+ *addrs = temp;
+ temp->ifa_name = strdup(ifp->ifr_name);
+ temp->ifa_flags = request.ifr_flags;
+ if ((temp->ifa_addr = calloc(1, sockaddr_len(&(ifp->ifr_addr)))) != NULL)
+ memcpy(temp->ifa_addr, &(ifp->ifr_addr), sockaddr_len(&(ifp->ifr_addr)));
+
+ /*
+ * Try to get the netmask for the interface...
+ */
+
+ if (!ioctl(sock, SIOCGIFNETMASK, &request))
+ {
+ /*
+ * Got it, make a copy...
+ */
+
+ if ((temp->ifa_netmask = calloc(1, sizeof(request.ifr_netmask))) != NULL)
+ memcpy(temp->ifa_netmask, &(request.ifr_netmask),
+ sizeof(request.ifr_netmask));
+ }
+
+ /*
+ * Then get the broadcast or point-to-point (destination) address,
+ * if applicable...
+ */
+
+ if (temp->ifa_flags & IFF_BROADCAST)
+ {
+ /*
+ * Have a broadcast address, so get it!
+ */
+
+ if (!ioctl(sock, SIOCGIFBRDADDR, &request))
+ {
+ /*
+ * Got it, make a copy...
+ */
+
+ if ((temp->ifa_dstaddr = calloc(1, sizeof(request.ifr_broadaddr))) != NULL)
+ memcpy(temp->ifa_dstaddr, &(request.ifr_broadaddr),
+ sizeof(request.ifr_broadaddr));
+ }
+ }
+ else if (temp->ifa_flags & IFF_POINTOPOINT)
+ {
+ /*
+ * Point-to-point interface; grab the remote address...
+ */
+
+ if (!ioctl(sock, SIOCGIFDSTADDR, &request))
+ {
+ temp->ifa_dstaddr = malloc(sizeof(request.ifr_dstaddr));
+ memcpy(temp->ifa_dstaddr, &(request.ifr_dstaddr),
+ sizeof(request.ifr_dstaddr));
+ }
+ }
+ }
+
+ /*
+ * OK, we're done with the socket, close it and return 0...
+ */
+
+ close(sock);
+
+ return (0);
+}
+
+
+/*
+ * '_cups_freeifaddrs()' - Free an interface list...
+ */
+
+static void
+_cups_freeifaddrs(struct ifaddrs *addrs)/* I - Interface list to free */
+{
+ struct ifaddrs *next; /* Next interface in list */
+
+
+ while (addrs != NULL)
+ {
+ /*
+ * Make a copy of the next interface pointer...
+ */
+
+ next = addrs->ifa_next;
+
+ /*
+ * Free data values as needed...
+ */
+
+ if (addrs->ifa_name)
+ {
+ free(addrs->ifa_name);
+ addrs->ifa_name = NULL;
+ }
+
+ if (addrs->ifa_addr)
+ {
+ free(addrs->ifa_addr);
+ addrs->ifa_addr = NULL;
+ }
+
+ if (addrs->ifa_netmask)
+ {
+ free(addrs->ifa_netmask);
+ addrs->ifa_netmask = NULL;
+ }
+
+ if (addrs->ifa_dstaddr)
+ {
+ free(addrs->ifa_dstaddr);
+ addrs->ifa_dstaddr = NULL;
+ }
+
+ /*
+ * Free this node and continue to the next...
+ */
+
+ free(addrs);
+
+ addrs = next;
+ }
+}
+#endif /* !HAVE_GETIFADDRS */
+
+
+/*
+ * End of "$Id: getifaddrs.c 5428 2006-04-18 20:45:30Z mike $".
+ */
diff --git a/cups/http-addr.c b/cups/http-addr.c
index d3c100fbdb..f0d5fb37e8 100644
--- a/cups/http-addr.c
+++ b/cups/http-addr.c
@@ -1,5 +1,5 @@
/*
- * "$Id: http-addr.c 5251 2006-03-08 18:34:07Z mike $"
+ * "$Id: http-addr.c 5443 2006-04-20 14:50:26Z mike $"
*
* HTTP address routines for the Common UNIX Printing System (CUPS).
*
@@ -52,6 +52,9 @@
int /* O - 1 if "any", 0 otherwise */
httpAddrAny(const http_addr_t *addr) /* I - Address to check */
{
+ if (!addr)
+ return (0);
+
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6 &&
IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr)))
@@ -76,6 +79,12 @@ int /* O - 1 if equal, 0 if not */
httpAddrEqual(const http_addr_t *addr1, /* I - First address */
const http_addr_t *addr2) /* I - Second address */
{
+ if (!addr1 && !addr2)
+ return (1);
+
+ if (!addr1 || !addr2)
+ return (0);
+
if (addr1->addr.sa_family != addr2->addr.sa_family)
return (0);
@@ -102,6 +111,9 @@ httpAddrEqual(const http_addr_t *addr1, /* I - First address */
int /* O - Length in bytes */
httpAddrLength(const http_addr_t *addr) /* I - Address */
{
+ if (!addr)
+ return (0);
+
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6)
return (sizeof(addr->ipv6));
@@ -131,6 +143,9 @@ int /* O - 1 if local host, 0 otherwise */
httpAddrLocalhost(
const http_addr_t *addr) /* I - Address to check */
{
+ if (!addr)
+ return (1);
+
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6 &&
IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr)))
@@ -508,6 +523,9 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */
struct hostent *host; /* Host entry to get FQDN */
+ if (!s || slen <= 1)
+ return (NULL);
+
if (http)
{
if (http->hostname[0] == '/')
@@ -521,7 +539,8 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */
* Get the hostname...
*/
- gethostname(s, slen);
+ if (gethostname(s, slen) < 0)
+ strlcpy(s, "localhost", slen);
if (!strchr(s, '.'))
{
@@ -529,7 +548,7 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */
* The hostname is not a FQDN, so look it up...
*/
- if ((host = gethostbyname(s)) != NULL)
+ if ((host = gethostbyname(s)) != NULL && host->h_name)
strlcpy(s, host->h_name, slen);
}
}
@@ -543,5 +562,5 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */
/*
- * End of "$Id: http-addr.c 5251 2006-03-08 18:34:07Z mike $".
+ * End of "$Id: http-addr.c 5443 2006-04-20 14:50:26Z mike $".
*/
diff --git a/cups/http-private.h b/cups/http-private.h
index 0a2927f6aa..d74f2beea0 100644
--- a/cups/http-private.h
+++ b/cups/http-private.h
@@ -1,5 +1,5 @@
/*
- * "$Id: http-private.h 5373 2006-04-06 20:03:32Z mike $"
+ * "$Id: http-private.h 5428 2006-04-18 20:45:30Z mike $"
*
* Private HTTP definitions for the Common UNIX Printing System (CUPS).
*
@@ -98,7 +98,11 @@ typedef struct
# include
-typedef SSLConnectionRef http_tls_t;
+typedef struct /**** CDSA connection information ****/
+{
+ SSLContextRef session; /* CDSA session object */
+ CFArrayRef certsArray; /* Certificates array */
+} http_tls_t;
typedef union _cdsa_conn_ref_u /**** CDSA Connection reference union
**** used to resolve 64-bit casting
@@ -129,8 +133,46 @@ extern const char *_cups_hstrerror(int error);
extern const char *hstrerror(int error);
# endif /* !HAVE_HSTRERROR */
+
+/*
+ * Some OS's don't have getifaddrs() and freeifaddrs()...
+ */
+
+# include
+# ifdef HAVE_GETIFADDRS
+# include
+# else
+# include
+# ifdef HAVE_SYS_SOCKIO_H
+# include
+# endif /* HAVE_SYS_SOCKIO_H */
+
+# ifdef ifa_dstaddr
+# undef ifa_dstaddr
+# endif /* ifa_dstaddr */
+# ifndef ifr_netmask
+# define ifr_netmask ifr_addr
+# endif /* !ifr_netmask */
+
+struct ifaddrs /**** Interface Structure ****/
+{
+ struct ifaddrs *ifa_next; /* Next interface in list */
+ char *ifa_name; /* Name of interface */
+ unsigned int ifa_flags; /* Flags (up, point-to-point, etc.) */
+ struct sockaddr *ifa_addr, /* Network address */
+ *ifa_netmask, /* Address mask */
+ *ifa_dstaddr; /* Broadcast or destination address */
+ void *ifa_data; /* Interface statistics */
+};
+
+static int _cups_getifaddrs(struct ifaddrs **addrs);
+# define getifaddrs _cups_getifaddrs
+static void _cups_freeifaddrs(struct ifaddrs *addrs);
+# define freeifaddrs _cups_freeifaddrs
+# endif /* HAVE_GETIFADDRS */
+
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
/*
- * End of "$Id: http-private.h 5373 2006-04-06 20:03:32Z mike $".
+ * End of "$Id: http-private.h 5428 2006-04-18 20:45:30Z mike $".
*/
diff --git a/cups/http.c b/cups/http.c
index a8ec36a028..2e96795f0f 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -1,5 +1,5 @@
/*
- * "$Id: http.c 5373 2006-04-06 20:03:32Z mike $"
+ * "$Id: http.c 5416 2006-04-17 21:24:17Z mike $"
*
* HTTP routines for the Common UNIX Printing System (CUPS).
*
@@ -867,7 +867,11 @@ httpGets(char *line, /* I - Line to read into */
*/
if (!http->blocking && !http_wait(http, 1000))
+ {
+ DEBUG_puts("httpGets: Timed out!");
+ http->error = ETIMEDOUT;
return (NULL);
+ }
#ifdef HAVE_SSL
if (http->tls)
@@ -2041,7 +2045,7 @@ http_read_ssl(http_t *http, /* I - HTTP connection */
size_t processed; /* Number of bytes processed */
- error = SSLRead((SSLContextRef)http->tls, buf, len, &processed);
+ error = SSLRead(((http_tls_t *)http->tls)->session, buf, len, &processed);
switch (error)
{
@@ -2217,15 +2221,16 @@ static int /* O - Status of connection */
http_setup_ssl(http_t *http) /* I - HTTP connection */
{
# ifdef HAVE_LIBSSL
- SSL_CTX *context; /* Context for encryption */
- SSL *conn; /* Connection for encryption */
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
# elif defined(HAVE_GNUTLS)
- http_tls_t *conn; /* TLS session object */
+ http_tls_t *conn; /* TLS session object */
gnutls_certificate_client_credentials *credentials;
- /* TLS credentials */
+ /* TLS credentials */
# elif defined(HAVE_CDSASSL)
- SSLContextRef conn; /* Context for encryption */
- OSStatus error; /* Error info */
+ OSStatus error; /* Error code */
+ http_tls_t *conn; /* CDSA connection information */
+ cdsa_conn_ref_t u; /* Connection reference union */
# endif /* HAVE_LIBSSL */
@@ -2262,9 +2267,7 @@ http_setup_ssl(http_t *http) /* I - HTTP connection */
}
# elif defined(HAVE_GNUTLS)
- conn = (http_tls_t *)malloc(sizeof(http_tls_t));
-
- if (conn == NULL)
+ if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
{
http->error = errno;
http->status = HTTP_ERROR;
@@ -2303,45 +2306,51 @@ http_setup_ssl(http_t *http) /* I - HTTP connection */
conn->credentials = credentials;
# elif defined(HAVE_CDSASSL)
- cdsa_conn_ref_t u; /* Connection reference union */
+ conn = (http_tls_t *)calloc(1, sizeof(http_tls_t));
+ if (conn == NULL)
+ return (-1);
- error = SSLNewContext(false, &conn);
-
- if (!error)
- error = SSLSetIOFuncs(conn, _httpReadCDSA, _httpWriteCDSA);
-
- if (!error)
+ if ((error = SSLNewContext(false, &conn->session)))
{
- /*
- * Use a union to resolve warnings about int/pointer size mismatches...
- */
+ http->error = error;
+ http->status = HTTP_ERROR;
- u.connection = NULL;
- u.sock = http->fd;
- error = SSLSetConnection(conn, u.connection);
+ free(conn);
+ return (-1);
}
+ /*
+ * Use a union to resolve warnings about int/pointer size mismatches...
+ */
+
+ u.connection = NULL;
+ u.sock = http->fd;
+ error = SSLSetConnection(conn->session, u.connection);
+
+ if (!error)
+ error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
+
if (!error)
- error = SSLSetAllowsExpiredCerts(conn, true);
+ error = SSLSetAllowsExpiredCerts(conn->session, true);
if (!error)
- error = SSLSetAllowsAnyRoot(conn, true);
+ error = SSLSetAllowsAnyRoot(conn->session, true);
if (!error)
{
- while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+ while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
usleep(1000);
}
- if (error != 0)
+ if (error)
{
http->error = error;
http->status = HTTP_ERROR;
- SSLDisposeContext(conn);
+ SSLDisposeContext(conn->session);
- close(http->fd);
+ free(conn);
return (-1);
}
@@ -2359,11 +2368,11 @@ http_setup_ssl(http_t *http) /* I - HTTP connection */
*/
static void
-http_shutdown_ssl(http_t *http) /* I - HTTP connection */
+http_shutdown_ssl(http_t *http) /* I - HTTP connection */
{
# ifdef HAVE_LIBSSL
- SSL_CTX *context; /* Context for encryption */
- SSL *conn; /* Connection for encryption */
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
conn = (SSL *)(http->tls);
@@ -2374,9 +2383,9 @@ http_shutdown_ssl(http_t *http) /* I - HTTP connection */
SSL_free(conn);
# elif defined(HAVE_GNUTLS)
- http_tls_t *conn; /* Encryption session */
+ http_tls_t *conn; /* Encryption session */
gnutls_certificate_client_credentials *credentials;
- /* TLS credentials */
+ /* TLS credentials */
conn = (http_tls_t *)(http->tls);
@@ -2389,10 +2398,20 @@ http_shutdown_ssl(http_t *http) /* I - HTTP connection */
free(conn);
# elif defined(HAVE_CDSASSL)
- while (SSLClose((SSLContextRef)http->tls) == errSSLWouldBlock)
+ http_tls_t *conn; /* CDSA connection information */
+
+
+ conn = (http_tls_t *)(http->tls);
+
+ while (SSLClose(conn->session) == errSSLWouldBlock)
usleep(1000);
- SSLDisposeContext((SSLContextRef)http->tls);
+ SSLDisposeContext(conn->session);
+
+ if (conn->certsArray)
+ CFRelease(conn->certsArray);
+
+ free(conn);
# endif /* HAVE_LIBSSL */
http->tls = NULL;
@@ -2405,11 +2424,11 @@ http_shutdown_ssl(http_t *http) /* I - HTTP connection */
* 'http_upgrade()' - Force upgrade to TLS encryption.
*/
-static int /* O - Status of connection */
-http_upgrade(http_t *http) /* I - HTTP connection */
+static int /* O - Status of connection */
+http_upgrade(http_t *http) /* I - HTTP connection */
{
- int ret; /* Return value */
- http_t myhttp; /* Local copy of HTTP data */
+ int ret; /* Return value */
+ http_t myhttp; /* Local copy of HTTP data */
DEBUG_printf(("http_upgrade(%p)\n", http));
@@ -2529,7 +2548,7 @@ http_wait(http_t *http, /* I - HTTP connection */
# elif defined(HAVE_CDSASSL)
size_t bytes; /* Bytes that are available */
- if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)
+ if (!SSLGetBufferedReadSize(((http_tls_t *)http->tls)->session, &bytes) && bytes > 0)
return (1);
# endif /* HAVE_LIBSSL */
}
@@ -2572,6 +2591,8 @@ http_wait(http_t *http, /* I - HTTP connection */
{
FD_SET(http->fd, http->input_set);
+ DEBUG_printf(("http_wait: msec=%d, http->fd=%d\n", msec, http->fd));
+
if (msec >= 0)
{
timeout.tv_sec = msec / 1000;
@@ -2581,6 +2602,8 @@ http_wait(http_t *http, /* I - HTTP connection */
}
else
nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
+
+ DEBUG_printf(("http_wait: select() returned %d...\n", nfds));
}
#ifdef WIN32
while (nfds < 0 && WSAGetLastError() == WSAEINTR);
@@ -2590,6 +2613,8 @@ http_wait(http_t *http, /* I - HTTP connection */
FD_CLR(http->fd, http->input_set);
+ DEBUG_printf(("http_wait: returning with nfds=%d...\n", nfds));
+
return (nfds > 0);
}
@@ -2745,7 +2770,7 @@ http_write_ssl(http_t *http, /* I - HTTP connection */
size_t processed; /* Number of bytes processed */
- error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);
+ error = SSLWrite(((http_tls_t *)http->tls)->session, buf, len, &processed);
switch (error)
{
@@ -2777,5 +2802,5 @@ http_write_ssl(http_t *http, /* I - HTTP connection */
/*
- * End of "$Id: http.c 5373 2006-04-06 20:03:32Z mike $".
+ * End of "$Id: http.c 5416 2006-04-17 21:24:17Z mike $".
*/
diff --git a/cups/ipp.c b/cups/ipp.c
index cc109b7cc5..53da93e9b9 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -1,5 +1,5 @@
/*
- * "$Id: ipp.c 5329 2006-03-23 20:37:36Z mike $"
+ * "$Id: ipp.c 5415 2006-04-17 20:39:05Z mike $"
*
* Internet Printing Protocol support functions for the Common UNIX
* Printing System (CUPS).
@@ -1034,6 +1034,7 @@ ippReadIO(void *src, /* I - Data source */
DEBUG_printf(("ippReadIO(%p, %p, %d, %p, %p)\n", src, cb, blocking,
parent, ipp));
+ DEBUG_printf(("ippReadIO: ipp->state=%d\n", ipp->state));
if (src == NULL || ipp == NULL)
return (IPP_ERROR);
@@ -1527,6 +1528,8 @@ ippReadIO(void *src, /* I - Data source */
break; /* anti-compiler-warning-code */
}
+ DEBUG_printf(("ippReadIO: returning ipp->state=%d!\n", ipp->state));
+
return (ipp->state);
}
@@ -1672,7 +1675,7 @@ ippWriteIO(void *dst, /* I - Destination */
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP header...");
+ DEBUG_puts("ippWriteIO: Could not write IPP header...");
return (IPP_ERROR);
}
}
@@ -1686,9 +1689,9 @@ ippWriteIO(void *dst, /* I - Destination */
ipp->current = ipp->attrs;
ipp->curtag = IPP_TAG_ZERO;
- DEBUG_printf(("ippWrite: version=%d.%d\n", buffer[0], buffer[1]));
- DEBUG_printf(("ippWrite: op_status=%04x\n", ipp->request.any.op_status));
- DEBUG_printf(("ippWrite: request_id=%d\n", ipp->request.any.request_id));
+ DEBUG_printf(("ippWriteIO: version=%d.%d\n", buffer[0], buffer[1]));
+ DEBUG_printf(("ippWriteIO: op_status=%04x\n", ipp->request.any.op_status));
+ DEBUG_printf(("ippWriteIO: request_id=%d\n", ipp->request.any.request_id));
/*
* If blocking is disabled, stop here...
@@ -1720,7 +1723,7 @@ ippWriteIO(void *dst, /* I - Destination */
if (attr->group_tag == IPP_TAG_ZERO)
continue;
- DEBUG_printf(("ippWrite: wrote group tag = %x\n", attr->group_tag));
+ DEBUG_printf(("ippWriteIO: wrote group tag = %x\n", attr->group_tag));
*bufptr++ = attr->group_tag;
}
else if (attr->group_tag == IPP_TAG_ZERO)
@@ -1751,8 +1754,8 @@ ippWriteIO(void *dst, /* I - Destination */
* Write the value tag, name length, and name string...
*/
- DEBUG_printf(("ippWrite: writing value tag = %x\n", attr->value_tag));
- DEBUG_printf(("ippWrite: writing name = %d, \'%s\'\n", n, attr->name));
+ DEBUG_printf(("ippWriteIO: writing value tag = %x\n", attr->value_tag));
+ DEBUG_printf(("ippWriteIO: writing name = %d, \'%s\'\n", n, attr->name));
*bufptr++ = attr->value_tag;
*bufptr++ = n >> 8;
@@ -1775,11 +1778,11 @@ ippWriteIO(void *dst, /* I - Destination */
* and empty name for the collection member attribute...
*/
- DEBUG_printf(("ippWrite: writing value tag = %x\n",
+ DEBUG_printf(("ippWriteIO: writing value tag = %x\n",
IPP_TAG_MEMBERNAME));
- DEBUG_printf(("ippWrite: writing name = %d, \'%s\'\n", n, attr->name));
- DEBUG_printf(("ippWrite: writing value tag = %x\n", attr->value_tag));
- DEBUG_puts("ippWrite: writing name = 0, \'\'\n");
+ DEBUG_printf(("ippWriteIO: writing name = %d, \'%s\'\n", n, attr->name));
+ DEBUG_printf(("ippWriteIO: writing value tag = %x\n", attr->value_tag));
+ DEBUG_puts("ippWriteIO: writing name = 0, \'\'\n");
*bufptr++ = IPP_TAG_MEMBERNAME;
*bufptr++ = 0;
@@ -1810,7 +1813,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -1854,7 +1857,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -1905,15 +1908,15 @@ ippWriteIO(void *dst, /* I - Destination */
* values with a zero-length name...
*/
- DEBUG_printf(("ippWrite: writing value tag = %x\n",
+ DEBUG_printf(("ippWriteIO: writing value tag = %x\n",
attr->value_tag));
- DEBUG_printf(("ippWrite: writing name = 0, \'\'\n"));
+ DEBUG_printf(("ippWriteIO: writing name = 0, \'\'\n"));
if ((sizeof(buffer) - (bufptr - buffer)) < 3)
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -1933,14 +1936,14 @@ ippWriteIO(void *dst, /* I - Destination */
if (n > (sizeof(buffer) - 2))
return (IPP_ERROR);
- DEBUG_printf(("ippWrite: writing string = %d, \'%s\'\n", n,
+ DEBUG_printf(("ippWriteIO: writing string = %d, \'%s\'\n", n,
value->string.text));
if ((int)(sizeof(buffer) - (bufptr - buffer)) < (n + 2))
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -1977,7 +1980,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2020,7 +2023,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2071,7 +2074,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2128,7 +2131,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2165,7 +2168,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2226,7 +2229,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2254,7 +2257,7 @@ ippWriteIO(void *dst, /* I - Destination */
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2287,7 +2290,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2315,7 +2318,7 @@ ippWriteIO(void *dst, /* I - Destination */
{
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
@@ -2342,11 +2345,11 @@ ippWriteIO(void *dst, /* I - Destination */
if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ DEBUG_puts("ippWriteIO: Could not write IPP attribute...");
return (IPP_ERROR);
}
- DEBUG_printf(("ippWrite: wrote %d bytes\n", bufptr - buffer));
+ DEBUG_printf(("ippWriteIO: wrote %d bytes\n", bufptr - buffer));
/*
* If blocking is disabled, stop here...
@@ -2380,7 +2383,7 @@ ippWriteIO(void *dst, /* I - Destination */
if ((*cb)(dst, buffer, n) < 0)
{
- DEBUG_puts("ippWrite: Could not write IPP end-tag...");
+ DEBUG_puts("ippWriteIO: Could not write IPP end-tag...");
return (IPP_ERROR);
}
@@ -2806,14 +2809,14 @@ ipp_write_file(int *fd, /* I - File descriptor */
*/
ipp_attribute_t * /* O - New attribute */
-_ipp_add(ipp_t *ipp, /* I - IPP message */
- int num_values) /* I - Number of values */
+_ipp_add_attr(ipp_t *ipp, /* I - IPP message */
+ int num_values) /* I - Number of values */
{
return (_ippAddAttr(ipp, num_values));
}
void
-_ipp_free(ipp_attribute_t *attr) /* I - Attribute to free */
+_ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */
{
_ippFreeAttr(attr);
}
@@ -2821,5 +2824,5 @@ _ipp_free(ipp_attribute_t *attr) /* I - Attribute to free */
/*
- * End of "$Id: ipp.c 5329 2006-03-23 20:37:36Z mike $".
+ * End of "$Id: ipp.c 5415 2006-04-17 20:39:05Z mike $".
*/
diff --git a/cups/localize.c b/cups/localize.c
index 97662b7be3..b07609bbbd 100644
--- a/cups/localize.c
+++ b/cups/localize.c
@@ -1,5 +1,5 @@
/*
- * "$Id: localize.c 4937 2006-01-17 04:03:22Z mike $"
+ * "$Id: localize.c 5391 2006-04-14 12:26:50Z mike $"
*
* PPD custom option routines for the Common UNIX Printing System (CUPS).
*
@@ -56,6 +56,8 @@ static const char *ppd_text(ppd_file_t *ppd, const char *keyword,
/*
* 'ppdLocalize()' - Localize the PPD file to the current locale.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on success, -1 on error */
@@ -183,5 +185,5 @@ ppd_text(ppd_file_t *ppd, /* I - PPD file */
/*
- * End of "$Id: localize.c 4937 2006-01-17 04:03:22Z mike $".
+ * End of "$Id: localize.c 5391 2006-04-14 12:26:50Z mike $".
*/
diff --git a/cups/request.c b/cups/request.c
index 4839bd3f1e..9a9161d3d6 100644
--- a/cups/request.c
+++ b/cups/request.c
@@ -1,5 +1,5 @@
/*
- * "$Id: request.c 5362 2006-03-31 15:26:12Z mike $"
+ * "$Id: request.c 5447 2006-04-21 20:07:51Z mike $"
*
* IPP utilities for the Common UNIX Printing System (CUPS).
*
@@ -118,7 +118,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
ippDelete(request);
- _cupsSetError(IPP_NOT_POSSIBLE, NULL);
+ _cupsSetError(IPP_NOT_POSSIBLE, strerror(EISDIR));
return (NULL);
}
@@ -278,10 +278,15 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
}
else if (status == HTTP_ERROR)
{
+ DEBUG_printf(("cupsDoFileRequest: http->error=%d (%s)\n", http->error,
+ strerror(http->error)));
+
#ifdef WIN32
- if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH)
+ if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH &&
+ http->error != ETIMEDOUT)
#else
- if (http->error != ENETDOWN && http->error != ENETUNREACH)
+ if (http->error != ENETDOWN && http->error != ENETUNREACH &&
+ http->error != ETIMEDOUT)
#endif /* WIN32 */
continue;
else
@@ -328,20 +333,21 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
response = ippNew();
- if (ippRead(http, response) == IPP_ERROR)
- {
- /*
- * Delete the response...
- */
+ while ((state = ippRead(http, response)) != IPP_DATA)
+ if (state == IPP_ERROR)
+ {
+ /*
+ * Delete the response...
+ */
- DEBUG_puts("IPP read error!");
- ippDelete(response);
- response = NULL;
+ DEBUG_puts("IPP read error!");
+ ippDelete(response);
+ response = NULL;
- _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno));
+ _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno));
- break;
- }
+ break;
+ }
}
}
@@ -463,5 +469,5 @@ _cupsSetError(ipp_status_t status, /* I - IPP status code */
/*
- * End of "$Id: request.c 5362 2006-03-31 15:26:12Z mike $".
+ * End of "$Id: request.c 5447 2006-04-21 20:07:51Z mike $".
*/
diff --git a/cups/testi18n.c b/cups/testi18n.c
index 8392a65fe3..0fc4397932 100644
--- a/cups/testi18n.c
+++ b/cups/testi18n.c
@@ -1,5 +1,5 @@
/*
- * "$Id: testi18n.c 5294 2006-03-15 21:09:32Z mike $"
+ * "$Id: testi18n.c 5444 2006-04-20 18:16:54Z mike $"
*
* Internationalization test for Common UNIX Printing System (CUPS).
*
@@ -23,9 +23,8 @@
*
* Contents:
*
- * main() - Main entry for internationalization test module.
- * print_utf8() - Print UTF-8 string with (optional) message.
- * print_utf32() - Print UTF-32 string with (optional) message.
+ * main() - Main entry for internationalization test module.
+ * print_utf8() - Print UTF-8 string with (optional) message.
*/
/*
@@ -36,6 +35,7 @@
#include
#include
#include
+#include
#include "i18n.h"
#include "string.h"
@@ -46,7 +46,6 @@
*/
static void print_utf8(const char *msg, const cups_utf8_t *src);
-static void print_utf32(const char *msg, const cups_utf32_t *src);
/*
@@ -81,18 +80,21 @@ main(int argc, /* I - Argument Count */
cups_utf8_t utf8taiwan[] = /* UTF-8 Chinese source */
{ 0x41, 0x20, 0x21, 0x3D, 0x20, 0xE4, 0xB9, 0x82, 0x2E, 0x00 };
/* "A != ." - use Windows 950 (Big5) or EUC-TW */
- cups_utf8_t utf8good[] = /* UTF-8 good 16-bit source */
- { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xC3, 0x84, 0x2E, 0x00 };
- /* "A ." */
- cups_utf8_t utf8bad[] = /* UTF-8 bad 16-bit source */
- { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xF8, 0x84, 0x2E, 0x00 };
- /* "A <...bad stuff...>." */
cups_utf8_t utf8dest[1024]; /* UTF-8 destination string */
- cups_utf32_t utf32src[1024]; /* UTF-32 source string */
cups_utf32_t utf32dest[1024]; /* UTF-32 destination string */
_cups_vmap_t *vmap; /* VBCS charmap pointer */
+ /*
+ * Make sure we have a symbolic link from the data directory to a
+ * "charmaps" directory, and then point the library at it...
+ */
+
+ if (access("charmaps", 0))
+ symlink("../data", "charmaps");
+
+ putenv("CUPS_DATADIR=.");
+
/*
* Start with some conversion tests from a UTF-8 test file.
*/
@@ -238,7 +240,7 @@ main(int argc, /* I - Argument Count */
len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_1);
if (len != strlen((char *)utf8latin))
{
- printf("FAIL (len=%d, expected %d)\n", len, strlen((char *)utf8latin));
+ printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8latin));
print_utf8(" utf8latin", utf8latin);
print_utf8(" utf8dest", utf8dest);
errors ++;
@@ -289,7 +291,7 @@ main(int argc, /* I - Argument Count */
len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_7);
if (len != strlen((char *)utf8greek))
{
- printf("FAIL (len=%d, expected %d)\n", len, strlen((char *)utf8greek));
+ printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8greek));
print_utf8(" utf8greek", utf8greek);
print_utf8(" utf8dest", utf8dest);
errors ++;
@@ -335,7 +337,7 @@ main(int argc, /* I - Argument Count */
len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_932);
if (len != strlen((char *)utf8japan))
{
- printf("FAIL (len=%d, expected %d)\n", len, strlen((char *)utf8japan));
+ printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8japan));
print_utf8(" utf8japan", utf8japan);
print_utf8(" utf8dest", utf8dest);
errors ++;
@@ -381,7 +383,7 @@ main(int argc, /* I - Argument Count */
len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_JP);
if (len != strlen((char *)utf8japan))
{
- printf("FAIL (len=%d, expected %d)\n", len, strlen((char *)utf8japan));
+ printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8japan));
print_utf8(" utf8japan", utf8japan);
print_utf8(" utf8dest", utf8dest);
errors ++;
@@ -427,7 +429,7 @@ main(int argc, /* I - Argument Count */
len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_950);
if (len != strlen((char *)utf8taiwan))
{
- printf("FAIL (len=%d, expected %d)\n", len, strlen((char *)utf8taiwan));
+ printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8taiwan));
print_utf8(" utf8taiwan", utf8taiwan);
print_utf8(" utf8dest", utf8dest);
errors ++;
@@ -473,7 +475,7 @@ main(int argc, /* I - Argument Count */
len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_TW);
if (len != strlen((char *)utf8taiwan))
{
- printf("FAIL (len=%d, expected %d)\n", len, strlen((char *)utf8taiwan));
+ printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8taiwan));
print_utf8(" utf8taiwan", utf8taiwan);
print_utf8(" utf8dest", utf8dest);
errors ++;
@@ -554,23 +556,5 @@ print_utf8(const char *msg, /* I - Message String */
/*
- * 'print_utf32()' - Print UTF-32 string with (optional) message.
- */
-
-static void
-print_utf32(const char *msg, /* I - Message String */
- const cups_utf32_t *src) /* I - UTF-32 Source String */
-{
- if (msg)
- printf("%s:", msg);
-
- for (; *src; src ++)
- printf(" %04x", (int) *src);
-
- putchar('\n');
-}
-
-
-/*
- * End of "$Id: testi18n.c 5294 2006-03-15 21:09:32Z mike $"
+ * End of "$Id: testi18n.c 5444 2006-04-20 18:16:54Z mike $"
*/
diff --git a/doc/Makefile b/doc/Makefile
index 5562d2a8b8..e5d8b85712 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile 5328 2006-03-23 20:23:19Z mike $"
+# "$Id: Makefile 5428 2006-04-18 20:45:30Z mike $"
#
# Documentation makefile for the Common UNIX Printing System (CUPS).
#
@@ -160,6 +160,7 @@ HELPFILES = \
help/ref-error_log.html \
help/ref-page_log.html \
help/ref-printers-conf.html \
+ help/ref-snmp-conf.html \
help/ref-subscriptions-conf.html \
help/security.html \
help/spec-cmp.html \
diff --git a/doc/help/api-ppd.html b/doc/help/api-ppd.html
index 139169bd75..a3949abeab 100644
--- a/doc/help/api-ppd.html
+++ b/doc/help/api-ppd.html
@@ -189,14 +189,19 @@ library:
ppdErrorString() CUPS 1.1.19
ppdFindAttr() CUPS 1.1.19
ppdFindChoice()
+ ppdFindCustomOption() CUPS 1.2
+ ppdFindCustomParam() CUPS 1.2
ppdFindMarkedChoice()
ppdFindNextAttr() CUPS 1.1.19
ppdFindOption()
+ ppdFirstCustomParam() CUPS 1.2
ppdFirstOption() CUPS 1.2
ppdIsMarked()
ppdLastError() CUPS 1.1.19
+ ppdLocalize() CUPS 1.2
ppdMarkDefaults()
ppdMarkOption()
+ ppdNextCustomParam() CUPS 1.2
ppdNextOption() CUPS 1.2
ppdOpen()
ppdOpen2() CUPS 1.2
@@ -515,6 +520,50 @@ ppdFindChoice(
Returns
Choice pointer or NULL
+
+Description
+Find a custom option.
+
+
+Syntax
+
+ppd_coption_t *
+ppdFindCustomOption(
+ ppd_file_t * ppd,
+ const char * keyword);
+
+Arguments
+
+| Name | Description |
+
+| ppd | PPD file |
+| keyword | Custom option name |
+
+Returns
+Custom option or NULL
+
+
+Description
+Find a parameter for a custom option.
+
+
+Syntax
+
+ppd_cparam_t *
+ppdFindCustomParam(
+ ppd_coption_t * opt,
+ const char * name);
+
+Arguments
+
+| Name | Description |
+
+| opt | Custom option |
+| name | Parameter name |
+
+Returns
+Custom parameter or NULL
+
Description
Return the marked choice for the specified option.
@@ -579,6 +628,26 @@ ppdFindOption(
Returns
Pointer to option or NULL
+
+Description
+Return the first parameter for a custom option.
+
+
+Syntax
+
+ppd_cparam_t *
+ppdFirstCustomParam(
+ ppd_coption_t * opt);
+
+Arguments
+
+| Name | Description |
+
+| opt | Custom option |
+
+Returns
+Custom parameter or NULL
+
Description
Return the first option in the PPD file.
@@ -643,6 +712,26 @@ ppdLastError(
Returns
Status code
+
+Description
+Localize the PPD file to the current locale.
+
+
+Syntax
+
+int
+ppdLocalize(
+ ppd_file_t * ppd);
+
+Arguments
+
+| Name | Description |
+
+| ppd | PPD file |
+
+Returns
+0 on success, -1 on error
+
Description
Mark all default options in the PPD file.
@@ -688,6 +777,26 @@ ppdMarkOption(
Returns
Number of conflicts
+
+Description
+Return the next parameter for a custom option.
+
+
+Syntax
+
+ppd_cparam_t *
+ppdNextCustomParam(
+ ppd_coption_t * opt);
+
+Arguments
+
+| Name | Description |
+
+| opt | Custom option |
+
+Returns
+Custom parameter or NULL
+
Description
Return the next option in the PPD file.
diff --git a/doc/help/ref-client-conf.html b/doc/help/ref-client-conf.html
index 762edf2657..20eac96294 100644
--- a/doc/help/ref-client-conf.html
+++ b/doc/help/ref-client-conf.html
@@ -5,58 +5,49 @@
-The /etc/cups/client.conf file contains many
-directives that determine how the client behaves:
+The /etc/cups/client.conf and
+~/.cups/client.conf files contain up to two directives
+that determine how the client behaves. Each directive is listed
+on a line by itself followed by its value. Comments are
+introduced using the number sign ("#") character at the beginning
+of a line.
-
-
-
-
-
-
-
-
-Examples
-
-
+
Encryption Never
Encryption IfRequested
Encryption Required
Encryption Always
-
+
+
+Description
-Description
+The Encryption directive specifies the default
+encryption settings for the client.
-The Encryption directive specifies the default encryption settings for the client.
-The default setting is IfRequested.
+
The default setting is IfRequested.
-
-
-
+
-Examples
+Examples
-
+
ServerName foo.bar.com
ServerName 11.22.33.44
-
+
-Description
+Description
-The ServerName directive specifies sets the remote server that is to be used
-for all client operations. That is, it redirects all client requests to the remote server.
+
The ServerName directive specifies sets the
+remote server that is to be used for all client operations. That
+is, it redirects all client requests to the remote server.
-The default is to use the local server ("localhost").
+The default is to use the local server
+("localhost") or domain socket, if so configured.