1 /* -*- c-basic-offset: 8 -*- 2 rdesktop: A Remote Desktop Protocol client. 3 Copyright (C) Matthew Chapman 1999-2005 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #include "rdesktop.h" 21 22 static PRINTER * 23 get_printer_data(RDPCLIENT * This, NTHANDLE handle) 24 { 25 int index; 26 27 for (index = 0; index < RDPDR_MAX_DEVICES; index++) 28 { 29 if (handle == This->rdpdr_device[index].handle) 30 return (PRINTER *) This->rdpdr_device[index].pdevice_data; 31 } 32 return NULL; 33 } 34 35 int 36 printer_enum_devices(RDPCLIENT * This, uint32 * id, char *optarg) 37 { 38 PRINTER *pprinter_data; 39 40 char *pos = optarg; 41 char *pos2; 42 int count = 0; 43 int already = 0; 44 45 /* we need to know how many printers we've already set up 46 supplied from other -r flags than this one. */ 47 while (count < *id) 48 { 49 if (This->rdpdr_device[count].device_type == DEVICE_TYPE_PRINTER) 50 already++; 51 count++; 52 } 53 54 count = 0; 55 56 if (*optarg == ':') 57 optarg++; 58 59 while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES) 60 { 61 pprinter_data = (PRINTER *) xmalloc(sizeof(PRINTER)); 62 63 strcpy(This->rdpdr_device[*id].name, "PRN"); 64 strcat(This->rdpdr_device[*id].name, l_to_a(already + count + 1, 10)); 65 66 /* first printer is set as default printer */ 67 if ((already + count) == 0) 68 pprinter_data->default_printer = True; 69 else 70 pprinter_data->default_printer = False; 71 72 pos2 = next_arg(optarg, '='); 73 if (*optarg == (char) 0x00) 74 pprinter_data->printer = "mydeskjet"; /* set default */ 75 else 76 { 77 pprinter_data->printer = xmalloc(strlen(optarg) + 1); 78 strcpy(pprinter_data->printer, optarg); 79 } 80 81 if (!pos2 || (*pos2 == (char) 0x00)) 82 pprinter_data->driver = "HP Color LaserJet 8500 PS"; /* no printer driver supplied set default */ 83 else 84 { 85 pprinter_data->driver = xmalloc(strlen(pos2) + 1); 86 strcpy(pprinter_data->driver, pos2); 87 } 88 89 printf("PRINTER %s to %s driver %s\n", This->rdpdr_device[*id].name, 90 pprinter_data->printer, pprinter_data->driver); 91 This->rdpdr_device[*id].device_type = DEVICE_TYPE_PRINTER; 92 This->rdpdr_device[*id].pdevice_data = (void *) pprinter_data; 93 count++; 94 (*id)++; 95 96 optarg = pos; 97 } 98 return count; 99 } 100 101 static NTSTATUS 102 printer_create(RDPCLIENT * This, uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition, uint32 flags, 103 char *filename, NTHANDLE * handle) 104 { 105 char cmd[256]; 106 PRINTER *pprinter_data; 107 108 pprinter_data = (PRINTER *) This->rdpdr_device[device_id].pdevice_data; 109 110 /* default printer name use default printer queue as well in unix */ 111 if (pprinter_data->printer == "mydeskjet") 112 { 113 pprinter_data->printer_fp = popen("lpr", "w"); 114 } 115 else 116 { 117 sprintf(cmd, "lpr -P %s", pprinter_data->printer); 118 pprinter_data->printer_fp = popen(cmd, "w"); 119 } 120 121 This->rdpdr_device[device_id].handle = fileno(pprinter_data->printer_fp); 122 *handle = This->rdpdr_device[device_id].handle; 123 return STATUS_SUCCESS; 124 } 125 126 static NTSTATUS 127 printer_close(RDPCLIENT * This, NTHANDLE handle) 128 { 129 int i = get_device_index(This, handle); 130 if (i >= 0) 131 { 132 PRINTER *pprinter_data = This->rdpdr_device[i].pdevice_data; 133 if (pprinter_data) 134 pclose(pprinter_data->printer_fp); 135 This->rdpdr_device[i].handle = 0; 136 } 137 return STATUS_SUCCESS; 138 } 139 140 static NTSTATUS 141 printer_write(RDPCLIENT * This, NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) 142 { 143 PRINTER *pprinter_data; 144 145 pprinter_data = get_printer_data(This, handle); 146 *result = length * fwrite(data, length, 1, pprinter_data->printer_fp); 147 148 if (ferror(pprinter_data->printer_fp)) 149 { 150 *result = 0; 151 return STATUS_INVALID_HANDLE; 152 } 153 return STATUS_SUCCESS; 154 } 155 156 DEVICE_FNS printer_fns = { 157 printer_create, 158 printer_close, 159 NULL, /* read */ 160 printer_write, 161 NULL /* device_control */ 162 }; 163