summaryrefslogtreecommitdiff
path: root/debian/patches/printer-filtering.patch
blob: 1093dfe26df65ffcef6d84aaa6f828ebcc00658a (plain)
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
146
147
148
From 5739ca30bae336e045657d4a1faab3e9ff92074c Mon Sep 17 00:00:00 2001
From: Julien Desfossez at Revolution Linux
 <Julien Desfossez at Revolution Linux>
Date: Tue, 9 Aug 2016 18:11:42 +0200
Subject: Filter printers based on PRINTER_LIST

Last-Update: 2015-10-02

=== modified file 'cups-1.3.9/cups/ipp.c'
Patch-Name: printer-filtering.patch
---
 cups/ipp.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/cups/ipp.c b/cups/ipp.c
index 1964962..5ed31f5 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -2701,6 +2701,120 @@ ippNew(void)
   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.
@@ -3047,6 +3161,8 @@ ippReadIO(void       *src,		/* I - Data source */
 	    */
 
             DEBUG_puts("2ippReadIO: IPP_TAG_END.");
+            if(getenv("PRINTER_LIST"))
+	            ippFilterPrinters(ipp);
 
 	    ipp->state = IPP_STATE_DATA;
 	    break;