1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5  *
6  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include "ifc_print_job.h"
26 #include "wprint_debug.h"
27 
28 #define TAG "plugin_pdf"
29 #define BUFF_SIZE 8192
30 
31 extern int g_API_version;
32 
33 typedef struct {
34     const ifc_wprint_t *wprint_ifc;
35     const ifc_print_job_t *print_ifc;
36 } plugin_data_t;
37 
38 static const char *_mime_types[] = {
39         MIME_TYPE_PDF,
40         NULL};
41 
42 static const char *_print_formats[] = {
43         PRINT_FORMAT_PDF,
44         NULL};
45 
_get_mime_types(void)46 static const char **_get_mime_types(void) {
47     return _mime_types;
48 }
49 
_get_print_formats(void)50 static const char **_get_print_formats(void) {
51     return _print_formats;
52 }
53 
_start_job(wJob_t job_handle,const ifc_wprint_t * wprint_ifc_p,const ifc_print_job_t * print_job_ifc_p,wprint_job_params_t * job_params)54 static int _start_job(wJob_t job_handle, const ifc_wprint_t *wprint_ifc_p,
55         const ifc_print_job_t *print_job_ifc_p,
56         wprint_job_params_t *job_params) {
57     plugin_data_t *priv;
58     if (job_params == NULL) return ERROR;
59 
60     job_params->plugin_data = NULL;
61     if ((wprint_ifc_p == NULL) || (print_job_ifc_p == NULL)) return ERROR;
62 
63     priv = (plugin_data_t *) malloc(sizeof(plugin_data_t));
64     priv->wprint_ifc = (ifc_wprint_t *) wprint_ifc_p;
65     priv->print_ifc = (ifc_print_job_t *) print_job_ifc_p;
66 
67     job_params->plugin_data = (void *) priv;
68     return OK;
69 }
70 
_print_page(wprint_job_params_t * job_params,const char * mime_type,const char * pathname)71 static int _print_page(wprint_job_params_t *job_params, const char *mime_type,
72         const char *pathname) {
73     plugin_data_t *priv;
74     int fd;
75     int result = OK;
76     int rbytes, wbytes, nbytes = 0;
77     char *buff;
78 
79     if (job_params == NULL) return ERROR;
80 
81     priv = (plugin_data_t *) job_params->plugin_data;
82 
83     if (priv == NULL) return ERROR;
84 
85     //  open the PDF file and dump it to the socket
86     if (pathname && strlen(pathname)) {
87         buff = malloc(BUFF_SIZE);
88         if (buff == NULL) {
89             return ERROR;
90         }
91 
92         fd = open(pathname, O_RDONLY);
93         if (fd != ERROR) {
94             rbytes = read(fd, buff, BUFF_SIZE);
95 
96             while ((rbytes > 0) && !job_params->cancelled) {
97                 wbytes = priv->print_ifc->send_data(priv->print_ifc, buff, rbytes);
98                 if (wbytes == rbytes) {
99                     nbytes += wbytes;
100                     rbytes = read(fd, buff, BUFF_SIZE);
101                 } else {
102                     LOGE("ERROR: write() failed, %s", strerror(errno));
103                     result = ERROR;
104                     break;
105                 }
106             }
107             LOGI("dumped %d bytes of %s to printer", nbytes, pathname);
108             close(fd);
109         }
110 
111         free(buff);
112     }
113     if ((job_params->page_range != NULL) && (strcmp(job_params->page_range, "") != 0)) {
114         remove(pathname);
115     }
116     return result;
117 }
118 
_end_job(wprint_job_params_t * job_params)119 static int _end_job(wprint_job_params_t *job_params) {
120     if (job_params != NULL) {
121         if (job_params->plugin_data != NULL) {
122             free(job_params->plugin_data);
123         }
124     }
125     return OK;
126 }
127 
libwprintplugin_pdf_reg(void)128 wprint_plugin_t *libwprintplugin_pdf_reg(void) {
129     static const wprint_plugin_t _pdf_plugin = {.version = WPRINT_PLUGIN_VERSION(0),
130             .priority = PRIORITY_PASSTHRU, .get_mime_types = _get_mime_types,
131             .get_print_formats = _get_print_formats, .start_job = _start_job,
132             .print_page = _print_page, .print_blank_page = NULL, .end_job = _end_job,};
133     return ((wprint_plugin_t *) &_pdf_plugin);
134 }
135