d83421a934d62b332f577970a4e84e94b91a773a
[apps/core/preloaded/print-service.git] / src / pt_ppd.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 #include <stdio.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <dirent.h>
25 #include <unistd.h>
26 #include <limits.h>
27 #include <stdlib.h>
28
29 #include <pt_db.h>
30 #include "pt_debug.h"
31 #include "pt_common.h"
32 #include "pt_ppd.h"
33
34 #define GETPPD "/usr/bin/getppd"
35 #define CUPS_PPDDIR "/opt/etc/cups/ppd/"
36 #define SAMSUNG_DRV "/opt/etc/cups/ppd/samsung/samsung.drv"
37 #define SAMSUNG_DRV_GZ "/opt/etc/cups/ppd/samsung/samsung.drv.gz"
38 #define SAMSUNG_DRV_GZ_ORG "/usr/share/cups/ppd/samsung/samsung.drv.gz"
39 #define HP_DRV "/opt/etc/cups/ppd/hp/hp.drv"
40 #define HP_DRV_GZ "/opt/etc/cups/ppd/hp/hp.drv.gz"
41 #define HP_DRV_GZ_ORG "/usr/share/cups/ppd/hp/hp.drv.gz"
42 #define EPSON_DRV "/opt/etc/cups/ppd/epson/epson.drv"
43 #define EPSON_DRV_GZ "/opt/etc/cups/ppd/epson/epson.drv.gz"
44 #define EPSON_DRV_GZ_ORG "/usr/share/cups/ppd/epson/epson.drv.gz"
45 #define SAMSUNG_PPD_DIR "/opt/etc/cups/ppd/samsung"
46 #define EPSON_PPD_DIR "/opt/etc/cups/ppd/epson"
47 #define HP_PPD_DIR "/opt/etc/cups/ppd/hp"
48
49 #define PPDC_PREFIX "ppdc: Writing ./"
50
51 /*supported manufacturer printer*/
52 const char *manufacturer[MANUFACTURER_NUM] = {"Samsung", "Hp", "Epson"};
53
54 ppd_size_t *pt_utils_paper_size_pts(const char *name)
55 {
56         return ppdPageSize(ppd, name);
57 }
58
59 /**
60  *      This function let the app get ppd file for the specified printer
61  *      @return    If success, return PT_ERR_NONE, else return PT_ERR_FAIL
62  *      @param[in] ppd the pointer to the printer's ppd path
63  *      @param[in] printer the printer entry
64  */
65 int pt_get_printer_ppd(pt_printer_mgr_t *printer)
66 {
67         PRINT_SERVICE_FUNC_ENTER;
68         PT_RETV_IF(printer == NULL, PT_ERR_INVALID_PARAM, "printer is NULL");
69         PT_RETV_IF(printer->mfg == NULL, PT_ERR_INVALID_PARAM, "printer mfg is NULL");
70         PT_RETV_IF(printer->mdl == NULL, PT_ERR_INVALID_PARAM, "printer mdl is NULL");
71
72         PT_DEBUG("product: %s", printer->name);
73         PT_DEBUG("printer->mdl %s", printer->mdl);
74         PT_DEBUG("printer->mfg %s", printer->mfg);
75
76         FILE *result = NULL;
77
78         char gunzip_drv[PT_MAX_LENGTH] = {0,};
79
80         static pt_db *db_samsung = NULL;
81         static pt_db *db_epson = NULL;
82         static pt_db *db_hp = NULL;
83         char *output = NULL;
84
85         if (strncasecmp(printer->mfg, "Samsung", 7) == 0) {
86                 if (chdir(SAMSUNG_PPD_DIR)) {
87                         PT_DEBUG("Failed to change directory");
88                         return PT_ERR_FAIL;
89                 }
90                 if (access(SAMSUNG_DRV, F_OK) != 0) {
91                         int ret = _pt_filecopy(SAMSUNG_DRV_GZ_ORG, SAMSUNG_DRV_GZ);
92                         if (ret != 0) {
93                                 PT_DEBUG("Failed to copy file");
94                                 return PT_ERR_FAIL;
95                         }
96                         snprintf(gunzip_drv, PT_MAX_LENGTH, "gzip -d %s", SAMSUNG_DRV_GZ);
97                         result = popen(gunzip_drv, "r");
98                         if (result == NULL) {
99                                 PT_DEBUG("%s is failed to popen error",gunzip_drv);
100                                 return PT_ERR_FAIL;
101                         }
102                         pclose(result);
103                 }
104                 if(!db_samsung) {
105                         db_samsung = pt_create_db(SAMSUNG_DRV);
106                         PT_DEBUG("db_samsung: %p", db_samsung);
107                         if(!db_samsung) {
108                                 PT_DEBUG("Failed to create samsung database");
109                                 return PT_ERR_FAIL;
110                         }
111                 }
112                 output = pt_extract_ppd(db_samsung, printer->mdl, PT_SEARCH_ALL);
113
114         } else if (strncasecmp(printer->mfg, "Hp", 2) == 0) {
115                 if (chdir(HP_PPD_DIR)) {
116                         PT_DEBUG("Failed to change directory");
117                         return PT_ERR_FAIL;
118                 }
119                 if (access(HP_DRV, F_OK) != 0) {
120                         int ret = _pt_filecopy(HP_DRV_GZ_ORG, HP_DRV_GZ);
121                         if (ret != 0) {
122                                 PT_DEBUG("Failed to copy file");
123                                 return PT_ERR_FAIL;
124                         }
125                         snprintf(gunzip_drv, PT_MAX_LENGTH, "gzip -d %s", HP_DRV_GZ);
126                         result = popen(gunzip_drv, "r");
127                         if (result == NULL) {
128                                 PT_DEBUG("%s is failed to popen error",gunzip_drv);
129                                 return PT_ERR_FAIL;
130                         }
131                         pclose(result);
132                 }
133                 if(!db_hp) {
134                         db_hp = pt_create_db(HP_DRV);
135                         if(!db_hp) {
136                                 PT_DEBUG("Failed to create hp database");
137                                 return PT_ERR_FAIL;
138                         }
139                 }
140                 output = pt_extract_ppd(db_hp, printer->mdl, PT_SEARCH_ALL);
141         } else if (strncasecmp(printer->mfg, "Epson", 5) == 0) {
142                 if (chdir(EPSON_PPD_DIR)) {
143                         PT_DEBUG("Failed to change directory");
144                         return PT_ERR_FAIL;
145                 }
146                 if (access(EPSON_DRV, F_OK) != 0) {
147                         int ret = _pt_filecopy(EPSON_DRV_GZ_ORG, EPSON_DRV_GZ);
148                         if (ret != 0) {
149                                 PT_DEBUG("Failed to copy file");
150                                 return PT_ERR_FAIL;
151                         }
152                         snprintf(gunzip_drv, PT_MAX_LENGTH, "gzip -d %s", EPSON_DRV_GZ);
153                         result = popen(gunzip_drv, "r");
154                         if (result == NULL) {
155                                 PT_DEBUG("%s is failed to popen error",gunzip_drv);
156                                 return PT_ERR_FAIL;
157                         }
158                         pclose(result);
159                 }
160                 if(!db_epson) {
161                         db_epson = pt_create_db(EPSON_DRV);
162                         if(!db_epson) {
163                                 PT_DEBUG("Failed to create epson database");
164                                 return PT_ERR_FAIL;
165                         }
166                 }
167                 output = pt_extract_ppd(db_epson, printer->mdl, PT_SEARCH_ALL);
168         } else {
169                 PT_DEBUG("Can't find PPD file");
170                 return PT_ERR_FAIL;
171         }
172
173         if(!output) {
174                 PT_DEBUG("Can't find PPD file");
175                 return PT_ERR_FAIL;
176         }
177
178         char *filename = NULL;
179         gboolean res = g_str_has_prefix(output, PPDC_PREFIX);
180         if(res == TRUE) {
181                 size_t len = strlen(PPDC_PREFIX);
182                 filename = output+len;
183                 size_t sublen = strlen(filename);
184                 gboolean expected_suffix = g_str_has_suffix(filename, ".\n");
185                 if(expected_suffix == TRUE) {
186                         filename[sublen-2] = '\0';
187                 } else {
188                         PT_DEBUG("ppdc returned unexpected output:\n%s\n", output);
189                         free(output);
190                         return PT_ERR_FAIL;
191                 }
192         } else {
193                 PT_DEBUG("ppdc returned unexpected output:\n%s\n", output);
194                 free(output);
195                 return PT_ERR_FAIL;
196         }
197
198         char *abspath = realpath(filename, NULL);
199         if(!abspath) {
200                 PT_DEBUG("pathname canonicalization fails\n");
201                 free(output);
202                 return PT_ERR_FAIL;
203         }
204
205         if(strlen(abspath) >= PT_MAX_LENGTH) {
206                 PT_DEBUG("ppd filename too long\n");
207                 free(output);
208                 return PT_ERR_FAIL;
209         }
210
211         memset(printer->ppd, '\0', PT_MAX_LENGTH);
212
213         strncpy(printer->ppd, abspath, PT_MAX_LENGTH-1);
214         free(abspath);
215         free(output);
216         PRINT_SERVICE_FUNC_LEAVE;
217         return PT_ERR_NONE;
218 }