#
-# "$Id: Makefile 5044 2006-02-01 21:35:30Z mike $"
+# "$Id: Makefile 5047 2006-02-02 05:14:15Z mike $"
#
# Backend makefile for the Common UNIX Printing System (CUPS).
#
test1284: test1284.o ../cups/libcups.a
echo Linking $@...
- $(CC) $(LDFLAGS) -o test1284 test1284.o ../cups/libcups.a
+ $(CC) $(LDFLAGS) -o test1284 test1284.o ../cups/libcups.a \
+ $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
#
#
-# End of "$Id: Makefile 5044 2006-02-01 21:35:30Z mike $".
+# End of "$Id: Makefile 5047 2006-02-02 05:14:15Z mike $".
#
/*
- * "$Id: admin.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: admin.c 5057 2006-02-02 20:38:29Z mike $"
*
* Administration CGI for the Common UNIX Printing System (CUPS).
*
}
else
{
- cgiCopyTemplateLang("samba-exported");
+ cgiCopyTemplateLang("samba-exported.tmpl");
cgiEndHTML();
return;
}
* rpcclient...
*/
- if (cupsFileFind("smbclient", getenv("PATH"), line, sizeof(line)) &&
- cupsFileFind("rpcclient", getenv("PATH"), line, sizeof(line)))
+ if (cupsFileFind("smbclient", getenv("PATH"), 1, line, sizeof(line)) &&
+ cupsFileFind("rpcclient", getenv("PATH"), 1, line, sizeof(line)))
cgiSetVariable("HAVE_SAMBA", "Y");
else
{
- if (!cupsFileFind("smbclient", getenv("PATH"), line, sizeof(line)))
+ if (!cupsFileFind("smbclient", getenv("PATH"), 1, line, sizeof(line)))
fputs("ERROR: smbclient not found!\n", stderr);
- if (!cupsFileFind("rpcclient", getenv("PATH"), line, sizeof(line)))
+ if (!cupsFileFind("rpcclient", getenv("PATH"), 1, line, sizeof(line)))
fputs("ERROR: rpcclient not found!\n", stderr);
}
}
/*
- * End of "$Id: admin.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: admin.c 5057 2006-02-02 20:38:29Z mike $".
*/
/*
- * "$Id: file.c 5026 2006-01-30 21:59:02Z mike $"
+ * "$Id: file.c 5057 2006-02-02 20:38:29Z mike $"
*
* File functions for the Common UNIX Printing System (CUPS).
*
const char * /* O - Full path to file or NULL */
cupsFileFind(const char *filename, /* I - File to find */
const char *path, /* I - Colon/semicolon-separated path */
- char *buffer, /* I - Filename buffer */
+ int executable, /* I - 1 = executable files, 0 = any file/dir */
+ char *buffer, /* I - Filename buffer */
int bufsize) /* I - Size of filename buffer */
{
char *bufptr, /* Current position in buffer */
strlcpy(bufptr, filename, bufend - bufptr);
+#ifdef WIN32
if (!access(buffer, 0))
+#else
+ if (!access(buffer, executable ? X_OK : 0))
+#endif /* WIN32 */
return (buffer);
bufptr = buffer;
/*
- * End of "$Id: file.c 5026 2006-01-30 21:59:02Z mike $".
+ * End of "$Id: file.c 5057 2006-02-02 20:38:29Z mike $".
*/
/*
- * "$Id: file.h 4933 2006-01-16 00:26:57Z mike $"
+ * "$Id: file.h 5057 2006-02-02 20:38:29Z mike $"
*
* Public file definitions for the Common UNIX Printing System (CUPS).
*
extern int cupsFileCompression(cups_file_t *fp);
extern int cupsFileEOF(cups_file_t *fp);
extern const char *cupsFileFind(const char *filename, const char *path,
- char *buffer, int bufsize);
+ int executable, char *buffer,
+ int bufsize);
extern int cupsFileFlush(cups_file_t *fp);
extern int cupsFileGetChar(cups_file_t *fp);
extern char *cupsFileGetConf(cups_file_t *fp, char *buf, size_t buflen,
#endif /* !_CUPS_FILE_H_ */
/*
- * End of "$Id: file.h 4933 2006-01-16 00:26:57Z mike $".
+ * End of "$Id: file.h 5057 2006-02-02 20:38:29Z mike $".
*/
/*
- * "$Id: globals.c 4967 2006-01-24 03:42:15Z mike $"
+ * "$Id: globals.c 5047 2006-02-02 05:14:15Z mike $"
*
* Global variable access routines for the Common UNIX Printing System (CUPS).
*
if (cg->http)
httpClose(cg->http);
+ _cups_sp_flush(cg);
_cupsLangFlush(cg);
_cupsCharmapFlush(cg);
_cupsNormalizeMapsFlush(cg);
/*
- * End of "$Id: globals.c 4967 2006-01-24 03:42:15Z mike $".
+ * End of "$Id: globals.c 5047 2006-02-02 05:14:15Z mike $".
*/
/*
- * "$Id: globals.h 4967 2006-01-24 03:42:15Z mike $"
+ * "$Id: globals.h 5047 2006-02-02 05:14:15Z mike $"
*
* Global variable definitions for the Common UNIX Printing System (CUPS).
*
/* Default printer */
char ppd_filename[HTTP_MAX_URI];
/* PPD filename */
+
+ /* string.c */
+ cups_array_t *stringpool; /* String pool */
} _cups_globals_t;
extern void _cupsLangFlush(_cups_globals_t *cg);
extern void _cupsCharmapFlush(_cups_globals_t *cg);
extern void _cupsNormalizeMapsFlush(_cups_globals_t *cg);
+extern void _cups_sp_flush(_cups_globals_t *cg);
/*
#endif /* !_CUPS_GLOBALS_H_ */
/*
- * End of "$Id: globals.h 4967 2006-01-24 03:42:15Z mike $".
+ * End of "$Id: globals.h 5047 2006-02-02 05:14:15Z mike $".
*/
/*
- * "$Id: http-private.h 4973 2006-01-25 02:36:02Z mike $"
+ * "$Id: http-private.h 5049 2006-02-02 14:50:57Z mike $"
*
* Private HTTP definitions for the Common UNIX Printing System (CUPS).
*
# define closesocket(f) close(f)
# endif /* WIN32 */
-# ifdef __sgi
+# if defined(__sgi) || (defined(__APPLE__) && !defined(_SOCKLEN_T))
/*
- * IRIX does not define socklen_t, and in fact uses an int instead of
+ * IRIX and MacOS X 10.2.x do not define socklen_t, and in fact use an int instead of
* unsigned type for length values...
*/
typedef int socklen_t;
-# endif /* __sgi */
+# endif /* __sgi || (__APPLE__ && !_SOCKLEN_T) */
# include "http.h"
# include "ipp-private.h"
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
/*
- * End of "$Id: http-private.h 4973 2006-01-25 02:36:02Z mike $".
+ * End of "$Id: http-private.h 5049 2006-02-02 14:50:57Z mike $".
*/
/*
- * "$Id: ipp.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: ipp.c 5047 2006-02-02 05:14:15Z mike $"
*
* Internet Printing Protocol support functions for the Common UNIX
* Printing System (CUPS).
if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_BOOLEAN;
attr->values[0].boolean = value;
if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_BOOLEAN;
if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_BEGIN_COLLECTION;
attr->values[0].collection = value;
if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_BEGIN_COLLECTION;
if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_DATE;
memcpy(attr->values[0].date, value, 11);
if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = type;
attr->values[0].integer = value;
if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = type;
* Initialize the attribute data...
*/
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_STRING;
attr->values[0].unknown.length = datalen;
const char *value) /* I - Value */
{
ipp_attribute_t *attr; /* New attribute */
+ char buffer[1024], /* Language/charset value buffer */
+ *bufptr; /* Pointer into buffer */
if (ipp == NULL || name == NULL)
* Force value to be English for the POSIX locale...
*/
- if (type == IPP_TAG_LANGUAGE && strcasecmp(value, "C") == 0)
+ if (type == IPP_TAG_LANGUAGE && !strcasecmp(value, "C"))
value = "en";
- /*
- * Initialize the attribute data...
- */
-
- attr->name = strdup(name);
- attr->group_tag = group;
- attr->value_tag = type;
- attr->values[0].string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset :
- charset ? strdup(charset) : NULL;
- attr->values[0].string.text = ((int)type & IPP_TAG_COPY) ? (char *)value :
- value ? strdup(value) : NULL;
-
/*
* Convert language values to lowercase and change _ to - as needed...
*/
- if ((type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) &&
- attr->values[0].string.text)
+ if ((type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) && value)
{
- char *p;
-
+ strlcpy(buffer, value, sizeof(buffer));
+ value = buffer;
- for (p = attr->values[0].string.text; *p; p ++)
- if (*p == '_')
- *p = '-';
+ for (bufptr = buffer; *bufptr; bufptr ++)
+ if (*bufptr == '_')
+ *bufptr = '-';
else
- *p = tolower(*p & 255);
+ *bufptr = tolower(*bufptr & 255);
}
+ /*
+ * Initialize the attribute data...
+ */
+
+ attr->name = _cups_sp_alloc(name);
+ attr->group_tag = group;
+ attr->value_tag = type;
+ attr->values[0].string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset :
+ charset ? _cups_sp_alloc(charset) : NULL;
+ attr->values[0].string.text = ((int)type & IPP_TAG_COPY) ? (char *)value :
+ value ? _cups_sp_alloc(value) : NULL;
+
return (attr);
}
* Initialize the attribute data...
*/
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = type;
{
if (i == 0)
value->string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset :
- charset ? strdup(charset) : NULL;
+ charset ? _cups_sp_alloc(charset) : NULL;
else
value->string.charset = attr->values[0].string.charset;
* Force language to be English for the POSIX locale...
*/
- if (type == IPP_TAG_LANGUAGE && strcasecmp(values[i], "C") == 0)
+ if (type == IPP_TAG_LANGUAGE && !strcasecmp(values[i], "C"))
value->string.text = ((int)type & IPP_TAG_COPY) ? "en" :
- strdup("en");
+ _cups_sp_alloc("en");
else
value->string.text = ((int)type & IPP_TAG_COPY) ? (char *)values[i] :
- strdup(values[i]);
+ _cups_sp_alloc(values[i]);
}
}
if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_RANGE;
attr->values[0].range.lower = lower;
if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_RANGE;
if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_RESOLUTION;
attr->values[0].resolution.xres = xres;
if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
return (NULL);
- attr->name = strdup(name);
+ attr->name = _cups_sp_alloc(name);
attr->group_tag = group;
attr->value_tag = IPP_TAG_RESOLUTION;
/*
* 'ippReadIO()' - Read data for an IPP message.
*
- * @since CUPS 1.1.19@
+ * @since CUPS 1.2@
*/
ipp_state_t /* O - Current state */
{
int n; /* Length of data */
unsigned char buffer[32768], /* Data buffer */
+ string[255], /* Small string buffer */
*bufptr; /* Pointer into buffer */
ipp_attribute_t *attr; /* Current attribute */
ipp_tag_t tag; /* Current tag */
attr->group_tag = ipp->curtag;
attr->value_tag = tag;
- attr->name = strdup((char *)buffer);
+ attr->name = _cups_sp_alloc((char *)buffer);
attr->num_values = 0;
}
else
case IPP_TAG_CHARSET :
case IPP_TAG_LANGUAGE :
case IPP_TAG_MIMETYPE :
- value->string.text = calloc(n + 1, 1);
-
- if ((*cb)(src, (ipp_uchar_t *)value->string.text, n) < n)
+ if ((*cb)(src, buffer, n) < n)
{
- DEBUG_puts("ippReadIO: Unable to read string value!");
+ DEBUG_puts("ippReadIO: unable to read name!");
return (IPP_ERROR);
}
+ buffer[n] = '\0';
+ value->string.text = _cups_sp_alloc((char *)buffer);
DEBUG_printf(("ippReadIO: value = \'%s\'\n",
value->string.text));
break;
n = (bufptr[0] << 8) | bufptr[1];
- value->string.charset = calloc(n + 1, 1);
+ if (n >= sizeof(string))
+ {
+ memcpy(string, bufptr + 2, sizeof(string) - 1);
+ string[sizeof(string) - 1] = '\0';
+ }
+ else
+ {
+ memcpy(string, bufptr + 2, n);
+ string[n] = '\0';
+ }
- memcpy(value->string.charset,
- bufptr + 2, n);
+ value->string.charset = _cups_sp_alloc((char *)string);
bufptr += 2 + n;
n = (bufptr[0] << 8) | bufptr[1];
- value->string.text = calloc(n + 1, 1);
-
- memcpy(value->string.text,
- bufptr + 2, n);
+ bufptr[2 + n] = '\0';
+ value->string.text = _cups_sp_alloc((char *)bufptr + 2);
break;
case IPP_TAG_BEGIN_COLLECTION :
case IPP_TAG_MEMBERNAME :
/*
- * The value is the name of the member in the collection,
- * which we need to carry over...
+ * The value the name of the member in the collection, which
+ * we need to carry over...
*/
- attr->name = calloc(n + 1, 1);
-
- if ((*cb)(src, (ipp_uchar_t *)attr->name, n) < n)
+ if ((*cb)(src, buffer, n) < n)
{
DEBUG_puts("ippReadIO: Unable to read member name value!");
return (IPP_ERROR);
}
+ buffer[n] = '\0';
+ attr->name = _cups_sp_alloc((char *)buffer);
+
/*
* Since collection members are encoded differently than
* regular attributes, make sure we don't start with an
/*
* 'ippWriteIO()' - Write data for an IPP message.
*
- * @since CUPS 1.1.19@
+ * @since CUPS 1.2@
*/
ipp_state_t /* O - Current state */
for (i = 0, value = attr->values;
i < attr->num_values;
i ++, value ++)
- free(value->string.text);
+ _cups_sp_free(value->string.text);
break;
case IPP_TAG_TEXTLANG :
i ++, value ++)
{
if (value->string.charset && i == 0)
- free(value->string.charset);
- free(value->string.text);
+ _cups_sp_free(value->string.charset);
+ _cups_sp_free(value->string.text);
}
break;
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ case IPP_TAG_BOOLEAN :
+ case IPP_TAG_DATE :
+ case IPP_TAG_RESOLUTION :
+ case IPP_TAG_RANGE :
+ break;
+
+ case IPP_TAG_BEGIN_COLLECTION :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ ippDelete(value->collection);
+ break;
+
default :
- break; /* anti-compiler-warning-code */
+ if (!((int)attr->value_tag & IPP_TAG_COPY))
+ {
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ if (value->unknown.data)
+ free(value->unknown.data);
+ }
+ break;
}
if (attr->name)
- free(attr->name);
+ _cups_sp_free(attr->name);
free(attr);
}
for (i = 0, value = attr->values;
i < attr->num_values;
i ++, value ++)
- bytes += ipp_length(attr->values[i].collection, 1);
+ bytes += ipp_length(value->collection, 1);
break;
default :
for (i = 0, value = attr->values;
i < attr->num_values;
i ++, value ++)
- bytes += attr->values[0].unknown.length;
+ bytes += value->unknown.length;
break;
}
}
/*
- * End of "$Id: ipp.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: ipp.c 5047 2006-02-02 05:14:15Z mike $".
*/
/*
- * "$Id: string.c 4683 2005-09-21 22:17:44Z mike $"
+ * "$Id: string.c 5047 2006-02-02 05:14:15Z mike $"
*
* String functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Easy Software Products and are protected by Federal
*
* Contents:
*
- * _cups_strcpy() - Copy a string allowing for overlapping strings.
- * _cups_strdup() - Duplicate a string.
- * _cups_strcasecmp() - Do a case-insensitive comparison.
- * _cups_strncasecmp() - Do a case-insensitive comparison on up to N chars.
- * _cups_strlcat() - Safely concatenate two strings.
- * _cups_strlcpy() - Safely copy two strings.
+ * _cups_sp_alloc() - Allocate/reference a string.
+ * _cups_sp_flush() - Flush the string pool...
+ * _cups_sp_free() - Free/dereference a string.
+ * _cups_sp_statistics() - Return allocation statistics for string pool.
+ * _cups_strcpy() - Copy a string allowing for overlapping strings.
+ * _cups_strdup() - Duplicate a string.
+ * _cups_strcasecmp() - Do a case-insensitive comparison.
+ * _cups_strncasecmp() - Do a case-insensitive comparison on up to N chars.
+ * _cups_strlcat() - Safely concatenate two strings.
+ * _cups_strlcpy() - Safely copy two strings.
+ * compare_sp_items() - Compare two string pool items...
*/
/*
* Include necessary headers...
*/
+#include <stdlib.h>
+#include <limits.h>
+#include "debug.h"
#include "string.h"
+#include "globals.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_sp_items(_cups_sp_item_t *a, _cups_sp_item_t *b);
+
+
+/*
+ * '_cups_sp_alloc()' - Allocate/reference a string.
+ */
+
+char * /* O - String pointer */
+_cups_sp_alloc(const char *s) /* I - String */
+{
+ _cups_globals_t *cg; /* Global data */
+ _cups_sp_item_t *item, /* String pool item */
+ key; /* Search key */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!s)
+ return (NULL);
+
+ /*
+ * Get the string pool...
+ */
+
+ cg = _cupsGlobals();
+
+ if (!cg->stringpool)
+ cg->stringpool = cupsArrayNew((cups_array_func_t)compare_sp_items, NULL);
+
+ if (!cg->stringpool)
+ return (NULL);
+
+ /*
+ * See if the string is already in the pool...
+ */
+
+ key.str = (char *)s;
+
+ if ((item = (_cups_sp_item_t *)cupsArrayFind(cg->stringpool, &key)) != NULL)
+ {
+ /*
+ * Found it, return the cached string...
+ */
+
+ item->ref_count ++;
+
+ return (item->str);
+ }
+
+ /*
+ * Not found, so allocate a new one...
+ */
+
+ item = (_cups_sp_item_t *)calloc(1, sizeof(_cups_sp_item_t));
+ if (!item)
+ return (NULL);
+
+ item->ref_count = 1;
+ item->str = strdup(s);
+
+ if (!item->str)
+ {
+ free(item);
+ return (NULL);
+ }
+
+ /*
+ * Add the string to the pool and return it...
+ */
+
+ cupsArrayAdd(cg->stringpool, item);
+
+ return (item->str);
+}
+
+
+/*
+ * '_cups_sp_flush()' - Flush the string pool...
+ */
+
+void
+_cups_sp_flush(_cups_globals_t *cg) /* I - Global data */
+{
+ _cups_sp_item_t *item; /* Current item */
+
+
+ for (item = (_cups_sp_item_t *)cupsArrayFirst(cg->stringpool);
+ item;
+ item = (_cups_sp_item_t *)cupsArrayNext(cg->stringpool))
+ {
+ free(item->str);
+ free(item);
+ }
+
+ cupsArrayDelete(cg->stringpool);
+}
+
+
+/*
+ * '_cups_sp_free()' - Free/dereference a string.
+ */
+
+void
+_cups_sp_free(const char *s)
+{
+ _cups_globals_t *cg; /* Global data */
+ _cups_sp_item_t *item, /* String pool item */
+ key; /* Search key */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!s)
+ return;
+
+ /*
+ * Get the string pool...
+ */
+
+ cg = _cupsGlobals();
+
+ if (!cg->stringpool)
+ return;
+
+ /*
+ * See if the string is already in the pool...
+ */
+
+ key.str = (char *)s;
+
+ if ((item = (_cups_sp_item_t *)cupsArrayFind(cg->stringpool, &key)) != NULL)
+ {
+ /*
+ * Found it, dereference...
+ */
+
+ item->ref_count --;
+
+ if (!item->ref_count)
+ {
+ /*
+ * Remove and free...
+ */
+
+ cupsArrayRemove(cg->stringpool, item);
+
+ free(item->str);
+ free(item);
+ }
+ }
+}
+
+
+/*
+ * '_cups_sp_statistics()' - Return allocation statistics for string pool.
+ */
+
+size_t /* O - Number of strings */
+_cups_sp_statistics(size_t *alloc_bytes,/* O - Allocated bytes */
+ size_t *total_bytes)/* O - Total string bytes */
+{
+ size_t count, /* Number of strings */
+ abytes, /* Allocated string bytes */
+ tbytes, /* Total string bytes */
+ len; /* Length of string */
+ _cups_sp_item_t *item; /* Current item */
+ _cups_globals_t *cg; /* Global data */
+
+
+ /*
+ * Loop through strings in pool, counting everything up...
+ */
+
+ cg = _cupsGlobals();
+
+ for (count = 0, abytes = 0, tbytes = 0,
+ item = (_cups_sp_item_t *)cupsArrayFirst(cg->stringpool);
+ item;
+ item = (_cups_sp_item_t *)cupsArrayNext(cg->stringpool))
+ {
+ /*
+ * Count allocated memory, using a 64-bit aligned buffer as a basis.
+ */
+
+ count += item->ref_count;
+ len = (strlen(item->str) + 8) & ~7;
+ abytes += sizeof(_cups_sp_item_t) + len;
+ tbytes += item->ref_count * len;
+ }
+
+ /*
+ * Return values...
+ */
+
+ if (alloc_bytes)
+ *alloc_bytes = abytes;
+
+ if (total_bytes)
+ *total_bytes = tbytes;
+
+ return (count);
+}
/*
/*
- * End of "$Id: string.c 4683 2005-09-21 22:17:44Z mike $".
+ * 'compare_sp_items()' - Compare two string pool items...
+ */
+
+static int /* O - Result of comparison */
+compare_sp_items(_cups_sp_item_t *a, /* I - First item */
+ _cups_sp_item_t *b) /* I - Second item */
+{
+ return (strcmp(a->str, b->str));
+}
+
+
+/*
+ * End of "$Id: string.c 5047 2006-02-02 05:14:15Z mike $".
*/
/*
- * "$Id: string.h 4683 2005-09-21 22:17:44Z mike $"
+ * "$Id: string.h 5047 2006-02-02 05:14:15Z mike $"
*
* String definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Easy Software Products and are protected by Federal
# endif /* __cplusplus */
+/*
+ * String pool structures...
+ */
+
+typedef struct _cups_sp_item_s /**** String Pool Item ****/
+{
+ char *str; /* String */
+ unsigned int ref_count; /* Reference count */
+} _cups_sp_item_t;
+
+
/*
* Prototypes...
*/
# define vsnprintf _cups_vsnprintf
# endif /* !HAVE_VSNPRINTF */
+/*
+ * String pool functions...
+ */
+
+extern char *_cups_sp_alloc(const char *s);
+extern void _cups_sp_free(const char *s);
+extern size_t _cups_sp_statistics(size_t *alloc_bytes, size_t *total_bytes);
+
/*
* C++ magic...
#endif /* !_CUPS_STRING_H_ */
/*
- * End of "$Id: string.h 4683 2005-09-21 22:17:44Z mike $".
+ * End of "$Id: string.h 5047 2006-02-02 05:14:15Z mike $".
*/
/*
- * "$Id: testfile.c 4942 2006-01-18 19:49:15Z mike $"
+ * "$Id: testfile.c 5057 2006-02-02 20:38:29Z mike $"
*
* File test program for the Common UNIX Printing System (CUPS).
*
*/
fputs("cupsFileFind: ", stdout);
- if (cupsFileFind("cat", "/bin", filename, sizeof(filename)) &&
- cupsFileFind("cat", "/bin:/usr/bin", filename, sizeof(filename)))
+ if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) &&
+ cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename)))
printf("PASS (%s)\n", filename);
else
{
/*
- * End of "$Id: testfile.c 4942 2006-01-18 19:49:15Z mike $".
+ * End of "$Id: testfile.c 5057 2006-02-02 20:38:29Z mike $".
*/
#
-# "$Id: Makefile 5020 2006-01-28 13:36:15Z mike $"
+# "$Id: Makefile 5054 2006-02-02 18:16:27Z mike $"
#
# Documentation makefile for the Common UNIX Printing System (CUPS).
#
images/delete-printer.gif \
images/edit-configuration-file.gif \
images/esp-logo.gif \
+ images/export-samba.gif \
images/happy.gif \
images/help.gif \
images/hold-job.gif \
/usr/lib/cups/backend/parallel
/usr/lib/cups/backend/scsi
/usr/lib/cups/backend/serial
+/usr/lib/cups/backend/socket
/usr/lib/cups/backend/usb
%dir /usr/lib/cups/cgi-bin
/usr/lib/cups/cgi-bin/*
/*
- * "$Id: banners.c 4968 2006-01-24 03:56:31Z mike $"
+ * "$Id: banners.c 5051 2006-02-02 16:13:16Z mike $"
*
* Banner routines for the Common UNIX Printing System (CUPS).
*
* See what the filetype is...
*/
- if ((filetype = mimeFileType(MimeDatabase, filename, NULL)) == NULL)
+ if ((filetype = mimeFileType(MimeDatabase, filename, NULL, NULL)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_WARN,
"cupsdAddBanner: Banner \"%s\" (\"%s\") is of an unknown file type - skipping!",
/*
- * End of "$Id: banners.c 4968 2006-01-24 03:56:31Z mike $".
+ * End of "$Id: banners.c 5051 2006-02-02 16:13:16Z mike $".
*/
/*
- * "$Id: client.c 5046 2006-02-01 22:11:58Z mike $"
+ * "$Id: client.c 5051 2006-02-02 16:13:16Z mike $"
*
* Client routines for the Common UNIX Printing System (CUPS) scheduler.
*
cupsdLogMessage(CUPSD_LOG_ERROR,
"EncryptClient: Could not find signing key in keychain "
"\"%s\"", ServerCertificate);
- error = errSSLBadConfiguration;
+ error = errSSLBadCert; /* errSSLBadConfiguration is a better choice, but not available on 10.2.x */
}
if (!error)
break;
}
- type = mimeFileType(MimeDatabase, filename, NULL);
+ type = mimeFileType(MimeDatabase, filename, NULL, NULL);
if (cupsdIsCGI(con, filename, &filestats, type))
{
break;
}
- type = mimeFileType(MimeDatabase, filename, NULL);
+ type = mimeFileType(MimeDatabase, filename, NULL, NULL);
if (!cupsdIsCGI(con, filename, &filestats, type))
{
* Serve a file...
*/
- type = mimeFileType(MimeDatabase, filename, NULL);
+ type = mimeFileType(MimeDatabase, filename, NULL, NULL);
if (type == NULL)
strcpy(line, "text/plain");
else
/*
- * End of "$Id: client.c 5046 2006-02-01 22:11:58Z mike $".
+ * End of "$Id: client.c 5051 2006-02-02 16:13:16Z mike $".
*/
/*
- * "$Id: cups-lpd.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: cups-lpd.c 5049 2006-02-02 14:50:57Z mike $"
*
* Line Printer Daemon interface for the Common UNIX Printing System (CUPS).
*
* Include necessary headers...
*/
+#include <cups/http-private.h>
#include <cups/cups.h>
#include <cups/string.h>
#include <cups/language.h>
/*
- * End of "$Id: cups-lpd.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: cups-lpd.c 5049 2006-02-02 14:50:57Z mike $".
*/
/*
- * "$Id: cupsd.h 5046 2006-02-01 22:11:58Z mike $"
+ * "$Id: cupsd.h 5053 2006-02-02 18:14:38Z mike $"
*
* Main header file for the Common UNIX Printing System (CUPS) scheduler.
*
/* Time of reload request... */
VAR int NeedReload VALUE(RELOAD_ALL);
/* Need to load configuration? */
+#ifdef HAVE_LAUNCH_H
+VAR int Launchd VALUE(0);
+ /* Running from launchd */
+#endif /* HAVE_LAUNCH_H */
/*
/*
- * End of "$Id: cupsd.h 5046 2006-02-01 22:11:58Z mike $".
+ * End of "$Id: cupsd.h 5053 2006-02-02 18:14:38Z mike $".
*/
/*
- * "$Id: dirsvc.c 5043 2006-02-01 18:55:16Z mike $"
+ * "$Id: dirsvc.c 5059 2006-02-02 23:17:16Z mike $"
*
* Directory services routines for the Common UNIX Printing System (CUPS).
*
else if (!strcasecmp(line, "DeviceURI"))
{
if (value)
+ {
+ cupsdSetString(&p->uri, value);
cupsdSetString(&p->device_uri, value);
+ }
else
{
cupsdLogMessage(CUPSD_LOG_ERROR,
/*
- * End of "$Id: dirsvc.c 5043 2006-02-01 18:55:16Z mike $".
+ * End of "$Id: dirsvc.c 5059 2006-02-02 23:17:16Z mike $".
*/
/*
- * "$Id: ipp.c 5046 2006-02-01 22:11:58Z mike $"
+ * "$Id: ipp.c 5051 2006-02-02 16:13:16Z mike $"
*
* IPP routines for the Common UNIX Printing System (CUPS) scheduler.
*
* Remote unauthenticated user masquerading as local root...
*/
- cupsdSetString(&(username->values[0].string.text), RemoteRoot);
+ _cups_sp_free(username->values[0].string.text);
+ username->values[0].string.text = _cups_sp_alloc(RemoteRoot);
}
}
else
{
for (i = 0; i < attr->num_values; i ++)
- toattr->values[i].string.text = strdup(attr->values[i].string.text);
+ toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text);
}
break;
{
if (!i)
toattr->values[i].string.charset =
- strdup(attr->values[i].string.charset);
+ _cups_sp_alloc(attr->values[i].string.charset);
else
toattr->values[i].string.charset =
toattr->values[0].string.charset;
- toattr->values[i].string.text = strdup(attr->values[i].string.text);
+ toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text);
}
}
break;
for (i = 0; i < attr->num_values; i ++)
{
- free(attr->values[i].string.text);
+ _cups_sp_free(attr->values[i].string.text);
attr->values[i].string.text = NULL;
if (attr->values[i].string.charset)
{
- free(attr->values[i].string.charset);
+ _cups_sp_free(attr->values[i].string.charset);
attr->values[i].string.charset = NULL;
}
}
attr->value_tag = IPP_TAG_NAME;
attr->num_values = 1;
- attr->values[0].string.text = strdup(con->http.hostname);
+ attr->values[0].string.text = _cups_sp_alloc(con->http.hostname);
}
attr->group_tag = IPP_TAG_JOB;
attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
2, NULL, NULL);
- attr->values[0].string.text = strdup(printer->job_sheets[0]);
- attr->values[1].string.text = strdup(printer->job_sheets[1]);
+ attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]);
+ attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]);
}
job->job_sheets = attr;
* Free the old hold value and copy the new one over...
*/
- free(attr->values[0].string.text);
+ _cups_sp_free(attr->values[0].string.text);
if (newattr)
{
attr->value_tag = newattr->value_tag;
- attr->values[0].string.text = strdup(newattr->values[0].string.text);
+ attr->values[0].string.text =
+ _cups_sp_alloc(newattr->values[0].string.text);
}
else
{
attr->value_tag = IPP_TAG_KEYWORD;
- attr->values[0].string.text = strdup("indefinite");
+ attr->values[0].string.text = _cups_sp_alloc("indefinite");
}
/*
cupsdSetJobHoldUntil(job, attr->values[0].string.text);
}
- cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was held by \"%s\".", jobid, username);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was held by \"%s\".", jobid,
+ username);
con->response->request.status.status_code = IPP_OK;
}
cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: auto-typing file...");
- filetype = mimeFileType(MimeDatabase, con->filename, &compression);
+ filetype = mimeFileType(MimeDatabase, con->filename, NULL, &compression);
if (filetype)
{
if (format)
{
- free(format->values[0].string.text);
- format->values[0].string.text = strdup(mimetype);
+ _cups_sp_free(format->values[0].string.text);
+
+ format->values[0].string.text = _cups_sp_alloc(mimetype);
}
else
ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
for (i = 0; i < attr->num_values; i ++)
{
- free(attr->values[i].string.text);
+ _cups_sp_free(attr->values[i].string.text);
attr->values[i].string.text = NULL;
if (attr->values[i].string.charset)
{
- free(attr->values[i].string.charset);
+ _cups_sp_free(attr->values[i].string.charset);
attr->values[i].string.charset = NULL;
}
}
attr->value_tag = IPP_TAG_NAME;
attr->num_values = 1;
- attr->values[0].string.text = strdup(con->http.hostname);
+ attr->values[0].string.text = _cups_sp_alloc(con->http.hostname);
}
attr->group_tag = IPP_TAG_JOB;
attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
2, NULL, NULL);
- attr->values[0].string.text = strdup(printer->job_sheets[0]);
- attr->values[1].string.text = strdup(printer->job_sheets[1]);
+ attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]);
+ attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]);
}
job->job_sheets = attr;
if (attr)
{
- free(attr->values[0].string.text);
+ _cups_sp_free(attr->values[0].string.text);
+
attr->value_tag = IPP_TAG_KEYWORD;
- attr->values[0].string.text = strdup("no-hold");
+ attr->values[0].string.text = _cups_sp_alloc("no-hold");
}
/*
cupsdLogMessage(CUPSD_LOG_DEBUG, "send_document: auto-typing file...");
- filetype = mimeFileType(MimeDatabase, con->filename, &compression);
+ filetype = mimeFileType(MimeDatabase, con->filename, NULL, &compression);
if (filetype)
{
if (format)
{
- free(format->values[0].string.text);
- format->values[0].string.text = strdup(mimetype);
+ _cups_sp_free(format->values[0].string.text);
+ format->values[0].string.text = _cups_sp_alloc(mimetype);
}
else
ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
/*
- * End of "$Id: ipp.c 5046 2006-02-01 22:11:58Z mike $".
+ * End of "$Id: ipp.c 5051 2006-02-02 16:13:16Z mike $".
*/
/*
- * "$Id: job.c 5046 2006-02-01 22:11:58Z mike $"
+ * "$Id: job.c 5051 2006-02-02 16:13:16Z mike $"
*
* Job management routines for the Common UNIX Printing System (CUPS).
*
job->num_files = fileid;
}
- job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, filename,
+ job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, filename, NULL,
job->compressions + fileid - 1);
if (job->filetypes[fileid - 1] == NULL)
/*
- * End of "$Id: job.c 5046 2006-02-01 22:11:58Z mike $".
+ * End of "$Id: job.c 5051 2006-02-02 16:13:16Z mike $".
*/
/*
- * "$Id: listen.c 5041 2006-02-01 16:54:50Z mike $"
+ * "$Id: listen.c 5053 2006-02-02 18:14:38Z mike $"
*
* Server listening routines for the Common UNIX Printing System (CUPS)
* scheduler.
*
- * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ * 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
"cupsdStartListening: Listening to %s:%d on fd %d...",
s, p, lis->fd);
else
+ {
cupsdLogMessage(CUPSD_LOG_INFO,
"cupsdStartListening: Listening to %s on fd %d...",
s, lis->fd);
+ if (chmod(s, 0140777))
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "cupsdStartListening: Unable to change permisssions on "
+ "domain socket \"%s\" - %s", s, strerror(errno));
+ }
+
/*
* Save the first port that is bound to the local loopback or
* "any" address...
void
cupsdStopListening(void)
{
- int i; /* Looping var */
+ int i; /* Looping var */
cupsd_listener_t *lis; /* Current listening socket */
#endif /* WIN32 */
#ifdef AF_LOCAL
- /*
- * Remove domain sockets...
- */
+ /*
+ * Remove domain sockets...
+ */
+# ifdef HAVE_LAUNCH_H
+ if (lis->address.addr.sa_family == AF_LOCAL && !Launchd)
+# else
if (lis->address.addr.sa_family == AF_LOCAL)
+# endif /* HAVE_LAUNCH_H */
unlink(lis->address.un.sun_path);
#endif /* AF_LOCAL */
}
/*
- * End of "$Id: listen.c 5041 2006-02-01 16:54:50Z mike $".
+ * End of "$Id: listen.c 5053 2006-02-02 18:14:38Z mike $".
*/
/*
- * "$Id: main.c 5042 2006-02-01 18:17:34Z mike $"
+ * "$Id: main.c 5056 2006-02-02 19:46:32Z mike $"
*
* Scheduler main loop for the Common UNIX Printing System (CUPS).
*
* launchd_reload() - Tell launchd to reload the configuration
* file to pick up the new listening directives.
* launchd_sync_conf() - Re-write the launchd(8) config file
- * com.easysw.cupsd.plist based on cupsd.conf.
+ * org.cups.cupsd.plist based on cupsd.conf.
* parent_handler() - Catch USR1/CHLD signals...
* process_children() - Process all dead children...
* sigchld_handler() - Handle 'child' signals from old processes.
browse_time, /* Next browse send time */
senddoc_time, /* Send-Document time */
expire_time; /* Subscription expire time */
-#ifdef HAVE_MALLINFO
time_t mallinfo_time; /* Malloc information time */
-#endif /* HAVE_MALLINFO */
+ size_t string_count, /* String count */
+ alloc_bytes, /* Allocated string bytes */
+ total_bytes; /* Total string bytes */
struct timeval timeout; /* select() timeout */
struct rlimit limit; /* Runtime limit */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct stat statbuf; /* Needed for checking lpsched FIFO */
#endif /* __sgi */
#if HAVE_LAUNCHD
- int launchd, /* Started with the -l option? */
- launchd_idle_exit;
+ int launchd_idle_exit;
/* Idle exit on select timeout? */
#endif /* HAVE_LAUNCHD */
* Check for command-line arguments...
*/
- fg = 0;
-#if HAVE_LAUNCHD
- launchd = 0;
-#endif /* HAVE_LAUNCHD */
+ fg = 0;
for (i = 1; i < argc; i ++)
if (argv[i][0] == '-')
case 'l' : /* Started by launchd... */
#ifdef HAVE_LAUNCHD
- launchd = 1;
+ Launchd = 1;
fg = 1;
#else
_cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
}
#if HAVE_LAUNCHD
- if (launchd)
+ if (Launchd)
{
/*
* If we were started by launchd make sure the cupsd plist file contains the
* Loop forever...
*/
-#ifdef HAVE_MALLINFO
mallinfo_time = 0;
-#endif /* HAVE_MALLINFO */
browse_time = time(NULL);
senddoc_time = time(NULL);
expire_time = time(NULL);
}
#if HAVE_LAUNCHD
- if (launchd)
+ if (Launchd)
{
if (launchd_sync_conf())
{
* inactivity...
*/
- if (timeout.tv_sec == 86400 && launchd && LaunchdTimeout &&
+ if (timeout.tv_sec == 86400 && Launchd && LaunchdTimeout &&
(!Browsing || !(BrowseLocalProtocols & BROWSE_DNSSD) ||
cupsArrayCount(Printers) == 0))
{
senddoc_time = current_time;
}
-#ifdef HAVE_MALLINFO
/*
* Log memory usage every minute...
*/
if ((current_time - mallinfo_time) >= 60 && LogLevel >= CUPSD_LOG_DEBUG)
{
+#ifdef HAVE_MALLINFO
struct mallinfo mem; /* Malloc information */
"mallinfo: arena = %d, used = %d, free = %d\n",
mem.arena, mem.usmblks + mem.uordblks,
mem.fsmblks + mem.fordblks);
+#endif /* HAVE_MALLINFO */
+
+ string_count = _cups_sp_statistics(&alloc_bytes, &total_bytes);
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "stringpool: " CUPS_LLFMT " strings, "
+ CUPS_LLFMT " allocated, " CUPS_LLFMT " total bytes",
+ CUPS_LLCAST string_count, CUPS_LLCAST alloc_bytes,
+ CUPS_LLCAST total_bytes);
+
mallinfo_time = current_time;
}
-#endif /* HAVE_MALLINFO */
/*
* Update the root certificate once every 5 minutes...
portnum = ntohs(addr.ipv6.sin6_port);
else
# endif /* AF_INET6 */
-# ifdef AF_LOCAL
- if (addr.addr.sa_family == AF_LOCAL)
- {
- /*
- * Make sure the domain socket is accessible to all...
- */
-
- fchmod(lis->fd, 0140777);
- }
- else
-# endif /* AF_LOCAL */
if (addr.addr.sa_family == AF_INET)
portnum = ntohs(addr.ipv4.sin_port);
{
int i, /* Looping var */
portnum; /* Port number */
- CFMutableDictionaryRef cupsd_dict, /* com.easysw.cupsd.plist dictionary */
+ CFMutableDictionaryRef cupsd_dict, /* org.cups.cupsd.plist dictionary */
sockets, /* Sockets dictionary */
listener; /* Listener dictionary */
CFDataRef resourceData; /* XML representation of the property list */
struct servent *service; /* Services data base entry */
char temp[1024]; /* Temporary buffer for value */
struct stat cupsd_sb, /* File info for cupsd.conf */
- launchd_sb; /* File info for com.easysw.cupsd.plist */
+ launchd_sb; /* File info for org.cups.cupsd.plist */
/*
}
/*
- * Time to write a new 'com.easysw.cupsd.plist' file.
+ * Time to write a new 'org.cups.cupsd.plist' file.
* Create the new dictionary and populate it with values...
*/
CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_RUNATLOAD),
kCFBooleanFalse);
+#ifdef LAUNCH_JOBKEY_SERVICEIPC
CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_SERVICEIPC),
kCFBooleanTrue);
+#endif /* LAUNCH_JOBKEY_SERVICEIPC */
if ((array = CFArrayCreateMutable(kCFAllocatorDefault, 2,
&kCFTypeArrayCallBacks)) != NULL)
/*
- * End of "$Id: main.c 5042 2006-02-01 18:17:34Z mike $".
+ * End of "$Id: main.c 5056 2006-02-02 19:46:32Z mike $".
*/
/*
- * "$Id: mime.c 4970 2006-01-24 14:05:45Z mike $"
+ * "$Id: mime.c 5057 2006-02-02 20:38:29Z mike $"
*
* MIME database file routines for the Common UNIX Printing System (CUPS).
*
* mimeDeleteType() - Delete a type from the MIME database.
* mimeFirstFilter() - Get the first filter in the MIME database.
* mimeFirstType() - Get the first type in the MIME database.
- * mimeNextType() - Get the next type in the MIME database.
* mimeLoad() - Create a new MIME database from disk.
* mimeMerge() - Merge a MIME database from disk with the current one.
* mimeNew() - Create a new, empty MIME database.
* mimeNextType() - Get the next type in the MIME database.
* mimeNumFilters() - Get the number of filters in a MIME database.
* mimeNumTypes() - Get the number of types in a MIME database.
- * load_types() - Load a xyz.types file...
+ * add_fcache() - Add a filter to the filter cache.
+ * compare_fcache() - Compare two filter cache entries.
+ * delete_fcache() - Free all memory used by the filter cache.
* delete_rules() - Free all memory for the given rule tree.
* load_convs() - Load a xyz.convs file...
+ * load_types() - Load a xyz.types file...
*/
/*
#include "mime.h"
+/*
+ * Local types...
+ */
+
+typedef struct _mime_fcache_s /**** Filter cache structure ****/
+{
+ char *name, /* Filter name */
+ *path; /* Full path to filter if available */
+} _mime_fcache_t;
+
+
/*
* Local functions...
*/
-static void load_types(mime_t *mime, const char *filename);
-static void load_convs(mime_t *mime, const char *filename,
- const char *filterpath);
+static const char *add_fcache(cups_array_t *filtercache, const char *name,
+ const char *filterpath);
+static int compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b);
+static void delete_fcache(cups_array_t *filtercache);
static void delete_rules(mime_magic_t *rules);
+static void load_convs(mime_t *mime, const char *filename,
+ const char *filterpath,
+ cups_array_t *filtercache);
+static void load_types(mime_t *mime, const char *filename);
/*
cups_dir_t *dir; /* Directory */
cups_dentry_t *dent; /* Directory entry */
char filename[1024]; /* Full filename of types/converts file */
+ cups_array_t *filtercache; /* Filter cache */
/*
* Read all the .convs files...
*/
+ filtercache = cupsArrayNew((cups_array_func_t)compare_fcache, NULL);
+
while ((dent = cupsDirRead(dir)) != NULL)
{
if (strlen(dent->filename) > 6 &&
*/
snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename);
- load_convs(mime, filename, filterpath);
+ load_convs(mime, filename, filterpath, filtercache);
}
}
+ delete_fcache(filtercache);
+
cupsDirClose(dir);
return (mime);
/*
- * 'load_types()' - Load a xyz.types file...
+ * 'add_fcache()' - Add a filter to the filter cache.
*/
-static void
-load_types(mime_t *mime, /* I - MIME database */
- const char *filename) /* I - Types file to load */
+static const char * /* O - Full path to filter or NULL */
+add_fcache(cups_array_t *filtercache, /* I - Filter cache */
+ const char *name, /* I - Filter name */
+ const char *filterpath) /* I - Filter path */
{
- cups_file_t *fp; /* Types file */
- int linelen; /* Length of line */
- char line[65536], /* Input line from file */
- *lineptr, /* Current position in line */
- super[MIME_MAX_SUPER], /* Super-type name */
- type[MIME_MAX_TYPE], /* Type name */
- *temp; /* Temporary pointer */
- mime_type_t *typeptr; /* New MIME type */
+ _mime_fcache_t key, /* Search key */
+ *temp; /* New filter cache */
+ char path[1024]; /* Full path to filter */
- /*
- * First try to open the file...
- */
+ key.name = (char *)name;
+ if ((temp = (_mime_fcache_t *)cupsArrayFind(filtercache, &key)) != NULL)
+ return (temp->path);
- if ((fp = cupsFileOpen(filename, "r")) == NULL)
- return;
+ if ((temp = calloc(1, sizeof(_mime_fcache_t))) == NULL)
+ return (NULL);
- /*
- * Then read each line from the file, skipping any comments in the file...
- */
+ temp->name = strdup(name);
- while (cupsFileGets(fp, line, sizeof(line)) != NULL)
- {
- /*
- * Skip blank lines and lines starting with a #...
- */
+ if (cupsFileFind(name, filterpath, 1, path, sizeof(path)))
+ temp->path = strdup(path);
- if (!line[0] || line[0] == '#')
- continue;
+ cupsArrayAdd(filtercache, temp);
- /*
- * While the last character in the line is a backslash, continue on to the
- * next line (and the next, etc.)
- */
+ return (temp->path);
+}
- linelen = strlen(line);
- while (line[linelen - 1] == '\\')
- {
- linelen --;
+/*
+ * 'compare_fcache()' - Compare two filter cache entries.
+ */
- if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL)
- line[linelen] = '\0';
- else
- linelen += strlen(line + linelen);
- }
+static int /* O - Result of comparison */
+compare_fcache(_mime_fcache_t *a, /* I - First entry */
+ _mime_fcache_t *b) /* I - Second entry */
+{
+ return (strcmp(a->name, b->name));
+}
- /*
- * Extract the super-type and type names from the beginning of the line.
- */
- lineptr = line;
- temp = super;
+/*
+ * 'delete_fcache()' - Free all memory used by the filter cache.
+ */
- while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
- (temp - super + 1) < MIME_MAX_SUPER)
- *temp++ = tolower(*lineptr++ & 255);
+static void
+delete_fcache(cups_array_t *filtercache)/* I - Filter cache */
+{
+ _mime_fcache_t *current; /* Current cache entry */
- *temp = '\0';
- if (*lineptr != '/')
- continue;
+ for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache);
+ current;
+ current = (_mime_fcache_t *)cupsArrayNext(filtercache))
+ {
+ free(current->name);
- lineptr ++;
- temp = type;
+ if (current->path)
+ free(current->path);
- while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
- *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
- *temp++ = tolower(*lineptr++ & 255);
+ free(current);
+ }
- *temp = '\0';
+ cupsArrayDelete(filtercache);
+}
- /*
- * Add the type and rules to the MIME database...
- */
- typeptr = mimeAddType(mime, super, type);
- mimeAddTypeRule(typeptr, lineptr);
- }
+/*
+ * 'delete_rules()' - Free all memory for the given rule tree.
+ */
- cupsFileClose(fp);
+static void
+delete_rules(mime_magic_t *rules) /* I - Rules to free */
+{
+ mime_magic_t *next; /* Next rule to free */
+
+
+ /*
+ * Free the rules list, descending recursively to free any child rules.
+ */
+
+ while (rules != NULL)
+ {
+ next = rules->next;
+
+ if (rules->child != NULL)
+ delete_rules(rules->child);
+
+ free(rules);
+ rules = next;
+ }
}
*/
static void
-load_convs(mime_t *mime, /* I - MIME database */
- const char *filename, /* I - Convs file to load */
- const char *filterpath) /* I - Path for filters */
+load_convs(mime_t *mime, /* I - MIME database */
+ const char *filename, /* I - Convs file to load */
+ const char *filterpath, /* I - Path for filters */
+ cups_array_t *filtercache) /* I - Filter program cache */
{
cups_file_t *fp; /* Convs file */
char line[1024], /* Input line from file */
mime_type_t *temptype, /* MIME type looping var */
*dsttype; /* Destination MIME type */
int cost; /* Cost of filter */
-#ifndef WIN32
- char filterprog[1024]; /* Full path of filter... */
-#endif /* !WIN32 */
/*
filter = lineptr;
-#ifndef WIN32
if (strcmp(filter, "-"))
{
/*
* Verify that the filter exists and is executable...
*/
- if (filter[0] == '/')
- strlcpy(filterprog, filter, sizeof(filterprog));
- else if (!cupsFileFind(filter, filterpath, filterprog,
- sizeof(filterprog)))
+ if (!add_fcache(filtercache, filter, filterpath))
continue;
-
- if (access(filterprog, X_OK))
- continue;
}
-#endif /* !WIN32 */
/*
* Finally, get the source super-type and type names from the beginning of
/*
- * 'delete_rules()' - Free all memory for the given rule tree.
+ * 'load_types()' - Load a xyz.types file...
*/
static void
-delete_rules(mime_magic_t *rules) /* I - Rules to free */
+load_types(mime_t *mime, /* I - MIME database */
+ const char *filename) /* I - Types file to load */
{
- mime_magic_t *next; /* Next rule to free */
+ cups_file_t *fp; /* Types file */
+ int linelen; /* Length of line */
+ char line[65536], /* Input line from file */
+ *lineptr, /* Current position in line */
+ super[MIME_MAX_SUPER], /* Super-type name */
+ type[MIME_MAX_TYPE], /* Type name */
+ *temp; /* Temporary pointer */
+ mime_type_t *typeptr; /* New MIME type */
/*
- * Free the rules list, descending recursively to free any child rules.
+ * First try to open the file...
*/
- while (rules != NULL)
+ if ((fp = cupsFileOpen(filename, "r")) == NULL)
+ return;
+
+ /*
+ * Then read each line from the file, skipping any comments in the file...
+ */
+
+ while (cupsFileGets(fp, line, sizeof(line)) != NULL)
{
- next = rules->next;
+ /*
+ * Skip blank lines and lines starting with a #...
+ */
- if (rules->child != NULL)
- delete_rules(rules->child);
+ if (!line[0] || line[0] == '#')
+ continue;
- free(rules);
- rules = next;
+ /*
+ * While the last character in the line is a backslash, continue on to the
+ * next line (and the next, etc.)
+ */
+
+ linelen = strlen(line);
+
+ while (line[linelen - 1] == '\\')
+ {
+ linelen --;
+
+ if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL)
+ line[linelen] = '\0';
+ else
+ linelen += strlen(line + linelen);
+ }
+
+ /*
+ * Extract the super-type and type names from the beginning of the line.
+ */
+
+ lineptr = line;
+ temp = super;
+
+ while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
+ (temp - super + 1) < MIME_MAX_SUPER)
+ *temp++ = tolower(*lineptr++ & 255);
+
+ *temp = '\0';
+
+ if (*lineptr != '/')
+ continue;
+
+ lineptr ++;
+ temp = type;
+
+ while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
+ *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
+ *temp++ = tolower(*lineptr++ & 255);
+
+ *temp = '\0';
+
+ /*
+ * Add the type and rules to the MIME database...
+ */
+
+ typeptr = mimeAddType(mime, super, type);
+ mimeAddTypeRule(typeptr, lineptr);
}
+
+ cupsFileClose(fp);
}
/*
- * End of "$Id: mime.c 4970 2006-01-24 14:05:45Z mike $".
+ * End of "$Id: mime.c 5057 2006-02-02 20:38:29Z mike $".
*/
/*
- * "$Id: mime.h 4970 2006-01-24 14:05:45Z mike $"
+ * "$Id: mime.h 5058 2006-02-02 21:58:45Z mike $"
*
* MIME type/conversion database definitions for the Common UNIX Printing System (CUPS).
*
# define MIME_MAX_SUPER 16 /* Maximum size of supertype name */
# define MIME_MAX_TYPE IPP_MAX_NAME /* Maximum size of type name */
# define MIME_MAX_FILTER 256 /* Maximum size of filter pathname */
-# define MIME_MAX_BUFFER 8192 /* Maximum size of file buffer */
+# define MIME_MAX_BUFFER 4096 /* Maximum size of file buffer */
/*
MIME_MAGIC_ISTRING /* Case-insensitive string matches */
} mime_op_t;
-typedef struct mime_magic_str /**** MIME Magic Data ****/
+typedef struct _mime_magic_s /**** MIME Magic Data ****/
{
struct mime_magic_str *prev, /* Previous rule */
*next, /* Next rule */
} value;
} mime_magic_t;
-typedef struct /**** MIME Type Data ****/
+typedef struct _mime_type_s /**** MIME Type Data ****/
{
mime_magic_t *rules; /* Rules used to detect this type */
char super[MIME_MAX_SUPER], /* Super-type name ("image", "application", etc.) */
type[MIME_MAX_TYPE]; /* Type name ("png", "postscript", etc.) */
} mime_type_t;
-typedef struct /**** MIME Conversion Filter Data ****/
+typedef struct _mime_filter_s /**** MIME Conversion Filter Data ****/
{
mime_type_t *src, /* Source type */
*dst; /* Destination type */
char filter[MIME_MAX_FILTER];/* Filter program to use */
} mime_filter_t;
-typedef struct /**** MIME Database ****/
+typedef struct _mime_s /**** MIME Database ****/
{
cups_array_t *types; /* File types */
cups_array_t *filters; /* Type conversion filters */
extern int mimeAddTypeRule(mime_type_t *mt, const char *rule);
extern void mimeDeleteType(mime_t *mime, mime_type_t *mt);
extern mime_type_t *mimeFileType(mime_t *mime, const char *pathname,
- int *compression);
+ const char *filename, int *compression);
extern mime_type_t *mimeFirstType(mime_t *mime);
extern mime_type_t *mimeNextType(mime_t *mime);
extern int mimeNumTypes(mime_t *mime);
#endif /* !_CUPS_MIME_H_ */
/*
- * End of "$Id: mime.h 4970 2006-01-24 14:05:45Z mike $".
+ * End of "$Id: mime.h 5058 2006-02-02 21:58:45Z mike $".
*/
/*
- * "$Id: printers.c 5039 2006-02-01 16:29:57Z mike $"
+ * "$Id: printers.c 5047 2006-02-02 05:14:15Z mike $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
cupsd_banner_t *banner; /* Current banner */
- attr->values[0].string.text = strdup("none");
+ attr->values[0].string.text = _cups_sp_alloc("none");
for (i = 1, banner = (cupsd_banner_t *)cupsArrayFirst(Banners);
banner;
i ++, banner = (cupsd_banner_t *)cupsArrayNext(Banners))
- attr->values[i].string.text = strdup(banner->name);
+ attr->values[i].string.text = _cups_sp_alloc(banner->name);
}
}
else
attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME,
"printer-op-policy-supported", NumPolicies, NULL, NULL);
for (i = 0; i < NumPolicies; i ++)
- attr->values[i].string.text = strdup(Policies[i]->name);
+ attr->values[i].string.text = _cups_sp_alloc(Policies[i]->name);
}
if (attr != NULL)
{
- attr->values[0].string.text = strdup(Classification ?
+ attr->values[0].string.text = _cups_sp_alloc(Classification ?
Classification : p->job_sheets[0]);
- attr->values[1].string.text = strdup(Classification ?
+ attr->values[1].string.text = _cups_sp_alloc(Classification ?
Classification : p->job_sheets[1]);
}
}
for (i = 0; i < p->num_printers; i ++)
{
if (attr != NULL)
- attr->values[i].string.text = strdup(p->printers[i]->uri);
+ attr->values[i].string.text = _cups_sp_alloc(p->printers[i]->uri);
p->type &= ~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
}
if (attr != NULL)
{
for (i = 0; i < p->num_printers; i ++)
- attr->values[i].string.text = strdup(p->printers[i]->name);
+ attr->values[i].string.text = _cups_sp_alloc(p->printers[i]->name);
}
}
}
if (input_slot != NULL)
for (i = 0; i < input_slot->num_choices; i ++, val ++)
- val->string.text = strdup(input_slot->choices[i].choice);
+ val->string.text = _cups_sp_alloc(input_slot->choices[i].choice);
if (media_type != NULL)
for (i = 0; i < media_type->num_choices; i ++, val ++)
- val->string.text = strdup(media_type->choices[i].choice);
+ val->string.text = _cups_sp_alloc(media_type->choices[i].choice);
if (media_quality != NULL)
for (i = 0; i < media_quality->num_choices; i ++, val ++)
- val->string.text = strdup(media_quality->choices[i].choice);
+ val->string.text = _cups_sp_alloc(media_quality->choices[i].choice);
if (page_size != NULL)
{
for (i = 0; i < page_size->num_choices; i ++, val ++)
- val->string.text = strdup(page_size->choices[i].choice);
+ val->string.text = _cups_sp_alloc(page_size->choices[i].choice);
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
NULL, page_size->defchoice);
for (i = 0, val = attr->values;
i < output_bin->num_choices;
i ++, val ++)
- val->string.text = strdup(output_bin->choices[i].choice);
+ val->string.text = _cups_sp_alloc(output_bin->choices[i].choice);
}
}
attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"port-monitor-supported", i, NULL, NULL);
- attr->values[0].string.text = strdup("none");
+ attr->values[0].string.text = _cups_sp_alloc("none");
for (i = 1, ppdattr = ppdFindAttr(ppd, "cupsPortMonitor", NULL);
ppdattr;
i ++, ppdattr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL))
- attr->values[i].string.text = strdup(ppdattr->value);
+ attr->values[i].string.text = _cups_sp_alloc(ppdattr->value);
if (ppd->protocols)
{
if (strstr(ppd->protocols, "TBCP"))
- attr->values[i].string.text = strdup("tbcp");
+ attr->values[i].string.text = _cups_sp_alloc("tbcp");
else if (strstr(ppd->protocols, "BCP"))
- attr->values[i].string.text = strdup("bcp");
+ attr->values[i].string.text = _cups_sp_alloc("bcp");
}
/*
/*
- * End of "$Id: printers.c 5039 2006-02-01 16:29:57Z mike $".
+ * End of "$Id: printers.c 5047 2006-02-02 05:14:15Z mike $".
*/
/*
- * "$Id: process.c 5046 2006-02-01 22:11:58Z mike $"
+ * "$Id: process.c 5049 2006-02-02 14:50:57Z mike $"
*
* Process management routines for the Common UNIX Printing System (CUPS).
*
#include "cupsd.h"
#include <grp.h>
+#if defined(__APPLE__) && __GNUC__ < 4
+# include <libgen.h>
+#endif /* __APPLE__ && __GNUC__ < 4 */
/*
* We have room, try to read the symlink path for this command...
*/
- if ((linkbytes = readlink(linkpath, sizeof(linkpath) - 1)) > 0)
+ if ((linkbytes = readlink(command, linkpath, sizeof(linkpath) - 1)) > 0)
{
/*
* Yes, this is a symlink to the actual program, nul-terminate and
/*
- * End of "$Id: process.c 5046 2006-02-01 22:11:58Z mike $".
+ * End of "$Id: process.c 5049 2006-02-02 14:50:57Z mike $".
*/
/*
- * "$Id: sysman.c 5018 2006-01-28 06:06:55Z mike $"
+ * "$Id: sysman.c 5049 2006-02-02 14:50:57Z mike $"
*
* System management definitions for the Common UNIX Printing System (CUPS).
*
case kIOMessageSystemWillNotPowerOff:
case kIOMessageSystemWillNotSleep:
+#ifdef kIOMessageSystemWillPowerOn
case kIOMessageSystemWillPowerOn:
+#endif /* kIOMessageSystemWillPowerOn */
default:
sendit = 0;
break;
/*
- * End of "$Id: sysman.c 5018 2006-01-28 06:06:55Z mike $".
+ * End of "$Id: sysman.c 5049 2006-02-02 14:50:57Z mike $".
*/
/*
- * "$Id: testmime.c 4970 2006-01-24 14:05:45Z mike $"
+ * "$Id: testmime.c 5051 2006-02-02 16:13:16Z mike $"
*
* MIME test program for the Common UNIX Printing System (CUPS).
*
*
* Contents:
*
- * main() - Main entry for the test program.
+ * main() - Main entry for the test program.
+ * print_rules() - Print the rules for a file type...
+ * type_dir() - Show the MIME types for a given directory.
*/
/*
#include <stdlib.h>
#include <cups/string.h>
#include "mime.h"
+#include <cups/dir.h>
/*
* Local functions...
*/
-static void print_rules(mime_magic_t *rules);
+static void print_rules(mime_magic_t *rules);
+static void type_dir(mime_t *mime, const char *dirname);
/*
if (!mime)
mime = mimeLoad("../conf", filter_path);
- src = mimeFileType(mime, argv[i], &compression);
+ src = mimeFileType(mime, argv[i], NULL, &compression);
if (src)
printf("%s: %s/%s%s\n", argv[i], src->super, src->type,
filter->src->super, filter->src->type,
filter->dst->super, filter->dst->type,
filter->filter, filter->cost);
+
+ type_dir(mime, "..");
}
return (0);
/*
- * End of "$Id: testmime.c 4970 2006-01-24 14:05:45Z mike $".
+ * 'type_dir()' - Show the MIME types for a given directory.
+ */
+
+static void
+type_dir(mime_t *mime, /* I - MIME database */
+ const char *dirname) /* I - Directory */
+{
+ cups_dir_t *dir; /* Directory */
+ cups_dentry_t *dent; /* Directory entry */
+ char filename[1024]; /* File to type */
+ mime_type_t *filetype; /* File type */
+ int compression; /* Compressed file? */
+ mime_type_t *pstype; /* application/vnd.cups-postscript */
+ cups_array_t *filters; /* Filters to pstype */
+ mime_filter_t *filter; /* Current filter */
+ int cost; /* Filter cost */
+
+
+ dir = cupsDirOpen(dirname);
+ if (!dir)
+ return;
+
+ pstype = mimeType(mime, "application", "vnd.cups-postscript");
+
+ while ((dent = cupsDirRead(dir)) != NULL)
+ {
+ snprintf(filename, sizeof(filename), "%s/%s", dirname, dent->filename);
+
+ if (S_ISDIR(dent->fileinfo.st_mode))
+ type_dir(mime, filename);
+
+ if (!S_ISREG(dent->fileinfo.st_mode))
+ continue;
+
+ filetype = mimeFileType(mime, filename, NULL, &compression);
+
+ if (filetype)
+ {
+ printf("%s: %s/%s%s\n", filename, filetype->super, filetype->type,
+ compression ? " (compressed)" : "");
+
+ filters = mimeFilter(mime, filetype, pstype, &cost, 10);
+
+ if (!filters)
+ puts(" No filters to convert application/vnd.cups-postscript.");
+ else
+ {
+ printf(" Filter cost = %d\n", cost);
+
+ filter = (mime_filter_t *)cupsArrayFirst(filters);
+ printf(" %s", filter->filter);
+
+ for (filter = (mime_filter_t *)cupsArrayNext(filters);
+ filter;
+ filter = (mime_filter_t *)cupsArrayNext(filters))
+ printf(" | %s", filter->filter);
+
+ putchar('\n');
+
+ cupsArrayDelete(filters);
+ }
+ }
+ else
+ printf("%s: unknown%s\n", filename, compression ? " (compressed)" : "");
+ }
+
+ cupsDirClose(dir);
+}
+
+
+/*
+ * End of "$Id: testmime.c 5051 2006-02-02 16:13:16Z mike $".
*/
/*
- * "$Id: type.c 4970 2006-01-24 14:05:45Z mike $"
+ * "$Id: type.c 5052 2006-02-02 16:21:13Z mike $"
*
* MIME typing routines for the Common UNIX Printing System (CUPS).
*
#include <cups/debug.h>
+/*
+ * Local types...
+ */
+
+typedef struct _mime_filebuf_s /**** File buffer for MIME typing ****/
+{
+ cups_file_t *fp; /* File pointer */
+ int offset, /* Offset in file */
+ length; /* Length of buffered data */
+ unsigned char buffer[MIME_MAX_BUFFER];/* Buffered data */
+} _mime_filebuf_t;
+
+
/*
* Local functions...
*/
static int compare_types(mime_type_t *t0, mime_type_t *t1);
-static int checkrules(const char *, cups_file_t *, mime_magic_t *);
-static int patmatch(const char *, const char *);
+static int checkrules(const char *filename, _mime_filebuf_t *fb,
+ mime_magic_t *rules);
+static int patmatch(const char *s, const char *pat);
/*
else if (*rule == '+' && current != NULL)
{
if (logic != MIME_MAGIC_AND &&
- current != NULL && current->prev != NULL && current->prev->prev != NULL)
+ current != NULL && current->prev != NULL &&
+ current->prev->prev != NULL)
{
/*
* OK, we have more than 1 rule in the current tree level... Make a
* Read an extension name or a function...
*/
- for (ptr = name; isalnum(*rule & 255) && (ptr - name) < (sizeof(name) - 1);)
+ ptr = name;
+ while (isalnum(*rule & 255) && (ptr - name) < (sizeof(name) - 1))
*ptr++ = *rule++;
*ptr = '\0';
mime_type_t * /* O - Type of file */
mimeFileType(mime_t *mime, /* I - MIME database */
- const char *pathname, /* I - Name of file to check */
+ const char *pathname, /* I - Name of file to check on disk */
+ const char *filename, /* I - Original filename or NULL */
int *compression) /* O - Is the file compressed? */
{
- cups_file_t *fp; /* File pointer */
- mime_type_t *type; /* File type */
- const char *filename; /* Base filename of file */
+ _mime_filebuf_t fb; /* File buffer */
+ const char *base; /* Base filename of file */
+ mime_type_t *type; /* File type */
- DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", compression=%p)\n",
- mime, pathname ? pathname : "(nil)", compression));
+ DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", basename=\"%s\", "
+ "compression=%p)\n",
+ mime, pathname ? pathname : "(nil)",
+ filename ? filename : "(nil)",
+ basenamecompression));
/*
* Range check input parameters...
* Try to open the file...
*/
- if ((fp = cupsFileOpen(pathname, "r")) == NULL)
+ if ((fb.fp = cupsFileOpen(pathname, "r")) == NULL)
return (NULL);
+ fb.offset = -1;
+ fb.length = 0;
+
/*
- * Figure out the filename (without directory portion)...
+ * Figure out the base filename (without directory portion)...
*/
- if ((filename = strrchr(pathname, '/')) != NULL)
- filename ++;
+ if (filename)
+ {
+ if ((base = strrchr(filename, '/')) != NULL)
+ base ++;
+ else
+ filename = filename;
+ }
+ else if ((base = strrchr(pathname, '/')) != NULL)
+ base ++;
else
filename = pathname;
for (type = (mime_type_t *)cupsArrayFirst(mime->types);
type;
type = (mime_type_t *)cupsArrayNext(mime->types))
- if (checkrules(filename, fp, type->rules))
+ if (checkrules(base, &fb, type->rules))
break;
/*
*/
if (compression)
- *compression = cupsFileCompression(fp);
+ *compression = cupsFileCompression(fb.fp);
- cupsFileClose(fp);
+ cupsFileClose(fb.fp);
return (type);
}
*/
static int /* O - 1 if match, 0 if no match */
-checkrules(const char *filename, /* I - Filename */
- cups_file_t *fp, /* I - File to check */
- mime_magic_t *rules) /* I - Rules to check */
+checkrules(const char *filename, /* I - Filename */
+ _mime_filebuf_t *fb, /* I - File to check */
+ mime_magic_t *rules) /* I - Rules to check */
{
int n; /* Looping var */
int region; /* Region to look at */
result, /* Result of test */
intv; /* Integer value */
short shortv; /* Short value */
- unsigned char buffer[MIME_MAX_BUFFER],/* Input buffer */
- *bufptr; /* Current buffer position */
- int bufoffset, /* Offset in file for buffer */
- buflength; /* Length of data in buffer */
+ unsigned char *bufptr; /* Pointer into buffer */
#ifdef DEBUG
const char * const debug_tests[] = /* Test names... */
{
"OR", /* Logical OR of all children */
"MATCH", /* Filename match */
"ASCII", /* ASCII characters in range */
- "PRINTABLE", /* Printable characters (32-255) in range */
+ "PRINTABLE", /* Printable characters (32-255) */
"STRING", /* String matches */
"CHAR", /* Character/byte matches */
"SHORT", /* Short/16-bit word matches */
else
logic = rules->parent->op;
- bufoffset = -1;
- buflength = 0;
- result = 0;
+ result = 0;
while (rules != NULL)
{
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* Test for ASCII printable characters plus standard control chars.
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
- n = bufoffset + buflength - rules->offset;
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
+ n = fb->offset + fb->length - rules->offset;
else
n = rules->length;
- bufptr = buffer + rules->offset - bufoffset;
+ bufptr = fb->buffer + rules->offset - fb->offset;
while (n > 0)
if ((*bufptr >= 32 && *bufptr <= 126) ||
(*bufptr >= 8 && *bufptr <= 13) ||
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* Test for 8-bit printable characters plus standard control chars.
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
- n = bufoffset + buflength - rules->offset;
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
+ n = fb->offset + fb->length - rules->offset;
else
n = rules->length;
- bufptr = buffer + rules->offset - bufoffset;
+ bufptr = fb->buffer + rules->offset - fb->offset;
while (n > 0)
if (*bufptr >= 128 ||
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
- DEBUG_printf((" loaded %d byte buffer at %d, starts with \"%c%c%c%c\"...\n",
- buflength, bufoffset, buffer[0], buffer[1],
- buffer[2], buffer[3]));
+ DEBUG_printf((" loaded %d byte fb->buffer at %d, starts "
+ "with \"%c%c%c%c\"...\n",
+ fb->length, fb->offset, fb->buffer[0], fb->buffer[1],
+ fb->buffer[2], fb->buffer[3]));
}
/*
* short then don't compare - it can't match...
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
- result = (memcmp(buffer + rules->offset - bufoffset,
+ result = (memcmp(fb->buffer + rules->offset - fb->offset,
rules->value.stringv, rules->length) == 0);
DEBUG_printf((" result=%d\n", result));
break;
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* short then don't compare - it can't match...
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
- result = (strncasecmp((char *)buffer + rules->offset - bufoffset,
+ result = (strncasecmp((char *)fb->buffer + rules->offset -
+ fb->offset,
rules->value.stringv, rules->length) == 0);
break;
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset)
+ if (fb->offset < 0 || rules->offset < fb->offset)
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* can't match...
*/
- if (buflength < 1)
+ if (fb->length < 1)
result = 0;
else
- result = (buffer[rules->offset - bufoffset] == rules->value.charv);
+ result = (fb->buffer[rules->offset - fb->offset] ==
+ rules->value.charv);
break;
case MIME_MAGIC_SHORT :
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + 2) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + 2) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* can't match...
*/
- if (buflength < 2)
+ if (fb->length < 2)
result = 0;
else
{
- bufptr = buffer + rules->offset - bufoffset;
+ bufptr = fb->buffer + rules->offset - fb->offset;
shortv = (bufptr[0] << 8) | bufptr[1];
result = (shortv == rules->value.shortv);
}
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + 4) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + 4) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* can't match...
*/
- if (buflength < 4)
+ if (fb->length < 4)
result = 0;
else
{
- bufptr = buffer + rules->offset - bufoffset;
- intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) | bufptr[2]) << 8) |
- bufptr[3];;
+ bufptr = fb->buffer + rules->offset - fb->offset;
+ intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) |
+ bufptr[2]) << 8) | bufptr[3];
result = (intv == rules->value.intv);
}
break;
case MIME_MAGIC_LOCALE :
#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
- result = (strcmp(rules->value.localev, setlocale(LC_ALL, "")) == 0);
+ result = (strcmp(rules->value.localev,
+ setlocale(LC_ALL, "")) == 0);
#else
- result = (strcmp(rules->value.localev, setlocale(LC_MESSAGES, "")) == 0);
+ result = (strcmp(rules->value.localev,
+ setlocale(LC_MESSAGES, "")) == 0);
#endif /* __APPLE__ */
break;
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->region) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->region) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* short then don't compare - it can't match...
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
{
- if (buflength > rules->region)
+ if (fb->length > rules->region)
region = rules->region - rules->length;
else
- region = buflength - rules->length;
+ region = fb->length - rules->length;
for (n = 0; n < region; n ++)
- if ((result = (memcmp(buffer + rules->offset - bufoffset + n,
- rules->value.stringv, rules->length) == 0)) != 0)
+ if ((result = (memcmp(fb->buffer + rules->offset - fb->offset + n,
+ rules->value.stringv,
+ rules->length) == 0)) != 0)
break;
}
break;
default :
if (rules->child != NULL)
- result = checkrules(filename, fp, rules->child);
+ result = checkrules(filename, fb, rules->child);
else
result = 0;
break;
pat ++;
if (*pat == '\0')
- return (1); /* Last pattern char is *, so everything matches now... */
+ return (1); /* Last pattern char is *, so everything matches... */
/*
* Test all remaining combinations until we get to the end of the string.
}
/*
- * Done parsing the pattern and string; return 1 if the last character matches
- * and 0 otherwise...
+ * Done parsing the pattern and string; return 1 if the last character
+ * matches and 0 otherwise...
*/
return (*s == *pat);
/*
- * End of "$Id: type.c 4970 2006-01-24 14:05:45Z mike $".
+ * End of "$Id: type.c 5052 2006-02-02 16:21:13Z mike $".
*/
#
-# "$Id: Makefile 4950 2006-01-19 16:07:57Z mike $"
+# "$Id: Makefile 5055 2006-02-02 18:25:38Z mike $"
#
# Template makefile for the Common UNIX Printing System (CUPS).
#
printers.tmpl \
printers-header.tmpl \
restart.tmpl \
+ samba-export.tmpl \
+ samba-exported.tmpl \
search.tmpl \
set-printer-options-header.tmpl \
set-printer-options-trailer.tmpl \
#
-# End of "$Id: Makefile 4950 2006-01-19 16:07:57Z mike $".
+# End of "$Id: Makefile 5055 2006-02-02 18:25:38Z mike $".
#
--- /dev/null
+<SCRIPT TYPE="text/javascript"><!--
+function select_printers() {
+ var list = document.export_samba.EXPORT_NAME;
+ var sel = document.export_samba.EXPORT_ALL.checked;
+
+ for (i = 0; i < list.length; i ++) {
+ list.options[i].selected = sel;
+ }
+}
+--></SCRIPT>
+
+<FORM METHOD="POST" ACTION="/admin/" NAME="export_samba">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="export-samba">
+
+<H2 CLASS="title">Export Printers to Samba</H2>
+
+{error?<P>Unable to export printers to Samba\:</P>
+<BLOCKQUOTE>{error}</BLOCKQUOTE>
+<P>Consult the <A HREF="/admin/log/error_log"
+TARGET="_blank">error_log</A> file for more information.</P>:
+<P>This page allows you to export printers to Samba so that
+Windows clients can access them through the <VAR>Network
+Neighborhood</VAR> or <VAR>Network Places</VAR> icons on their
+desktop. You must previously install the Windows PostScript
+printer drivers as described in the <A
+HREF="/help/man-cupsaddsmb.html"
+TARGET="_blank">cupsaddsmb(8)</A> man page.</P>}
+
+<TABLE>
+<TR>
+<TH CLASS="label">Printers:</TH>
+<TD>
+<SELECT NAME="EXPORT_NAME" SIZE="10" MULTIPLE>
+{[printer_name]<OPTION VALUE="{printer_name}"{export_all? SELECTED:{printer_export? SELECTED:}}>{printer_name}}
+</SELECT><BR>
+<INPUT TYPE="CHECKBOX" NAME="EXPORT_ALL"{export_all? CHECKED:}
+onChange="select_printers()"> Export All Printers
+</TD>
+</TR>
+<TR>
+<TH CLASS="label">Samba Username:</TH>
+<TD><INPUT TYPE="TEXT" NAME="USERNAME" VALUE="{?USERNAME}"> (required)</TD>
+</TR>
+<TR>
+<TH CLASS="label">Samba Password:</TH>
+<TD><INPUT TYPE="PASSWORD" NAME="PASSWORD" VALUE=""> (required)</TD>
+</TR>
+<TR>
+<TD></TD>
+<TD><INPUT TYPE="IMAGE" SRC="/images/export-samba.gif"
+ALT="Export Printers to Samba"></TD>
+</TR>
+</TABLE>
+
+</FORM>
--- /dev/null
+<P>Printers exported to samba successfully.</P>