1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
Description: Filter printers based on PRINTER_LIST
Author: Julien Desfossez at Revolution Linux
=== modified file 'cups-1.3.9/cups/ipp.c'
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -77,6 +77,8 @@
* ippNewResponse() - Allocate a new IPP response message.
* ippRead() - Read data for an IPP message from a HTTP
* connection.
+ * ippFilterPrinters() - Filter printer list based on an environment
+ * variable
* ippReadFile() - Read data for an IPP message from a file.
* ippReadIO() - Read data for an IPP message.
* ippSetBoolean() - Set a boolean value in an attribute.
@@ -2762,6 +2764,120 @@
return (temp);
}
+/*
+ * 'ippFilterPrinters()' - Filter printer list based on environment variables
+ */
+ipp_state_t /* O - Current state */
+ippFilterPrinters(ipp_t *ipp) /* I - IPP data */
+{
+ char *env_printer_list = NULL;
+ char *result_printer_list;
+ char delim_printers[] = ",";
+ char **printer_list_array;
+ char *default_printer_env;
+ int printer_list_size = 0;
+ ipp_attribute_t *filtertmpattr;
+ ipp_attribute_t *filtertmpattr2;
+ int i = 0;
+ int j = 0;
+ int found = 0;
+ int printer_name_found = 0;
+ int len = 0;
+ int last_null = 0;
+
+ /*
+ * First we create an array from PRINTER and PRINTER_LIST
+ */
+ if(getenv("PRINTER") != NULL) {
+ default_printer_env = getenv("PRINTER");
+ printer_list_size++;
+ } else {
+ default_printer_env = (char *)malloc(sizeof(char));
+ default_printer_env = "";
+ }
+
+ env_printer_list = strdup(getenv("PRINTER_LIST"));
+ result_printer_list = strtok(env_printer_list, delim_printers);
+ while(result_printer_list) {
+ if(default_printer_env && strcasecmp(result_printer_list, default_printer_env) != 0)
+ printer_list_size++;
+ result_printer_list = strtok( NULL, delim_printers);
+ }
+
+ printer_list_array = (char **)malloc(printer_list_size * sizeof(char *));
+
+ env_printer_list = strdup(getenv("PRINTER_LIST"));
+
+ result_printer_list = strtok(env_printer_list, delim_printers);
+ while(result_printer_list) {
+ /*
+ * Don't add the default printer if it's defined
+ */
+ if(strcasecmp(result_printer_list, default_printer_env) != 0) {
+ printer_list_array[i] = (char *)malloc(sizeof(result_printer_list));
+ printer_list_array[i++] = result_printer_list;
+ }
+ result_printer_list = strtok( NULL, delim_printers);
+ }
+
+ if(strcasecmp(default_printer_env, "") != 0)
+ printer_list_array[printer_list_size-1] = default_printer_env;
+
+ // number of attributes
+ for (filtertmpattr = ipp->attrs; filtertmpattr != NULL; filtertmpattr = filtertmpattr->next) {
+ len++;
+ }
+ ipp_attribute_t* array[len];
+
+ for (filtertmpattr = ipp->attrs; filtertmpattr != NULL; filtertmpattr = filtertmpattr->next) {
+ array[j++] = filtertmpattr;
+ }
+
+ for (j=0; j<len; j++) {
+ filtertmpattr = array[j];
+ // if the current attribute is a printer_name, find it in the list
+ if ((filtertmpattr->value_tag == IPP_TAG_NAME) &&
+ (strcasecmp(filtertmpattr->name, "printer-name") == 0)) {
+ printer_name_found = 1;
+
+ // compare the current printer with the values in the list
+ for(i = 0; i < printer_list_size; i++) {
+ if (printer_list_array[i] && filtertmpattr->values[0].string.text &&
+ (strcasecmp(filtertmpattr->values[0].string.text, printer_list_array[i]) == 0)) {
+ found = 1;
+ }
+ }
+ }
+
+ // last attribute of a printer (separator) or last attribute
+ if (filtertmpattr->value_tag == IPP_TAG_ZERO || filtertmpattr->next == NULL) {
+ if(found == 0 && printer_name_found == 1) { // not found so we remove it
+ // First printer
+ if(last_null == 0) {
+ ipp->attrs = filtertmpattr->next;
+ } else {
+ // Printer in the middle
+ (array[last_null])->next = filtertmpattr->next;
+ }
+ } else {
+ // the last known good printer
+ last_null = j;
+ }
+ printer_name_found = 0;
+ found = 0;
+ }
+ }
+
+ // remove the last IPP_TAG_ZERO if the last element in the list
+ for (filtertmpattr = ipp->attrs; filtertmpattr != NULL; filtertmpattr = filtertmpattr->next){
+ if (filtertmpattr->value_tag == IPP_TAG_ZERO && filtertmpattr->next == NULL){
+ filtertmpattr2->next = NULL;
+ }
+ filtertmpattr2 = filtertmpattr;
+ }
+ return 0;
+}
+
/*
* 'ippNewRequest()' - Allocate a new IPP request message.
@@ -3112,6 +3228,8 @@
*/
DEBUG_puts("2ippReadIO: IPP_TAG_END.");
+ if(getenv("PRINTER_LIST"))
+ ippFilterPrinters(ipp);
ipp->state = IPP_STATE_DATA;
break;
|