aa29a24dbd91571c2e7199da297fb2f3815c6e02
[apps/core/preloaded/print-service.git] / src / pt_utils.c
1 /*
2 *       Printservice
3 *
4 * Copyright 2012  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9
10 * http://floralicense.org/license/
11
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 #define _GNU_SOURCE
21 #include <string.h>
22 #include <ctype.h>
23 #include <cups/ppd.h>
24 #include <cups/http.h>
25 #include <linux/unistd.h>
26 #include <sys/utsname.h>
27 #include <dirent.h>
28
29 #include "pt_debug.h"
30 #include "pt_common.h"
31
32 #define MAX_PPDGZ_SIZE (1048576)
33
34 ppd_file_t *ppd;
35
36 int __standardization(char *name)
37 {
38         char *ptr = NULL;/* Pointer into name */
39         PT_RETV_IF(name == NULL, -1, "Invalid argument");
40
41         for (ptr = name; *ptr; ptr++) {
42                 if (*ptr == '@') {
43                         return 0;
44                 } else if ((*ptr >= 0 && *ptr < ' ') ||
45                                    *ptr == 127 || *ptr == '/' ||*ptr == '#') {
46                         return -1;
47                 } else if (*ptr == 0x20) {
48                         *ptr = 0x5F; /*convert space to _*/
49                 } else if (*ptr == '[' || *ptr == '(') {
50                         *ptr='\0';
51                         while (name <= ptr) {
52                                 ptr--;
53                                 if (*ptr==0x5F) {
54                                         *ptr='\0';
55                                 } else {
56                                         return 0;
57                                 }
58                         }
59                         return 0;
60                 }
61         }
62         return 0;
63 }
64
65 /**
66  *      This function let the app clear the list of previous searching
67  *      @return    void
68  *      @param[in] list the pointer to the printers list
69  */
70 void pt_utils_free_local_printer_list(Eina_List *list)
71 {
72         PT_RET_IF(list == NULL, "Invalid argument");
73         pt_printer_info_t *detail;
74
75         EINA_LIST_FREE(list, detail) {
76                 PT_IF_FREE_MEM(detail);
77         }
78
79         eina_list_free(list);
80 }
81
82 /**
83  *      This function let the app clear the list of previous searching
84  *      @return    void
85  *      @param[in] list the pointer to the printers list
86  */
87 void pt_utils_free_search_list(Eina_List *list)
88 {
89         PT_RET_IF(list == NULL, "Invalid argument");
90         pt_printer_mgr_t *detail;
91
92         EINA_LIST_FREE(list, detail) {
93                 PT_IF_FREE_MEM(detail);
94         }
95         eina_list_free(list);
96 }
97
98 void pt_utils_free_printing_thd_list(Eina_List *list)
99 {
100         PT_RET_IF(list == NULL, "Invalid argument");
101         pt_printing_job_t *detail;
102
103         EINA_LIST_FREE(list, detail) {
104                 if (detail) {
105
106                         if (detail->job_noti_timer) {
107                                 ecore_timer_del(detail->job_noti_timer);
108                                 detail->job_noti_timer = NULL;
109                         }
110                 }
111         }
112 }
113
114 char *pt_utils_filename_from_URI(const char *uri)
115 {
116         char                    scheme[1024];   /* URI for printer/class */
117         char                    username[1024];         /* Line from PPD file */
118         char                    hostname[1024];         /* Keyword from Default line */
119         int             port;           /* Pointer into keyword... */
120         char                    resource[1024]; /* Temporary filename */
121         char           *filename = NULL;
122
123         PT_RETV_IF(uri == NULL, NULL, "uri is NULL");
124
125         http_uri_status_t status = httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
126                                                            username, sizeof(username), hostname, sizeof(hostname), &port,
127                                                            resource, sizeof(resource));
128         PT_DEBUG("uri:[%s]", uri);
129         PT_DEBUG("scheme: [%s]", scheme);
130         PT_DEBUG("resource: [%s]", resource);
131         PT_DEBUG("status: [%d], HTTP_URI_OK = %d", status, HTTP_URI_OK);
132         if ((status == HTTP_URI_OK || status == HTTP_URI_MISSING_SCHEME)
133                         && (strlen(resource) != 0) && (strcmp(scheme, "file") == 0)) {
134                 filename = strdup(resource);
135         }
136         return filename;
137 }
138
139 static char *pt_utils_rtrim(char *s)
140 {
141         static char t[1024];
142         char *end;
143
144         memset(t,0x00,sizeof(t));
145         strncpy(t, s, sizeof(t) - 1);
146         end = t + strlen(t) - 1;
147         while (end != t && isspace(*end)) {
148                 end--;
149         }
150         *(end + 1) = '\0';
151         s = t;
152
153         return s;
154 }
155
156 static char *pt_utils_ltrim(char *s)
157 {
158         char *begin;
159         begin = s;
160
161         while (*begin != '\0') {
162                 if (isspace(*begin)) {
163                         begin++;
164                 } else {
165                         s = begin;
166                         break;
167                 }
168         }
169
170         return s;
171 }
172
173 static char *pt_utils_trim_space(char *string)
174 {
175         return pt_utils_rtrim(pt_utils_ltrim(string));
176 }
177
178 static char *pt_utils_trim_prefix(const char *string, const char *prefix)
179 {
180         PT_RETV_IF(string == NULL, NULL, "string is NULL");
181         PT_RETV_IF(prefix == NULL, NULL, "prefix is NULL");
182
183         char *buffer = NULL;
184         char *ret = NULL;
185
186         if (strlen(string) <= strlen(prefix)) {
187                 PT_DEBUG("(%s) is greater than (%s)",string, prefix);
188                 return NULL;
189         }
190         if (strncasecmp(string, prefix, strlen(prefix)) == 0) {
191                 buffer = strdup(string + strlen(prefix));
192                 PT_RETV_IF(buffer == NULL, NULL, "Not enough memory");
193                 ret = pt_utils_trim_space(buffer);
194                 PT_IF_FREE_MEM(buffer);
195                 PT_RETV_IF(ret == NULL, NULL, "Not enough memory");
196                 buffer = strdup(ret);
197                 PT_RETV_IF(buffer == NULL, NULL, "Not enough memory");
198         }
199
200         return buffer;
201 }
202
203 int pt_utils_get_mfg_mdl(const char *printer, char **mfg, char **mdl)
204 {
205         PT_RETV_IF(printer == NULL || mfg == NULL || mdl == NULL , PT_ERR_FAIL, "Invalid argument");
206
207         const char *vendor[3] = {"Samsung", "HP", "Epson"};
208         int     index   = 0;
209
210         if (strcasestr(printer, vendor[0]) != NULL) {
211                 index = 0;
212         } else if (strcasestr(printer, vendor[1]) != NULL) {
213                 index = 1;
214         } else if (strcasestr(printer, vendor[2]) != NULL) {
215                 index = 2;
216         } else {
217                 PT_DEBUG("Unsupported printer %s", printer);
218                 return PT_ERR_UNSUPPORTED;
219         }
220
221         *mfg = strdup(vendor[index]);
222         PT_RETV_IF(*mfg == NULL, PT_ERR_NO_MEMORY, "Not enough memory");
223
224         char *temp1 = NULL;
225         char *buffer = strdup(printer);
226         PT_RETV_IF(buffer == NULL, PT_ERR_NO_MEMORY, "Not enough memory");
227
228         //Patch unusual HP modelname case
229         if (strcasestr(*mfg, "HP") != NULL) {
230                 while(strncasecmp(buffer, "Hewlett-Packard", strlen("Hewlett-Packard")) == 0) {
231                         temp1 = pt_utils_trim_prefix(buffer, "Hewlett-Packard");
232                         PT_IF_FREE_MEM(buffer);
233                         PT_RETV_IF(temp1 == NULL, PT_ERR_INVALID_PARAM, "Invalid value");
234                         buffer = temp1;
235                 }
236         }
237
238         // It can include Manufacturer twice in printer name.
239         while(strncasecmp(buffer, vendor[index], strlen(vendor[index])) == 0) {
240                 temp1 = pt_utils_trim_prefix(buffer, vendor[index]);
241                 PT_IF_FREE_MEM(buffer);
242                 PT_RETV_IF(temp1 == NULL, PT_ERR_INVALID_PARAM, "Invalid value");
243                 buffer = temp1;
244         }
245         *mdl = buffer;
246         return PT_ERR_NONE;
247 }
248
249 static long _pt_get_file_length(const char *filename)
250 {
251
252         struct stat file_info;
253         long len;
254
255         if (stat(filename, &file_info)) {
256                 PT_DEBUG("File %s stat error", filename);
257                 len = 0;
258         } else {
259                 PT_DEBUG("File size = %d", file_info.st_size);
260                 len = file_info.st_size;
261         }
262
263         return len;
264 }
265
266 int _pt_filecopy(const char *org_file_path, const char *dest_file_path)
267 {
268         FILE *src = NULL;
269         FILE *dest = NULL;
270         char *buffer = NULL;
271         size_t len = 0;
272
273         PT_RETV_IF(org_file_path==NULL, -1, "org_file_path is NULL");
274         PT_RETV_IF(dest_file_path==NULL, -1, "dest_file_path is NULL");
275
276         if (!strcmp(org_file_path, dest_file_path)) {
277                 PT_DEBUG("org_file_path is same with dest_file_path");
278                 return -1;
279         }
280
281         if ((src  = fopen(org_file_path, "rb")) == NULL) {
282                 PT_DEBUG("Failed to open %s",org_file_path);
283                 return -1;
284         }
285
286         if (access(dest_file_path, F_OK) == 0) {
287                 PT_DEBUG("It exists already");
288                 fclose(src);
289                 return 0;
290         }
291
292         long src_length = _pt_get_file_length(org_file_path);
293         if (src_length <= 0) {
294                 PT_DEBUG("failed to get file length(%ld)",src_length);
295                 fclose(src);
296                 return -1;
297         }
298
299         if ((dest = fopen(dest_file_path, "wb")) == NULL) {
300                 fclose(src);
301                 PT_DEBUG("Failed to open %s",dest_file_path);
302                 return -1;
303         }
304
305         buffer =        (char *) malloc(MAX_PPDGZ_SIZE);
306         if (buffer == NULL) {
307                 fclose(src);
308                 fclose(dest);
309                 PT_DEBUG("Not enough memory");
310                 return -1;
311         }
312
313         while (1) {
314                 len = fread(buffer, sizeof(char), MAX_PPDGZ_SIZE, src);
315                 if (len < MAX_PPDGZ_SIZE) {
316                         if (feof(src) != 0) {
317                                 fwrite(buffer, sizeof(char), len, dest);
318                                 break;
319                         } else {
320                                 PT_DEBUG("Failed to write output file");
321                                 fclose(src);
322                                 fclose(dest);
323                                 free(buffer);
324                                 unlink(dest_file_path);
325                                 return -1;
326                         }
327                 }
328                 fwrite(buffer, sizeof(char), MAX_PPDGZ_SIZE, dest);
329         }
330         fclose(src);
331         fclose(dest);
332         free(buffer);
333
334         long dest_length = _pt_get_file_length(dest_file_path);
335         if (src_length != dest_length) {
336                 PT_DEBUG("file length is diffrent(%ld, %ld)",src_length, dest_length);
337                 return -1;
338         }
339
340         return 0;
341 }
342
343 void pt_utils_remove_files_in(const char *path)
344 {
345         PT_RET_IF(path == NULL, "path is NULL");
346         char *cwd;
347         struct dirent *entry;
348         int ret = 1;
349         int iret = -1;
350         DIR *dir;
351
352         cwd = get_current_dir_name();
353
354         errno = 0;
355         ret = chdir(path);
356         if (ret == 0) {
357                 dir = opendir(path);
358                 if (dir == NULL) {
359                         PT_IF_FREE_MEM(cwd);
360                         return;
361                 }
362                 while ((entry = readdir(dir)) != NULL) {
363                         PT_DEBUG("Remove %s", entry->d_name);
364                         iret = remove(entry->d_name);
365                         if (iret == -1) {
366                                 PT_DEBUG("unable to remove %s",entry->d_name);
367                         }
368                 }
369                 closedir(dir);
370
371                 iret = chdir(cwd);
372                 PT_IF_FREE_MEM(cwd);
373                 PT_RET_IF(iret == -1, "unable to chdir");
374         } else {
375                 if (errno == ENOENT) {
376                         PT_DEBUG("Not existed %s, just skip", path);
377                 }
378         }
379         PT_IF_FREE_MEM(cwd);
380         return;
381 }