├── .gitignore ├── CUPS-PDF_noopt.ppd ├── CUPS-PDF_opt.ppd ├── LICENSE ├── README.md ├── cups-pdf.c ├── cups-pdf.conf └── cups-pdf.h /.gitignore: -------------------------------------------------------------------------------- 1 | cups-pdf 2 | *.bak 3 | -------------------------------------------------------------------------------- /CUPS-PDF_noopt.ppd: -------------------------------------------------------------------------------- 1 | *PPD-Adobe: "4.3" 2 | *% 3 | *% "$Id: postscript.ppd,v 1.1.1.1 2000/08/24 19:23:13 goffioul Exp $" 4 | *% 5 | *% Sample Postscript driver PPD file for the Common UNIX Printing 6 | *% System (CUPS). 7 | *% 8 | *% Michael Goffioul 9 | *% 10 | *% Changes to the original file by Volker Behr, Martin-Eric Racine, 11 | *% Nickolay Kondrashov and other contributors: 12 | *% added IEEE-1284 device id - 2008-03-24 13 | *% added custom page size - 2006-05-18 14 | *% replaced page descriptions - 2006-05-18 15 | *% InputSlot constraints removed - 2006-05-11 16 | *% maxed out imageable regions - 2006-05-11 17 | *% added pstitleiconv filter - 2006-05-11 18 | *% added ledger paper size - 2006-01-29 19 | *% match Adobe specifications - 2005-12-23 20 | *% additional paper formats - 2005-02-03 and 2005-02-07 21 | *% made A4 default paper size - 2005-02-03 22 | *% Color enabled - 2003-12-02 23 | *% 24 | *FormatVersion: "4.3" 25 | *FileVersion: "1.1" 26 | *LanguageVersion: English 27 | *LanguageEncoding: ISOLatin1 28 | *PCFileName: "CUPS-PDF.PPD" 29 | *Manufacturer: "Generic" 30 | *Product: "(CUPS v1.1)" 31 | *ModelName: "Generic CUPS-PDF Printer" 32 | *ShortNickName: "Generic CUPS-PDF Printer" 33 | *NickName: "Generic CUPS-PDF Printer (no options)" 34 | *% 1284DeviceID: "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;" 35 | *1284DeviceID: "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;" 36 | *% cupsFilter: "application/vnd.cups-postscript 100 pstitleiconv" 37 | *% cupsFilter: "application/vnd.cups-pdf 0 pstitleiconv" 38 | *cupsFilter: "application/pdf 0 -" 39 | *PSVersion: "(2017.000) 0" 40 | *LanguageLevel: "2" 41 | *ColorDevice: True 42 | *DefaultColorSpace: RGB 43 | *FileSystem: False 44 | *Throughput: "8" 45 | *LandscapeOrientation: Plus90 46 | *TTRasterizer: Type42 47 | 48 | *HWMargins: 0 0 0 0 49 | *VariablePaperSize: True 50 | *MaxMediaWidth: 100000 51 | *MaxMediaHeight: 100000 52 | *NonUIOrderDependency: 100 AnySetup *CustomPageSize 53 | *CustomPageSize True: "pop pop pop 54 | <>setpagedevice" 55 | *End 56 | *ParamCustomPageSize Width: 1 points 36 100000 57 | *ParamCustomPageSize Height: 2 points 36 100000 58 | *ParamCustomPageSize Orientation: 3 int 0 3 59 | *ParamCustomPageSize WidthOffset: 4 points 0 0 60 | *ParamCustomPageSize HeightOffset: 5 points 0 0 61 | 62 | *OpenGroup: General/General 63 | 64 | *OpenUI *PageSize/Page Size: PickOne 65 | *OrderDependency: 100 AnySetup *PageSize 66 | *DefaultPageSize: Letter 67 | *PageSize 11x14/11x14: "<>setpagedevice" 68 | *PageSize 11x17/11x17: "<>setpagedevice" 69 | *PageSize 13x19/13x19: "<>setpagedevice" 70 | *PageSize 16x20/16x20: "<>setpagedevice" 71 | *PageSize 16x24/16x24: "<>setpagedevice" 72 | *PageSize 2A/2A: "<>setpagedevice" 73 | *PageSize 4A/4A: "<>setpagedevice" 74 | *PageSize 8x10/8x10: "<>setpagedevice" 75 | *PageSize 8x12/8x12: "<>setpagedevice" 76 | *PageSize A0/A0: "<>setpagedevice" 77 | *PageSize A1/A1: "<>setpagedevice" 78 | *PageSize A2/A2: "<>setpagedevice" 79 | *PageSize A3/A3: "<>setpagedevice" 80 | *PageSize A4/A4: "<>setpagedevice" 81 | *PageSize A5/A5: "<>setpagedevice" 82 | *PageSize AnsiA/ANSI A: "<>setpagedevice" 83 | *PageSize AnsiB/ANSI B: "<>setpagedevice" 84 | *PageSize AnsiC/ANSI C: "<>setpagedevice" 85 | *PageSize AnsiD/ANSI D: "<>setpagedevice" 86 | *PageSize AnsiE/ANSI E: "<>setpagedevice" 87 | *PageSize ArchA/Arch A: "<>setpagedevice" 88 | *PageSize ArchB/Arch B: "<>setpagedevice" 89 | *PageSize ArchC/Arch C: "<>setpagedevice" 90 | *PageSize ArchD/Arch D: "<>setpagedevice" 91 | *PageSize ArchE/Arch E: "<>setpagedevice" 92 | *PageSize C0/C0: "<>setpagedevice" 93 | *PageSize C1/C1: "<>setpagedevice" 94 | *PageSize C2/C2: "<>setpagedevice" 95 | *PageSize C3/C3: "<>setpagedevice" 96 | *PageSize C4/C4: "<>setpagedevice" 97 | *PageSize C5/C5: "<>setpagedevice" 98 | *PageSize Env10/Envelope #10: "<>setpagedevice" 99 | *PageSize EnvC5/Envelope C5: "<>setpagedevice" 100 | *PageSize EnvDL/Envelope DL: "<>setpagedevice" 101 | *PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice" 102 | *PageSize Executive/Executive: "<>setpagedevice" 103 | *PageSize ISOB0/B0 (ISO): "<>setpagedevice" 104 | *PageSize ISOB1/B1 (ISO): "<>setpagedevice" 105 | *PageSize ISOB2/B2 (ISO): "<>setpagedevice" 106 | *PageSize ISOB3/B3 (ISO): "<>setpagedevice" 107 | *PageSize ISOB4/B4 (ISO): "<>setpagedevice" 108 | *PageSize ISOB5/B5 (ISO): "<>setpagedevice" 109 | *PageSize JISB0/B0 (JIS): "<>setpagedevice" 110 | *PageSize JISB1/B1 (JIS): "<>setpagedevice" 111 | *PageSize JISB2/B2 (JIS): "<>setpagedevice" 112 | *PageSize JISB3/B3 (JIS): "<>setpagedevice" 113 | *PageSize JISB4/B4 (JIS): "<>setpagedevice" 114 | *PageSize JISB5/B5 (JIS): "<>setpagedevice" 115 | *PageSize Ledger/Ledger: "<>setpagedevice" 116 | *PageSize Legal/US Legal: "<>setpagedevice" 117 | *PageSize Letter/US Letter: "<>setpagedevice" 118 | *PageSize RA0/RA0: "<>setpagedevice" 119 | *PageSize RA1/RA1: "<>setpagedevice" 120 | *PageSize RA2/RA2: "<>setpagedevice" 121 | *PageSize RA3/RA3: "<>setpagedevice" 122 | *PageSize RA4/RA4: "<>setpagedevice" 123 | *PageSize SRA0/SRA0: "<>setpagedevice" 124 | *PageSize SRA1/SRA1: "<>setpagedevice" 125 | *PageSize SRA2/SRA2: "<>setpagedevice" 126 | *PageSize SRA3/SRA3: "<>setpagedevice" 127 | *PageSize SRA4/SRA4: "<>setpagedevice" 128 | *PageSize SuperA/Super A: "<>setpagedevice" 129 | *PageSize SuperB/Super B: "<>setpagedevice" 130 | *PageSize TabloidExtra/Tabloid Extra: "<>setpagedevice" 131 | *PageSize Tabloid/Tabloid: "<>setpagedevice" 132 | *CloseUI: *PageSize 133 | 134 | *OpenUI *PageRegion: PickOne 135 | *OrderDependency: 100 AnySetup *PageRegion 136 | *DefaultPageRegion: Letter 137 | *PageRegion 11x14/11x14: "<>setpagedevice" 138 | *PageRegion 11x17/11x17: "<>setpagedevice" 139 | *PageRegion 13x19/13x19: "<>setpagedevice" 140 | *PageRegion 16x20/16x20: "<>setpagedevice" 141 | *PageRegion 16x24/16x24: "<>setpagedevice" 142 | *PageRegion 2A/2A: "<>setpagedevice" 143 | *PageRegion 4A/4A: "<>setpagedevice" 144 | *PageRegion 8x10/8x10: "<>setpagedevice" 145 | *PageRegion 8x12/8x12: "<>setpagedevice" 146 | *PageRegion A0/A0: "<>setpagedevice" 147 | *PageRegion A1/A1: "<>setpagedevice" 148 | *PageRegion A2/A2: "<>setpagedevice" 149 | *PageRegion A3/A3: "<>setpagedevice" 150 | *PageRegion A4/A4: "<>setpagedevice" 151 | *PageRegion A5/A5: "<>setpagedevice" 152 | *PageRegion AnsiA/ANSI A: "<>setpagedevice" 153 | *PageRegion AnsiB/ANSI B: "<>setpagedevice" 154 | *PageRegion AnsiC/ANSI C: "<>setpagedevice" 155 | *PageRegion AnsiD/ANSI D: "<>setpagedevice" 156 | *PageRegion AnsiE/ANSI E: "<>setpagedevice" 157 | *PageRegion ArchA/Arch A: "<>setpagedevice" 158 | *PageRegion ArchB/Arch B: "<>setpagedevice" 159 | *PageRegion ArchC/Arch C: "<>setpagedevice" 160 | *PageRegion ArchD/Arch D: "<>setpagedevice" 161 | *PageRegion ArchE/Arch E: "<>setpagedevice" 162 | *PageRegion C0/C0: "<>setpagedevice" 163 | *PageRegion C1/C1: "<>setpagedevice" 164 | *PageRegion C2/C2: "<>setpagedevice" 165 | *PageRegion C3/C3: "<>setpagedevice" 166 | *PageRegion C4/C4: "<>setpagedevice" 167 | *PageRegion C5/C5: "<>setpagedevice" 168 | *PageRegion Env10/Envelope #10: "<>setpagedevice" 169 | *PageRegion EnvC5/Envelope C5: "<>setpagedevice" 170 | *PageRegion EnvDL/Envelope DL: "<>setpagedevice" 171 | *PageRegion EnvMonarch/Envelope Monarch: "<>setpagedevice" 172 | *PageRegion Executive/Executive: "<>setpagedevice" 173 | *PageRegion ISOB0/B0 (ISO): "<>setpagedevice" 174 | *PageRegion ISOB1/B1 (ISO): "<>setpagedevice" 175 | *PageRegion ISOB2/B2 (ISO): "<>setpagedevice" 176 | *PageRegion ISOB3/B3 (ISO): "<>setpagedevice" 177 | *PageRegion ISOB4/B4 (ISO): "<>setpagedevice" 178 | *PageRegion ISOB5/B5 (ISO): "<>setpagedevice" 179 | *PageRegion JISB0/B0 (JIS): "<>setpagedevice" 180 | *PageRegion JISB1/B1 (JIS): "<>setpagedevice" 181 | *PageRegion JISB2/B2 (JIS): "<>setpagedevice" 182 | *PageRegion JISB3/B3 (JIS): "<>setpagedevice" 183 | *PageRegion JISB4/B4 (JIS): "<>setpagedevice" 184 | *PageRegion JISB5/B5 (JIS): "<>setpagedevice" 185 | *PageRegion Ledger/Ledger: "<>setpagedevice" 186 | *PageRegion Legal/US Legal: "<>setpagedevice" 187 | *PageRegion Letter/US Letter: "<>setpagedevice" 188 | *PageRegion RA0/RA0: "<>setpagedevice" 189 | *PageRegion RA1/RA1: "<>setpagedevice" 190 | *PageRegion RA2/RA2: "<>setpagedevice" 191 | *PageRegion RA3/RA3: "<>setpagedevice" 192 | *PageRegion RA4/RA4: "<>setpagedevice" 193 | *PageRegion SRA0/SRA0: "<>setpagedevice" 194 | *PageRegion SRA1/SRA1: "<>setpagedevice" 195 | *PageRegion SRA2/SRA2: "<>setpagedevice" 196 | *PageRegion SRA3/SRA3: "<>setpagedevice" 197 | *PageRegion SRA4/SRA4: "<>setpagedevice" 198 | *PageRegion SuperA/Super A: "<>setpagedevice" 199 | *PageRegion SuperB/Super B: "<>setpagedevice" 200 | *PageRegion TabloidExtra/Tabloid Extra: "<>setpagedevice" 201 | *PageRegion Tabloid/Tabloid: "<>setpagedevice" 202 | *CloseUI: *PageRegion 203 | 204 | *DefaultImageableArea: Letter 205 | *ImageableArea 11x14/11x14: "0 0 792 1008" 206 | *ImageableArea 11x17/11x17: "0 0 792 1224" 207 | *ImageableArea 13x19/13x19: "0 0 936 1368" 208 | *ImageableArea 16x20/16x20: "0 0 1152 1440" 209 | *ImageableArea 16x24/16x24: "0 0 1152 1728" 210 | *ImageableArea 2A/2A: "0 0 3370 4768" 211 | *ImageableArea 4A/4A: "0 0 4768 6749" 212 | *ImageableArea 8x10/8x10: "0 0 576 720" 213 | *ImageableArea 8x12/8x12: "0 0 576 864" 214 | *ImageableArea A0/A0: "0 0 2384 3370" 215 | *ImageableArea A1/A1: "0 0 1684 2384" 216 | *ImageableArea A2/A2: "0 0 1191 1684" 217 | *ImageableArea A3/A3: "0 0 842 1191" 218 | *ImageableArea A4/A4: "0 0 595 842" 219 | *ImageableArea A5/A5: "0 0 421 595" 220 | *ImageableArea AnsiA/ANSI A: "0 0 612 792" 221 | *ImageableArea AnsiB/ANSI B: "0 0 792 1224" 222 | *ImageableArea AnsiC/ANSI C: "0 0 1224 1584" 223 | *ImageableArea AnsiD/ANSI D: "0 0 1584 2448" 224 | *ImageableArea AnsiE/ANSI E: "0 0 2448 3168" 225 | *ImageableArea ArchA/Arch A: "0 0 648 864" 226 | *ImageableArea ArchB/Arch B: "0 0 864 1296" 227 | *ImageableArea ArchC/Arch C: "0 0 1296 1728" 228 | *ImageableArea ArchD/Arch D: "0 0 1728 2592" 229 | *ImageableArea ArchE/Arch E: "0 0 2592 3456" 230 | *ImageableArea C0/C0: "0 0 2599 3676" 231 | *ImageableArea C1/C1: "0 0 1836 2599" 232 | *ImageableArea C2/C2: "0 0 1298 1836" 233 | *ImageableArea C3/C3: "0 0 918 1298" 234 | *ImageableArea C4/C4: "0 0 649 918" 235 | *ImageableArea C5/C5: "0 0 459 649" 236 | *ImageableArea Env10/Envelope #10: "0 0 297 684" 237 | *ImageableArea EnvC5/Envelope C5: "0 0 459 649" 238 | *ImageableArea EnvDL/Envelope DL: "0 0 312 624" 239 | *ImageableArea EnvMonarch/Envelope Monarch: "0 0 279 540" 240 | *ImageableArea Executive/Executive: "0 0 522 756" 241 | *ImageableArea ISOB0/B0 (ISO): "0 0 2834 4008" 242 | *ImageableArea ISOB1/B1 (ISO): "0 0 2004 2834" 243 | *ImageableArea ISOB2/B2 (ISO): "0 0 1417 2004" 244 | *ImageableArea ISOB3/B3 (ISO): "0 0 1000 1417" 245 | *ImageableArea ISOB4/B4 (ISO): "0 0 708 1000" 246 | *ImageableArea ISOB5/B5 (ISO): "0 0 498 708" 247 | *ImageableArea JISB0/B0 (JIS): "0 0 2919 4127" 248 | *ImageableArea JISB1/B1 (JIS): "0 0 2063 2919" 249 | *ImageableArea JISB2/B2 (JIS): "0 0 1459 2063" 250 | *ImageableArea JISB3/B3 (JIS): "0 0 1029 1459" 251 | *ImageableArea JISB4/B4 (JIS): "0 0 727 1029" 252 | *ImageableArea JISB5/B5 (JIS): "0 0 518 727" 253 | *ImageableArea Ledger/Ledger: "0 0 1224 792" 254 | *ImageableArea Legal/US Legal: "0 0 612 1008" 255 | *ImageableArea Letter/US Letter: "0 0 612 792" 256 | *ImageableArea RA0/RA0: "0 0 2437 3458" 257 | *ImageableArea RA1/RA1: "0 0 1729 2437" 258 | *ImageableArea RA2/RA2: "0 0 1218 1729" 259 | *ImageableArea RA3/RA3: "0 0 864 1218" 260 | *ImageableArea RA4/RA4: "0 0 609 864" 261 | *ImageableArea SRA0/SRA0: "0 0 2551 3628" 262 | *ImageableArea SRA1/SRA1: "0 0 1814 2551" 263 | *ImageableArea SRA2/SRA2: "0 0 1275 1814" 264 | *ImageableArea SRA3/SRA3: "0 0 907 1275" 265 | *ImageableArea SRA4/SRA4: "0 0 637 907" 266 | *ImageableArea SuperA/Super A: "0 0 644 1008" 267 | *ImageableArea SuperB/Super B: "0 0 936 1368" 268 | *ImageableArea TabloidExtra/Tabloid Extra: "0 0 864 1296" 269 | *ImageableArea Tabloid/Tabloid: "0 0 792 1224" 270 | 271 | *DefaultPaperDimension: Letter 272 | *PaperDimension 11x14/11x14: "792 1008" 273 | *PaperDimension 11x17/11x17: "792 1224" 274 | *PaperDimension 13x19/13x19: "936 1368" 275 | *PaperDimension 16x20/16x20: "1152 1440" 276 | *PaperDimension 16x24/16x24: "1152 1728" 277 | *PaperDimension 2A/2A: "3370 4768" 278 | *PaperDimension 4A/4A: "4768 6749" 279 | *PaperDimension 8x10/8x10: "576 720" 280 | *PaperDimension 8x12/8x12: "576 864" 281 | *PaperDimension A0/A0: "2384 3370" 282 | *PaperDimension A1/A1: "1684 2384" 283 | *PaperDimension A2/A2: "1191 1684" 284 | *PaperDimension A3/A3: "842 1191" 285 | *PaperDimension A4/A4: "595 842" 286 | *PaperDimension A5/A5: "421 595" 287 | *PaperDimension AnsiA/ANSI A: "612 792" 288 | *PaperDimension AnsiB/ANSI B: "792 1224" 289 | *PaperDimension AnsiC/ANSI C: "1224 1584" 290 | *PaperDimension AnsiD/ANSI D: "1584 2448" 291 | *PaperDimension AnsiE/ANSI E: "2448 3168" 292 | *PaperDimension ArchA/Arch A: "648 864" 293 | *PaperDimension ArchB/Arch B: "864 1296" 294 | *PaperDimension ArchC/Arch C: "1296 1728" 295 | *PaperDimension ArchD/Arch D: "1728 2592" 296 | *PaperDimension ArchE/Arch E: "2592 3456" 297 | *PaperDimension C0/C0: "2599 3676" 298 | *PaperDimension C1/C1: "1836 2599" 299 | *PaperDimension C2/C2: "1298 1836" 300 | *PaperDimension C3/C3: "918 1298" 301 | *PaperDimension C4/C4: "649 918" 302 | *PaperDimension C5/C5: "459 649" 303 | *PaperDimension Env10/Envelope #10: "297 684" 304 | *PaperDimension EnvC5/Envelope C5: "459 649" 305 | *PaperDimension EnvDL/Envelope DL: "312 624" 306 | *PaperDimension EnvMonarch/Envelope Monarch: "279 540" 307 | *PaperDimension Executive/Executive: "522 756" 308 | *PaperDimension ISOB0/B0 (ISO): "2834 4008" 309 | *PaperDimension ISOB1/B1 (ISO): "2004 2834" 310 | *PaperDimension ISOB2/B2 (ISO): "1417 2004" 311 | *PaperDimension ISOB3/B3 (ISO): "1000 1417" 312 | *PaperDimension ISOB4/B4 (ISO): "708 1000" 313 | *PaperDimension ISOB5/B5 (ISO): "498 708" 314 | *PaperDimension JISB0/B0 (JIS): "2919 4127" 315 | *PaperDimension JISB1/B1 (JIS): "2063 2919" 316 | *PaperDimension JISB2/B2 (JIS): "1459 2063" 317 | *PaperDimension JISB3/B3 (JIS): "1029 1459" 318 | *PaperDimension JISB4/B4 (JIS): "727 1029" 319 | *PaperDimension JISB5/B5 (JIS): "518 727" 320 | *PaperDimension Ledger/Ledger: "1224 792" 321 | *PaperDimension Legal/US Legal: "612 1008" 322 | *PaperDimension Letter/US Letter: "612 792" 323 | *PaperDimension RA0/RA0: "2437 3458" 324 | *PaperDimension RA1/RA1: "1729 2437" 325 | *PaperDimension RA2/RA2: "1218 1729" 326 | *PaperDimension RA3/RA3: "864 1218" 327 | *PaperDimension RA4/RA4: "609 864" 328 | *PaperDimension SRA0/SRA0: "2551 3628" 329 | *PaperDimension SRA1/SRA1: "1814 2551" 330 | *PaperDimension SRA2/SRA2: "1275 1814" 331 | *PaperDimension SRA3/SRA3: "907 1275" 332 | *PaperDimension SRA4/SRA4: "637 907" 333 | *PaperDimension SuperA/Super A: "644 1008" 334 | *PaperDimension SuperB/Super B: "936 1368" 335 | *PaperDimension TabloidExtra/Tabloid Extra: "864 1296" 336 | *PaperDimension Tabloid/Tabloid: "792 1224" 337 | 338 | *OpenUI *Resolution/Output Resolution: PickOne 339 | *OrderDependency: 100 AnySetup *Resolution 340 | *DefaultResolution: 300dpi 341 | *Resolution 150dpi/150 DPI: "<>setpagedevice" 342 | *Resolution 300dpi/300 DPI: "<>setpagedevice" 343 | *Resolution 600dpi/600 DPI: "<>setpagedevice" 344 | *Resolution 1200dpi/1200 DPI: "<>setpagedevice" 345 | *Resolution 2400dpi/2400 DPI: "<>setpagedevice" 346 | *CloseUI: *Resolution 347 | 348 | *CloseGroup: General 349 | 350 | *DefaultFont: Courier 351 | *Font AvantGarde-Book: Standard "(001.006S)" Standard ROM 352 | *Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM 353 | *Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM 354 | *Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM 355 | *Font Bookman-Demi: Standard "(001.004S)" Standard ROM 356 | *Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM 357 | *Font Bookman-Light: Standard "(001.004S)" Standard ROM 358 | *Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM 359 | *Font Courier: Standard "(002.004S)" Standard ROM 360 | *Font Courier-Bold: Standard "(002.004S)" Standard ROM 361 | *Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM 362 | *Font Courier-Oblique: Standard "(002.004S)" Standard ROM 363 | *Font Helvetica: Standard "(001.006S)" Standard ROM 364 | *Font Helvetica-Bold: Standard "(001.007S)" Standard ROM 365 | *Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM 366 | *Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM 367 | *Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM 368 | *Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM 369 | *Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM 370 | *Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM 371 | *Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM 372 | *Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM 373 | *Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM 374 | *Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM 375 | *Font Palatino-Bold: Standard "(001.005S)" Standard ROM 376 | *Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM 377 | *Font Palatino-Italic: Standard "(001.005S)" Standard ROM 378 | *Font Palatino-Roman: Standard "(001.005S)" Standard ROM 379 | *Font Symbol: Special "(001.007S)" Special ROM 380 | *Font Times-Bold: Standard "(001.007S)" Standard ROM 381 | *Font Times-BoldItalic: Standard "(001.009S)" Standard ROM 382 | *Font Times-Italic: Standard "(001.007S)" Standard ROM 383 | *Font Times-Roman: Standard "(001.007S)" Standard ROM 384 | *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM 385 | *Font ZapfDingbats: Special "(001.004S)" Standard ROM 386 | *% 387 | *% End of "$Id: postscript.ppd,v 1.1.1.1 2000/08/24 19:23:13 goffioul Exp $". 388 | *% 389 | -------------------------------------------------------------------------------- /CUPS-PDF_opt.ppd: -------------------------------------------------------------------------------- 1 | *PPD-Adobe: "4.3" 2 | *% 3 | *% "$Id: postscript.ppd,v 1.1.1.1 2000/08/24 19:23:13 goffioul Exp $" 4 | *% 5 | *% Sample Postscript driver PPD file for the Common UNIX Printing 6 | *% System (CUPS). 7 | *% 8 | *% Michael Goffioul 9 | *% 10 | *% Changes to the original file by Volker Behr, Martin-Eric Racine, 11 | *% Nickolay Kondrashov, Louis Lagendijk and other contributors: 12 | *% added option setting from PPD - 2011-08-05 13 | *% added IEEE-1284 device id - 2008-03-24 14 | *% added custom page size - 2006-05-18 15 | *% replaced page descriptions - 2006-05-18 16 | *% InputSlot constraints removed - 2006-05-11 17 | *% maxed out imageable regions - 2006-05-11 18 | *% added pstitleiconv filter - 2006-05-11 19 | *% added ledger paper size - 2006-01-29 20 | *% match Adobe specifications - 2005-12-23 21 | *% additional paper formats - 2005-02-03 and 2005-02-07 22 | *% made A4 default paper size - 2005-02-03 23 | *% Color enabled - 2003-12-02 24 | *% 25 | *FormatVersion: "4.3" 26 | *FileVersion: "1.1" 27 | *LanguageVersion: English 28 | *LanguageEncoding: ISOLatin1 29 | *PCFileName: "CUPS-PDF.PPD" 30 | *Manufacturer: "Generic" 31 | *Product: "(CUPS v1.1)" 32 | *ModelName: "Generic CUPS-PDF Printer" 33 | *ShortNickName: "Generic CUPS-PDF Printer" 34 | *NickName: "Generic CUPS-PDF Printer (w/ options)" 35 | *% 1284DeviceID: "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;" 36 | *1284DeviceID: "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;" 37 | *% cupsFilter: "application/vnd.cups-postscript 100 pstitleiconv" 38 | *% cupsFilter: "application/vnd.cups-pdf 0 pstitleiconv" 39 | *cupsFilter: "application/pdf 0 -" 40 | *PSVersion: "(2017.000) 0" 41 | *LanguageLevel: "2" 42 | *ColorDevice: True 43 | *DefaultColorSpace: RGB 44 | *FileSystem: False 45 | *Throughput: "8" 46 | *LandscapeOrientation: Plus90 47 | *TTRasterizer: Type42 48 | 49 | *HWMargins: 0 0 0 0 50 | *VariablePaperSize: True 51 | *MaxMediaWidth: 100000 52 | *MaxMediaHeight: 100000 53 | *NonUIOrderDependency: 100 AnySetup *CustomPageSize 54 | *CustomPageSize True: "pop pop pop 55 | <>setpagedevice" 56 | *End 57 | *ParamCustomPageSize Width: 1 points 36 100000 58 | *ParamCustomPageSize Height: 2 points 36 100000 59 | *ParamCustomPageSize Orientation: 3 int 0 3 60 | *ParamCustomPageSize WidthOffset: 4 points 0 0 61 | *ParamCustomPageSize HeightOffset: 5 points 0 0 62 | 63 | *OpenGroup: General/General 64 | 65 | *OpenUI *PageSize/Page Size: PickOne 66 | *OrderDependency: 100 AnySetup *PageSize 67 | *DefaultPageSize: A4 68 | *PageSize 11x14/11x14: "<>setpagedevice" 69 | *PageSize 11x17/11x17: "<>setpagedevice" 70 | *PageSize 13x19/13x19: "<>setpagedevice" 71 | *PageSize 16x20/16x20: "<>setpagedevice" 72 | *PageSize 16x24/16x24: "<>setpagedevice" 73 | *PageSize 2A/2A: "<>setpagedevice" 74 | *PageSize 4A/4A: "<>setpagedevice" 75 | *PageSize 8x10/8x10: "<>setpagedevice" 76 | *PageSize 8x12/8x12: "<>setpagedevice" 77 | *PageSize A0/A0: "<>setpagedevice" 78 | *PageSize A1/A1: "<>setpagedevice" 79 | *PageSize A2/A2: "<>setpagedevice" 80 | *PageSize A3/A3: "<>setpagedevice" 81 | *PageSize A4/A4: "<>setpagedevice" 82 | *PageSize A5/A5: "<>setpagedevice" 83 | *PageSize AnsiA/ANSI A: "<>setpagedevice" 84 | *PageSize AnsiB/ANSI B: "<>setpagedevice" 85 | *PageSize AnsiC/ANSI C: "<>setpagedevice" 86 | *PageSize AnsiD/ANSI D: "<>setpagedevice" 87 | *PageSize AnsiE/ANSI E: "<>setpagedevice" 88 | *PageSize ArchA/Arch A: "<>setpagedevice" 89 | *PageSize ArchB/Arch B: "<>setpagedevice" 90 | *PageSize ArchC/Arch C: "<>setpagedevice" 91 | *PageSize ArchD/Arch D: "<>setpagedevice" 92 | *PageSize ArchE/Arch E: "<>setpagedevice" 93 | *PageSize C0/C0: "<>setpagedevice" 94 | *PageSize C1/C1: "<>setpagedevice" 95 | *PageSize C2/C2: "<>setpagedevice" 96 | *PageSize C3/C3: "<>setpagedevice" 97 | *PageSize C4/C4: "<>setpagedevice" 98 | *PageSize C5/C5: "<>setpagedevice" 99 | *PageSize Env10/Envelope #10: "<>setpagedevice" 100 | *PageSize EnvC5/Envelope C5: "<>setpagedevice" 101 | *PageSize EnvDL/Envelope DL: "<>setpagedevice" 102 | *PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice" 103 | *PageSize Executive/Executive: "<>setpagedevice" 104 | *PageSize ISOB0/B0 (ISO): "<>setpagedevice" 105 | *PageSize ISOB1/B1 (ISO): "<>setpagedevice" 106 | *PageSize ISOB2/B2 (ISO): "<>setpagedevice" 107 | *PageSize ISOB3/B3 (ISO): "<>setpagedevice" 108 | *PageSize ISOB4/B4 (ISO): "<>setpagedevice" 109 | *PageSize ISOB5/B5 (ISO): "<>setpagedevice" 110 | *PageSize JISB0/B0 (JIS): "<>setpagedevice" 111 | *PageSize JISB1/B1 (JIS): "<>setpagedevice" 112 | *PageSize JISB2/B2 (JIS): "<>setpagedevice" 113 | *PageSize JISB3/B3 (JIS): "<>setpagedevice" 114 | *PageSize JISB4/B4 (JIS): "<>setpagedevice" 115 | *PageSize JISB5/B5 (JIS): "<>setpagedevice" 116 | *PageSize Ledger/Ledger: "<>setpagedevice" 117 | *PageSize Legal/US Legal: "<>setpagedevice" 118 | *PageSize Letter/US Letter: "<>setpagedevice" 119 | *PageSize RA0/RA0: "<>setpagedevice" 120 | *PageSize RA1/RA1: "<>setpagedevice" 121 | *PageSize RA2/RA2: "<>setpagedevice" 122 | *PageSize RA3/RA3: "<>setpagedevice" 123 | *PageSize RA4/RA4: "<>setpagedevice" 124 | *PageSize SRA0/SRA0: "<>setpagedevice" 125 | *PageSize SRA1/SRA1: "<>setpagedevice" 126 | *PageSize SRA2/SRA2: "<>setpagedevice" 127 | *PageSize SRA3/SRA3: "<>setpagedevice" 128 | *PageSize SRA4/SRA4: "<>setpagedevice" 129 | *PageSize SuperA/Super A: "<>setpagedevice" 130 | *PageSize SuperB/Super B: "<>setpagedevice" 131 | *PageSize TabloidExtra/Tabloid Extra: "<>setpagedevice" 132 | *PageSize Tabloid/Tabloid: "<>setpagedevice" 133 | *CloseUI: *PageSize 134 | 135 | *OpenUI *PageRegion: PickOne 136 | *OrderDependency: 100 AnySetup *PageRegion 137 | *DefaultPageRegion: A4 138 | *PageRegion 11x14/11x14: "<>setpagedevice" 139 | *PageRegion 11x17/11x17: "<>setpagedevice" 140 | *PageRegion 13x19/13x19: "<>setpagedevice" 141 | *PageRegion 16x20/16x20: "<>setpagedevice" 142 | *PageRegion 16x24/16x24: "<>setpagedevice" 143 | *PageRegion 2A/2A: "<>setpagedevice" 144 | *PageRegion 4A/4A: "<>setpagedevice" 145 | *PageRegion 8x10/8x10: "<>setpagedevice" 146 | *PageRegion 8x12/8x12: "<>setpagedevice" 147 | *PageRegion A0/A0: "<>setpagedevice" 148 | *PageRegion A1/A1: "<>setpagedevice" 149 | *PageRegion A2/A2: "<>setpagedevice" 150 | *PageRegion A3/A3: "<>setpagedevice" 151 | *PageRegion A4/A4: "<>setpagedevice" 152 | *PageRegion A5/A5: "<>setpagedevice" 153 | *PageRegion AnsiA/ANSI A: "<>setpagedevice" 154 | *PageRegion AnsiB/ANSI B: "<>setpagedevice" 155 | *PageRegion AnsiC/ANSI C: "<>setpagedevice" 156 | *PageRegion AnsiD/ANSI D: "<>setpagedevice" 157 | *PageRegion AnsiE/ANSI E: "<>setpagedevice" 158 | *PageRegion ArchA/Arch A: "<>setpagedevice" 159 | *PageRegion ArchB/Arch B: "<>setpagedevice" 160 | *PageRegion ArchC/Arch C: "<>setpagedevice" 161 | *PageRegion ArchD/Arch D: "<>setpagedevice" 162 | *PageRegion ArchE/Arch E: "<>setpagedevice" 163 | *PageRegion C0/C0: "<>setpagedevice" 164 | *PageRegion C1/C1: "<>setpagedevice" 165 | *PageRegion C2/C2: "<>setpagedevice" 166 | *PageRegion C3/C3: "<>setpagedevice" 167 | *PageRegion C4/C4: "<>setpagedevice" 168 | *PageRegion C5/C5: "<>setpagedevice" 169 | *PageRegion Env10/Envelope #10: "<>setpagedevice" 170 | *PageRegion EnvC5/Envelope C5: "<>setpagedevice" 171 | *PageRegion EnvDL/Envelope DL: "<>setpagedevice" 172 | *PageRegion EnvMonarch/Envelope Monarch: "<>setpagedevice" 173 | *PageRegion Executive/Executive: "<>setpagedevice" 174 | *PageRegion ISOB0/B0 (ISO): "<>setpagedevice" 175 | *PageRegion ISOB1/B1 (ISO): "<>setpagedevice" 176 | *PageRegion ISOB2/B2 (ISO): "<>setpagedevice" 177 | *PageRegion ISOB3/B3 (ISO): "<>setpagedevice" 178 | *PageRegion ISOB4/B4 (ISO): "<>setpagedevice" 179 | *PageRegion ISOB5/B5 (ISO): "<>setpagedevice" 180 | *PageRegion JISB0/B0 (JIS): "<>setpagedevice" 181 | *PageRegion JISB1/B1 (JIS): "<>setpagedevice" 182 | *PageRegion JISB2/B2 (JIS): "<>setpagedevice" 183 | *PageRegion JISB3/B3 (JIS): "<>setpagedevice" 184 | *PageRegion JISB4/B4 (JIS): "<>setpagedevice" 185 | *PageRegion JISB5/B5 (JIS): "<>setpagedevice" 186 | *PageRegion Ledger/Ledger: "<>setpagedevice" 187 | *PageRegion Legal/US Legal: "<>setpagedevice" 188 | *PageRegion Letter/US Letter: "<>setpagedevice" 189 | *PageRegion RA0/RA0: "<>setpagedevice" 190 | *PageRegion RA1/RA1: "<>setpagedevice" 191 | *PageRegion RA2/RA2: "<>setpagedevice" 192 | *PageRegion RA3/RA3: "<>setpagedevice" 193 | *PageRegion RA4/RA4: "<>setpagedevice" 194 | *PageRegion SRA0/SRA0: "<>setpagedevice" 195 | *PageRegion SRA1/SRA1: "<>setpagedevice" 196 | *PageRegion SRA2/SRA2: "<>setpagedevice" 197 | *PageRegion SRA3/SRA3: "<>setpagedevice" 198 | *PageRegion SRA4/SRA4: "<>setpagedevice" 199 | *PageRegion SuperA/Super A: "<>setpagedevice" 200 | *PageRegion SuperB/Super B: "<>setpagedevice" 201 | *PageRegion TabloidExtra/Tabloid Extra: "<>setpagedevice" 202 | *PageRegion Tabloid/Tabloid: "<>setpagedevice" 203 | *CloseUI: *PageRegion 204 | 205 | *DefaultImageableArea: A4 206 | *ImageableArea 11x14/11x14: "0 0 792 1008" 207 | *ImageableArea 11x17/11x17: "0 0 792 1224" 208 | *ImageableArea 13x19/13x19: "0 0 936 1368" 209 | *ImageableArea 16x20/16x20: "0 0 1152 1440" 210 | *ImageableArea 16x24/16x24: "0 0 1152 1728" 211 | *ImageableArea 2A/2A: "0 0 3370 4768" 212 | *ImageableArea 4A/4A: "0 0 4768 6749" 213 | *ImageableArea 8x10/8x10: "0 0 576 720" 214 | *ImageableArea 8x12/8x12: "0 0 576 864" 215 | *ImageableArea A0/A0: "0 0 2384 3370" 216 | *ImageableArea A1/A1: "0 0 1684 2384" 217 | *ImageableArea A2/A2: "0 0 1191 1684" 218 | *ImageableArea A3/A3: "0 0 842 1191" 219 | *ImageableArea A4/A4: "0 0 595 842" 220 | *ImageableArea A5/A5: "0 0 421 595" 221 | *ImageableArea AnsiA/ANSI A: "0 0 612 792" 222 | *ImageableArea AnsiB/ANSI B: "0 0 792 1224" 223 | *ImageableArea AnsiC/ANSI C: "0 0 1224 1584" 224 | *ImageableArea AnsiD/ANSI D: "0 0 1584 2448" 225 | *ImageableArea AnsiE/ANSI E: "0 0 2448 3168" 226 | *ImageableArea ArchA/Arch A: "0 0 648 864" 227 | *ImageableArea ArchB/Arch B: "0 0 864 1296" 228 | *ImageableArea ArchC/Arch C: "0 0 1296 1728" 229 | *ImageableArea ArchD/Arch D: "0 0 1728 2592" 230 | *ImageableArea ArchE/Arch E: "0 0 2592 3456" 231 | *ImageableArea C0/C0: "0 0 2599 3676" 232 | *ImageableArea C1/C1: "0 0 1836 2599" 233 | *ImageableArea C2/C2: "0 0 1298 1836" 234 | *ImageableArea C3/C3: "0 0 918 1298" 235 | *ImageableArea C4/C4: "0 0 649 918" 236 | *ImageableArea C5/C5: "0 0 459 649" 237 | *ImageableArea Env10/Envelope #10: "0 0 297 684" 238 | *ImageableArea EnvC5/Envelope C5: "0 0 459 649" 239 | *ImageableArea EnvDL/Envelope DL: "0 0 312 624" 240 | *ImageableArea EnvMonarch/Envelope Monarch: "0 0 279 540" 241 | *ImageableArea Executive/Executive: "0 0 522 756" 242 | *ImageableArea ISOB0/B0 (ISO): "0 0 2834 4008" 243 | *ImageableArea ISOB1/B1 (ISO): "0 0 2004 2834" 244 | *ImageableArea ISOB2/B2 (ISO): "0 0 1417 2004" 245 | *ImageableArea ISOB3/B3 (ISO): "0 0 1000 1417" 246 | *ImageableArea ISOB4/B4 (ISO): "0 0 708 1000" 247 | *ImageableArea ISOB5/B5 (ISO): "0 0 498 708" 248 | *ImageableArea JISB0/B0 (JIS): "0 0 2919 4127" 249 | *ImageableArea JISB1/B1 (JIS): "0 0 2063 2919" 250 | *ImageableArea JISB2/B2 (JIS): "0 0 1459 2063" 251 | *ImageableArea JISB3/B3 (JIS): "0 0 1029 1459" 252 | *ImageableArea JISB4/B4 (JIS): "0 0 727 1029" 253 | *ImageableArea JISB5/B5 (JIS): "0 0 518 727" 254 | *ImageableArea Ledger/Ledger: "0 0 1224 792" 255 | *ImageableArea Legal/US Legal: "0 0 612 1008" 256 | *ImageableArea Letter/US Letter: "0 0 612 792" 257 | *ImageableArea RA0/RA0: "0 0 2437 3458" 258 | *ImageableArea RA1/RA1: "0 0 1729 2437" 259 | *ImageableArea RA2/RA2: "0 0 1218 1729" 260 | *ImageableArea RA3/RA3: "0 0 864 1218" 261 | *ImageableArea RA4/RA4: "0 0 609 864" 262 | *ImageableArea SRA0/SRA0: "0 0 2551 3628" 263 | *ImageableArea SRA1/SRA1: "0 0 1814 2551" 264 | *ImageableArea SRA2/SRA2: "0 0 1275 1814" 265 | *ImageableArea SRA3/SRA3: "0 0 907 1275" 266 | *ImageableArea SRA4/SRA4: "0 0 637 907" 267 | *ImageableArea SuperA/Super A: "0 0 644 1008" 268 | *ImageableArea SuperB/Super B: "0 0 936 1368" 269 | *ImageableArea TabloidExtra/Tabloid Extra: "0 0 864 1296" 270 | *ImageableArea Tabloid/Tabloid: "0 0 792 1224" 271 | 272 | *DefaultPaperDimension: A4 273 | *PaperDimension 11x14/11x14: "792 1008" 274 | *PaperDimension 11x17/11x17: "792 1224" 275 | *PaperDimension 13x19/13x19: "936 1368" 276 | *PaperDimension 16x20/16x20: "1152 1440" 277 | *PaperDimension 16x24/16x24: "1152 1728" 278 | *PaperDimension 2A/2A: "3370 4768" 279 | *PaperDimension 4A/4A: "4768 6749" 280 | *PaperDimension 8x10/8x10: "576 720" 281 | *PaperDimension 8x12/8x12: "576 864" 282 | *PaperDimension A0/A0: "2384 3370" 283 | *PaperDimension A1/A1: "1684 2384" 284 | *PaperDimension A2/A2: "1191 1684" 285 | *PaperDimension A3/A3: "842 1191" 286 | *PaperDimension A4/A4: "595 842" 287 | *PaperDimension A5/A5: "421 595" 288 | *PaperDimension AnsiA/ANSI A: "612 792" 289 | *PaperDimension AnsiB/ANSI B: "792 1224" 290 | *PaperDimension AnsiC/ANSI C: "1224 1584" 291 | *PaperDimension AnsiD/ANSI D: "1584 2448" 292 | *PaperDimension AnsiE/ANSI E: "2448 3168" 293 | *PaperDimension ArchA/Arch A: "648 864" 294 | *PaperDimension ArchB/Arch B: "864 1296" 295 | *PaperDimension ArchC/Arch C: "1296 1728" 296 | *PaperDimension ArchD/Arch D: "1728 2592" 297 | *PaperDimension ArchE/Arch E: "2592 3456" 298 | *PaperDimension C0/C0: "2599 3676" 299 | *PaperDimension C1/C1: "1836 2599" 300 | *PaperDimension C2/C2: "1298 1836" 301 | *PaperDimension C3/C3: "918 1298" 302 | *PaperDimension C4/C4: "649 918" 303 | *PaperDimension C5/C5: "459 649" 304 | *PaperDimension Env10/Envelope #10: "297 684" 305 | *PaperDimension EnvC5/Envelope C5: "459 649" 306 | *PaperDimension EnvDL/Envelope DL: "312 624" 307 | *PaperDimension EnvMonarch/Envelope Monarch: "279 540" 308 | *PaperDimension Executive/Executive: "522 756" 309 | *PaperDimension ISOB0/B0 (ISO): "2834 4008" 310 | *PaperDimension ISOB1/B1 (ISO): "2004 2834" 311 | *PaperDimension ISOB2/B2 (ISO): "1417 2004" 312 | *PaperDimension ISOB3/B3 (ISO): "1000 1417" 313 | *PaperDimension ISOB4/B4 (ISO): "708 1000" 314 | *PaperDimension ISOB5/B5 (ISO): "498 708" 315 | *PaperDimension JISB0/B0 (JIS): "2919 4127" 316 | *PaperDimension JISB1/B1 (JIS): "2063 2919" 317 | *PaperDimension JISB2/B2 (JIS): "1459 2063" 318 | *PaperDimension JISB3/B3 (JIS): "1029 1459" 319 | *PaperDimension JISB4/B4 (JIS): "727 1029" 320 | *PaperDimension JISB5/B5 (JIS): "518 727" 321 | *PaperDimension Ledger/Ledger: "1224 792" 322 | *PaperDimension Legal/US Legal: "612 1008" 323 | *PaperDimension Letter/US Letter: "612 792" 324 | *PaperDimension RA0/RA0: "2437 3458" 325 | *PaperDimension RA1/RA1: "1729 2437" 326 | *PaperDimension RA2/RA2: "1218 1729" 327 | *PaperDimension RA3/RA3: "864 1218" 328 | *PaperDimension RA4/RA4: "609 864" 329 | *PaperDimension SRA0/SRA0: "2551 3628" 330 | *PaperDimension SRA1/SRA1: "1814 2551" 331 | *PaperDimension SRA2/SRA2: "1275 1814" 332 | *PaperDimension SRA3/SRA3: "907 1275" 333 | *PaperDimension SRA4/SRA4: "637 907" 334 | *PaperDimension SuperA/Super A: "644 1008" 335 | *PaperDimension SuperB/Super B: "936 1368" 336 | *PaperDimension TabloidExtra/Tabloid Extra: "864 1296" 337 | *PaperDimension Tabloid/Tabloid: "792 1224" 338 | 339 | *OpenUI *Resolution/Output Resolution: PickOne 340 | *OrderDependency: 100 AnySetup *Resolution 341 | *DefaultResolution: 300dpi 342 | *Resolution 150dpi/150 DPI: "<>setpagedevice" 343 | *Resolution 300dpi/300 DPI: "<>setpagedevice" 344 | *Resolution 600dpi/600 DPI: "<>setpagedevice" 345 | *Resolution 1200dpi/1200 DPI: "<>setpagedevice" 346 | *Resolution 2400dpi/2400 DPI: "<>setpagedevice" 347 | *CloseUI: *Resolution 348 | 349 | *OpenUI *PDFVer/PDF version: PickOne 350 | *OrderDependency: 100 AnySetup *PDFVer 351 | *OPOptionHints PDFVer: "dropdown" 352 | *DefaultPDFVer: 1.2 353 | *PDFVer 1.1/1.1: "" 354 | *PDFVer 1.2/1.2: "" 355 | *PDFVer 1.3/1.3: "" 356 | *PDFVer 1.4/1.4: "" 357 | *PDFVer 1.5/1.5: "" 358 | *CloseUI: *PDFVer 359 | 360 | *OpenUI *Truncate/Truncate output filename to: PickOne 361 | *OrderDependency: 100 AnySetup *Truncate 362 | *OPOptionHints Truncate: "dropdown" 363 | *DefaultTruncate: 64 364 | *Truncate 8/8 Characters: aap 365 | *Truncate 16/16 Characters: noot 366 | *Truncate 32/32 Characters: mies 367 | *Truncate 64/64 Characters: wim 368 | *CloseUI: *Truncate 369 | 370 | *OpenUI *Label/Label outputfiles:PickOne 371 | *OrdeDependency: 100 AnySetup *Label 372 | *DefaultLabel: 2 373 | *Label 0/Label only untitled documents with job-id: "" 374 | *Label 1/Prefix all documents with job-id: "" 375 | *Label 2/Suffix all documents with job-id: "" 376 | *CloseUI: *Label 377 | 378 | *OpenUI *TitlePref/Prefer title from:PickOne 379 | *OrdeDependency: 100 AnySetup *TitlePref 380 | *DefaultTitlePref: 0 381 | *TitlePref 0/Title in postscript document: "" 382 | *TitlePref 1/Title passed via command-line1: "" 383 | *CloseUI: *TitlePref 384 | 385 | *OpenUI *LogType/Log level: PickOne 386 | *DefaultLogType: 7 387 | *LogType 1/Only errors: "" 388 | *LogType 3/Error and status messages: "" 389 | *LogType 7/Debug, error and status messages: "" 390 | *CloseUI: *Logtype 391 | 392 | *CloseGroup: General 393 | 394 | *DefaultFont: Courier 395 | *Font AvantGarde-Book: Standard "(001.006S)" Standard ROM 396 | *Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM 397 | *Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM 398 | *Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM 399 | *Font Bookman-Demi: Standard "(001.004S)" Standard ROM 400 | *Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM 401 | *Font Bookman-Light: Standard "(001.004S)" Standard ROM 402 | *Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM 403 | *Font Courier: Standard "(002.004S)" Standard ROM 404 | *Font Courier-Bold: Standard "(002.004S)" Standard ROM 405 | *Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM 406 | *Font Courier-Oblique: Standard "(002.004S)" Standard ROM 407 | *Font Helvetica: Standard "(001.006S)" Standard ROM 408 | *Font Helvetica-Bold: Standard "(001.007S)" Standard ROM 409 | *Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM 410 | *Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM 411 | *Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM 412 | *Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM 413 | *Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM 414 | *Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM 415 | *Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM 416 | *Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM 417 | *Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM 418 | *Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM 419 | *Font Palatino-Bold: Standard "(001.005S)" Standard ROM 420 | *Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM 421 | *Font Palatino-Italic: Standard "(001.005S)" Standard ROM 422 | *Font Palatino-Roman: Standard "(001.005S)" Standard ROM 423 | *Font Symbol: Special "(001.007S)" Special ROM 424 | *Font Times-Bold: Standard "(001.007S)" Standard ROM 425 | *Font Times-BoldItalic: Standard "(001.009S)" Standard ROM 426 | *Font Times-Italic: Standard "(001.007S)" Standard ROM 427 | *Font Times-Roman: Standard "(001.007S)" Standard ROM 428 | *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM 429 | *Font ZapfDingbats: Special "(001.004S)" Standard ROM 430 | *% 431 | *% End of "$Id: postscript.ppd,v 1.1.1.1 2000/08/24 19:23:13 goffioul Exp $". 432 | *% 433 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CUPS-PDF v3 with text print support 2 | This is a [cups-pdf v3.0.1](http://www.cups-pdf.de/src/cups-pdf_3.0.1.tar.gz) with a patch to allow printing text as text, not as images. This issue is also known as "cups-pdf not embedding text", or "[producing large PDFs with text that can not be searched](https://bugs.launchpad.net/ubuntu/+source/cups-pdf/+bug/366949)" 3 | 4 | This is fix is achieved by adding PDF passthrough functionality, so incoming PDFs remain PDFs, instead of being converted from [PDF to PostScript, then back to PDF](https://bugs.launchpad.net/ubuntu/+source/cups-pdf/+bug/820820). Why is this fix not in the original code? The author had different goals for CUPS-PDF in mind, [refusing to fix it.](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=658004) 5 | 6 | ### How is this better than a Save-as-PDF or Print-as-file functionality in many GTK/QT interfaces? 7 | 8 | 1. You can do post-processing, for example choose pdf filename and saving location in a standard file save dialog, and automatically open generated PDF. 9 | 2. Use PDF printing from non GTK/QT apps, like Wine 10 | 3. Provide consistent PDF printing experience 11 | 12 | 13 | Installing 14 | ---------- 15 | There is a cups-pdf version 2.6.1 with the fix in an easy to install deb patch form in [ppa:jethrogb/ppa](https://launchpad.net/~jethrogb/+archive/ubuntu/ppa). Add it to your list of apt sources and update. 16 | For Arch Linux you can find it in AUR: [cups-pdf-to-pdf-git](https://aur.archlinux.org/packages/cups-pdf-to-pdf-git/) 17 | 18 | For all the other system, or if you want the latest functionality follow the directions below: 19 | 20 | 21 | 1. Get the development prerequisites 22 | 23 | ``apt-get install libcups2-dev`` 24 | 25 | 2. Compile 26 | 27 | ``gcc -O9 -s -o cups-pdf cups-pdf.c -lcups`` 28 | 29 | 30 | (note the different order of options than the one suggested on the cups-pdf website) 31 | 32 | 3. Copy to your system folder 33 | 34 | ``` 35 | sudo cp /usr/lib/cups/backend/cups-pdf /usr/lib/cups/backend/cups-pdf.bak 36 | sudo cp cups-pdf /usr/lib/cups/backend/ 37 | ``` 38 | 39 | 4. Copy CUPS-PDF_opt.ppd to your CUPS model directory 40 | 41 | ``sudo cp CUPS-PDF_opt.ppd /usr/share/cups/model`` 42 | 43 | 5. Copy cups-pdf.conf to /etc/cups (and then edit as needed): 44 | 45 | ``sudo cp cups-pdf.conf /etc/cups/`` 46 | 47 | 6. Remove CUPS-PDF printer, if you have any, and recreate it. Make sure to pick "Generic CUPS-PDF Printer (w/ options)" as the driver 48 | 49 | 50 | Troubleshooting 51 | --------------- 52 | 53 | ### The options from /etc/cups/cups-pdf.conf are ignored 54 | If you create the printer with the URL like this: , then it will be looking for a file cups-pdf-/localhost.conf 55 | Change the URL to cups-pdf:/ (it is a valid url after it's created, but you might not be able to use it *during* creation). It will then look for cups-pdf.conf 56 | 57 | ### Apparmor is getting in the way 58 | ``sudo vi /etc/apparmor.d/usr.sbin.cupsd`` 59 | 60 | 61 | 1. At the end of the ``/usr/sbin/cupsd flags=(attach_disconnected)`` section add 62 | 63 | ``` 64 | unix peer=(label=/usr/lib/cups/backend/cups-pdf), 65 | signal peer=/usr/lib/cups/backend/cups-pdf, 66 | ``` 67 | 68 | 69 | 2. At the end of the ``/usr/lib/cups/backend/cups-pdf`` section add 70 | 71 | ``` 72 | /var/log/cups/ r, 73 | /var/log/cups/** rwk, 74 | /etc/cups/ r, 75 | unix peer=(label=/usr/sbin/cupsd), 76 | signal peer=/usr/sbin/cupsd, 77 | @{HOME}/bin/pdfpostproc.sh rUx, 78 | ``` 79 | 80 | (last line is needed if you indicated a post-processor in your /etc/cups/cups-pdf.conf) 81 | 82 | 83 | 3. Reload apparmor profile 84 | 85 | ``sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.cupsd `` 86 | 87 | Other 88 | ----- 89 | 90 | * For other issues refer to the [original README](http://www.cups-pdf.de/cups-pdf-CURRENT/README) or [the original documentation](http://www.cups-pdf.de/documentation.shtml) 91 | * Kudos to [Björgvin Ragnarsson](https://launchpad.net/~nifgraup) for the patch to CUPS-PDF v2.6 92 | -------------------------------------------------------------------------------- /cups-pdf.c: -------------------------------------------------------------------------------- 1 | /* cups-pdf.c -- CUPS Backend (version 3.0.1, 2017-02-24) 2 | 08.02.2003, Volker C. Behr 3 | volker@cups-pdf.de 4 | http://www.cups-pdf.de 5 | 6 | This code may be freely distributed as long as this header 7 | is preserved. 8 | 9 | This code is distributed under the GPL. 10 | (http://www.gnu.org/copyleft/gpl.html) 11 | 12 | --------------------------------------------------------------------------- 13 | 14 | Copyright (C) 2003-2017 Volker C. Behr 15 | 16 | This program is free software; you can redistribute it and/or 17 | modify it under the terms of the GNU General Public License 18 | as published by the Free Software Foundation; either version 2 19 | of the License, or (at your option) any later version. 20 | 21 | This program is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with this program; if not, write to the Free Software 28 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 29 | 30 | --------------------------------------------------------------------------- 31 | 32 | If you want to redistribute modified sources/binaries this header 33 | has to be preserved and all modifications should be clearly 34 | indicated. 35 | In case you want to include this code into your own programs 36 | I would appreciate your feedback via email. 37 | 38 | 39 | HISTORY: see ChangeLog in the parent directory of the source archive 40 | */ 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | #include 60 | #include 61 | #include 62 | 63 | #include "cups-pdf.h" 64 | 65 | 66 | static FILE *logfp=NULL; 67 | int input_is_pdf=0; 68 | 69 | 70 | static void log_event(short type, const char *message, ...) { 71 | time_t secs; 72 | int error=errno; 73 | char ctype[8], *timestring; 74 | cp_string logbuffer; 75 | va_list ap; 76 | 77 | if ((logfp != NULL) && (type & Conf_LogType)) { 78 | (void) time(&secs); 79 | timestring=ctime(&secs); 80 | timestring[strlen(timestring)-1]='\0'; 81 | 82 | if (type == CPERROR) 83 | snprintf(ctype, 8, "ERROR"); 84 | else if (type == CPSTATUS) 85 | snprintf(ctype, 8, "STATUS"); 86 | else 87 | snprintf(ctype, 8, "DEBUG"); 88 | 89 | va_start(ap, message); 90 | vsnprintf(logbuffer, BUFSIZE, message, ap); 91 | va_end(ap); 92 | 93 | fprintf(logfp,"%s [%s] %s\n", timestring, ctype, logbuffer); 94 | if ((Conf_LogType & CPDEBUG) && (type == CPERROR) && error) 95 | fprintf(logfp,"%s [DEBUG] ERRNO: %d (%s)\n", timestring, error, strerror(error)); 96 | 97 | (void) fflush(logfp); 98 | } 99 | 100 | return; 101 | } 102 | 103 | static int create_dir(char *dirname, int nolog) { 104 | struct stat fstatus; 105 | char buffer[BUFSIZE],*delim; 106 | int i; 107 | 108 | while ((i=strlen(dirname))>1 && dirname[i-1]=='/') 109 | dirname[i-1]='\0'; 110 | if (stat(dirname, &fstatus) || !S_ISDIR(fstatus.st_mode)) { 111 | strncpy(buffer,dirname,BUFSIZE); 112 | delim=strrchr(buffer,'/'); 113 | if (delim!=buffer) 114 | delim[0]='\0'; 115 | else 116 | delim[1]='\0'; 117 | if (create_dir(buffer,nolog)!=0) 118 | return 1; 119 | (void) stat(buffer, &fstatus); 120 | if (mkdir(dirname,fstatus.st_mode)!=0) { 121 | if (!nolog) 122 | log_event(CPERROR, "failed to create directory: %s", dirname); 123 | return 1; 124 | } 125 | else 126 | if (!nolog) 127 | log_event(CPSTATUS, "directory created: %s", dirname); 128 | if (chown(dirname,fstatus.st_uid,fstatus.st_gid)!=0) 129 | if (!nolog) 130 | log_event(CPDEBUG, "failed to set owner on directory: %s (non fatal)", dirname); 131 | } 132 | return 0; 133 | } 134 | 135 | static int _assign_value(int security, char *key, char *value) { 136 | int tmp; 137 | int option; 138 | 139 | for (option=0; option 1) && (!stat(filename, &fstatus)) && 250 | (S_ISREG(fstatus.st_mode) || S_ISLNK(fstatus.st_mode))) { 251 | fp=fopen(filename,"r"); 252 | } 253 | if (fp==NULL) { 254 | log_event(CPERROR, "Cannot open config: %s", filename); 255 | return; 256 | } 257 | 258 | while (fgets(buffer, BUFSIZE, fp) != NULL) { 259 | key[0]='\0'; 260 | value[0]='\0'; 261 | if (sscanf(buffer,"%s %[^\n]",key,value)) { 262 | if (!strlen(key) || !strncmp(key,"#",1)) 263 | continue; 264 | _assign_value(SEC_CONF, key, value); 265 | } 266 | } 267 | 268 | (void) fclose(fp); 269 | return; 270 | } 271 | 272 | static void read_config_ppd() { 273 | ppd_option_t *option; 274 | ppd_file_t *ppd_file; 275 | char * ppd_name; 276 | 277 | ppd_name = getenv("PPD"); 278 | if (ppd_name == NULL) { 279 | log_event(CPERROR, "Could not retrieve PPD name"); 280 | return; 281 | } 282 | ppd_file = ppdOpenFile(ppd_name); 283 | if (ppd_file == NULL) { 284 | log_event(CPERROR, "Could not open PPD file: %s", ppd_name); 285 | return; 286 | } 287 | ppdMarkDefaults(ppd_file); 288 | 289 | option = ppdFirstOption(ppd_file); 290 | while (option != NULL) { 291 | _assign_value(SEC_PPD, option->keyword, option->defchoice); 292 | option = ppdNextOption(ppd_file); 293 | } 294 | ppdClose(ppd_file); 295 | 296 | return; 297 | } 298 | 299 | static void read_config_options(const char *lpoptions) { 300 | int i; 301 | int num_options; 302 | cups_option_t *options; 303 | cups_option_t *option; 304 | 305 | num_options = cupsParseOptions(lpoptions, 0, &options); 306 | 307 | for (i = 0, option = options; i < num_options; i ++, option ++) { 308 | 309 | /* replace all _ by " " in value */ 310 | int j; 311 | for (j=0; option->value[j]!= '\0'; j++) { 312 | if (option->value[j] == '_') { 313 | option->value[j] = ' '; 314 | } 315 | } 316 | _assign_value(SEC_LPOPT, option->name, option->value); 317 | } 318 | return; 319 | } 320 | 321 | static void dump_configuration() { 322 | if (Conf_LogType & CPDEBUG) { 323 | log_event(CPDEBUG, "*** Final Configuration ***"); 324 | log_event(CPDEBUG, "AnonDirName = \"%s\"", Conf_AnonDirName); 325 | log_event(CPDEBUG, "AnonUser = \"%s\"", Conf_AnonUser); 326 | log_event(CPDEBUG, "GhostScript = \"%s\"", Conf_GhostScript); 327 | log_event(CPDEBUG, "GSCall = \"%s\"", Conf_GSCall); 328 | log_event(CPDEBUG, "Grp = \"%s\"", Conf_Grp); 329 | log_event(CPDEBUG, "GSTmp = \"%s\"", Conf_GSTmp); 330 | log_event(CPDEBUG, "Log = \"%s\"", Conf_Log); 331 | log_event(CPDEBUG, "PDFVer = \"%s\"", Conf_PDFVer); 332 | log_event(CPDEBUG, "PostProcessing = \"%s\"", Conf_PostProcessing); 333 | log_event(CPDEBUG, "Out = \"%s\"", Conf_Out); 334 | log_event(CPDEBUG, "Spool = \"%s\"", Conf_Spool); 335 | log_event(CPDEBUG, "UserPrefix = \"%s\"", Conf_UserPrefix); 336 | log_event(CPDEBUG, "RemovePrefix = \"%s\"", Conf_RemovePrefix); 337 | log_event(CPDEBUG, "OutExtension = \"%s\"", Conf_OutExtension); 338 | log_event(CPDEBUG, "Cut = %d", Conf_Cut); 339 | log_event(CPDEBUG, "Truncate = %d", Conf_Truncate); 340 | log_event(CPDEBUG, "DirPrefix = %d", Conf_DirPrefix); 341 | log_event(CPDEBUG, "Label = %d", Conf_Label); 342 | log_event(CPDEBUG, "LogType = %d", Conf_LogType); 343 | log_event(CPDEBUG, "LowerCase = %d", Conf_LowerCase); 344 | log_event(CPDEBUG, "TitlePref = %d", Conf_TitlePref); 345 | log_event(CPDEBUG, "DecodeHexStrings = %d", Conf_DecodeHexStrings); 346 | log_event(CPDEBUG, "FixNewlines = %d", Conf_FixNewlines); 347 | log_event(CPDEBUG, "AllowUnsafeOptions = %d", Conf_AllowUnsafeOptions); 348 | log_event(CPDEBUG, "AnonUMask = %04o", Conf_AnonUMask); 349 | log_event(CPDEBUG, "UserUMask = %04o", Conf_UserUMask); 350 | log_event(CPDEBUG, "*** End of Configuration ***"); 351 | } 352 | return; 353 | } 354 | 355 | static int init(char *argv[]) { 356 | struct stat fstatus; 357 | struct group *group; 358 | cp_string filename; 359 | int grpstat; 360 | const char *uri=cupsBackendDeviceURI(argv); 361 | 362 | if ((uri != NULL) && (strncmp(uri, "cups-pdf:/", 10) == 0) && strlen(uri) > 10) { 363 | uri = uri + 10; 364 | sprintf(filename, "%s/cups-pdf-%s.conf", CP_CONFIG_PATH, uri); 365 | } 366 | else { 367 | sprintf(filename, "%s/cups-pdf.conf", CP_CONFIG_PATH); 368 | } 369 | read_config_file(filename); 370 | 371 | read_config_ppd(); 372 | 373 | read_config_options(argv[5]); 374 | 375 | (void) umask(0077); 376 | 377 | group=getgrnam(Conf_Grp); 378 | grpstat=setgid(group->gr_gid); 379 | 380 | if (strlen(Conf_Log)) { 381 | if (stat(Conf_Log, &fstatus) || !S_ISDIR(fstatus.st_mode)) { 382 | if (create_dir(Conf_Log, 1)) 383 | return 1; 384 | if (chmod(Conf_Log, 0700)) 385 | return 1; 386 | } 387 | snprintf(filename, BUFSIZE, "%s/%s%s%s", Conf_Log, "cups-pdf-", getenv("PRINTER"), "_log"); 388 | logfp=fopen(filename, "a"); 389 | } 390 | 391 | dump_configuration(); 392 | 393 | if (!group) { 394 | log_event(CPERROR, "Grp not found: %s", Conf_Grp); 395 | return 1; 396 | } 397 | else if (grpstat) { 398 | log_event(CPERROR, "failed to set new gid: %s", Conf_Grp); 399 | return 1; 400 | } 401 | else 402 | log_event(CPDEBUG, "set new gid: %s", Conf_Grp); 403 | 404 | (void) umask(0022); 405 | 406 | if (stat(Conf_Spool, &fstatus) || !S_ISDIR(fstatus.st_mode)) { 407 | if (create_dir(Conf_Spool, 0)) { 408 | log_event(CPERROR, "failed to create spool directory: %s", Conf_Spool); 409 | return 1; 410 | } 411 | if (chmod(Conf_Spool, 0751)) { 412 | log_event(CPERROR, "failed to set mode on spool directory: %s", Conf_Spool); 413 | return 1; 414 | } 415 | if (chown(Conf_Spool, -1, group->gr_gid)) 416 | log_event(CPERROR, "failed to set group id %s on spool directory: %s (non fatal)", Conf_Grp, Conf_Spool); 417 | log_event(CPSTATUS, "spool directory created: %s", Conf_Spool); 418 | } 419 | 420 | (void) umask(0077); 421 | return 0; 422 | } 423 | 424 | static void announce_printers() { 425 | DIR *dir; 426 | struct dirent *config_ent; 427 | int len; 428 | cp_string setup; 429 | 430 | printf("file cups-pdf:/ \"Virtual PDF Printer\" \"CUPS-PDF\" \"MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;\"\n"); 431 | 432 | if ((dir = opendir(CP_CONFIG_PATH)) != NULL) { 433 | while ((config_ent = readdir(dir)) != NULL) { 434 | len = strlen(config_ent->d_name); 435 | if ((strncmp(config_ent->d_name, "cups-pdf-", 9) == 0) && 436 | (len > 14 && strcmp(config_ent->d_name + len - 5, ".conf") == 0)) { 437 | strncpy(setup, config_ent->d_name + 9, BUFSIZE>len-14 ? len-14 : BUFSIZE); 438 | setup[BUFSIZE>len-14 ? len-14 : BUFSIZE - 1] = '\0'; 439 | printf("file cups-pdf:/%s \"Virtual %s Printer\" \"CUPS-PDF\" \"MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;\"\n", setup, setup); 440 | } 441 | } 442 | closedir(dir); 443 | } 444 | return; 445 | } 446 | 447 | static char *preparedirname(struct passwd *passwd, char *uname) { 448 | int size; 449 | char bufin[BUFSIZE], bufout[BUFSIZE], *needle, *cptr; 450 | 451 | needle=strstr(uname, Conf_RemovePrefix); 452 | if ((int)strlen(uname)>(size=strlen(Conf_RemovePrefix))) 453 | uname=uname+size; 454 | 455 | strncpy(bufin, Conf_Out, BUFSIZE); 456 | do { 457 | needle=strstr(bufin, "${HOME}"); 458 | if (needle == NULL) 459 | break; 460 | needle[0]='\0'; 461 | cptr=needle+7; 462 | snprintf(bufout, BUFSIZE, "%s%s%s", bufin, passwd->pw_dir, cptr); 463 | strncpy(bufin, bufout, BUFSIZE); 464 | } while (needle != NULL); 465 | do { 466 | needle=strstr(bufin, "${USER}"); 467 | if (needle == NULL) 468 | break; 469 | needle[0]='\0'; 470 | cptr=needle+7; 471 | if (!Conf_DirPrefix) 472 | snprintf(bufout, BUFSIZE, "%s%s%s", bufin, uname, cptr); 473 | else 474 | snprintf(bufout, BUFSIZE, "%s%s%s", bufin, passwd->pw_name, cptr); 475 | strncpy(bufin, bufout, BUFSIZE); 476 | } while (needle != NULL); 477 | size=strlen(bufin)+1; 478 | cptr=calloc(size, sizeof(char)); 479 | if (cptr == NULL) 480 | return NULL; 481 | snprintf(cptr,size,"%s",bufin); 482 | return cptr; 483 | } 484 | 485 | static int prepareuser(struct passwd *passwd, char *dirname) { 486 | struct stat fstatus; 487 | 488 | (void) umask(0000); 489 | if (stat(dirname, &fstatus) || !S_ISDIR(fstatus.st_mode)) { 490 | if (!strcmp(passwd->pw_name, Conf_AnonUser)) { 491 | if (create_dir(dirname, 0)) { 492 | log_event(CPERROR, "failed to create anonymous output directory: %s", dirname); 493 | return 1; 494 | } 495 | if (chmod(dirname, (mode_t)(0777&~Conf_AnonUMask))) { 496 | log_event(CPERROR, "failed to set mode on anonymous output directory: %s", dirname); 497 | return 1; 498 | } 499 | log_event(CPDEBUG, "anonymous output directory created: %s", dirname); 500 | } 501 | else { 502 | if (create_dir(dirname, 0)) { 503 | log_event(CPERROR, "failed to create user output directory: %s", dirname); 504 | return 1; 505 | } 506 | if (chmod(dirname, (mode_t)(0777&~Conf_UserUMask))) { 507 | log_event(CPERROR, "failed to set mode on user output directory: %s", dirname); 508 | return 1; 509 | } 510 | log_event(CPDEBUG, "user output directory created: %s", dirname); 511 | } 512 | if (chown(dirname, passwd->pw_uid, passwd->pw_gid)) { 513 | log_event(CPERROR, "failed to set owner for output directory: %s", passwd->pw_name); 514 | return 1; 515 | } 516 | log_event(CPDEBUG, "owner set for output directory: %s", passwd->pw_name); 517 | } 518 | (void) umask(0077); 519 | return 0; 520 | } 521 | 522 | /* no validation is done here, please use is_ps_hex_string for that */ 523 | static void decode_ps_hex_string(char *string) { 524 | char *src_ptr, *dst_ptr; 525 | int is_lower_digit; /* 0 - higher digit, 1 - lower digit */ 526 | char number, digit; 527 | 528 | dst_ptr=string; /* we should always be behind src_ptr, 529 | so it's safe to write over original string */ 530 | number=(char)0; 531 | is_lower_digit=0; 532 | for (src_ptr=string+1;*src_ptr != '>';src_ptr++) { /* begin after start marker */ 533 | if (*src_ptr == ' ' || *src_ptr == '\t' ) { /* skip whitespace */ 534 | continue; 535 | } 536 | if (*src_ptr >= 'a') { /* assuming 0 < A < a */ 537 | digit=*src_ptr-'a'+(char)10; 538 | } 539 | else if (*src_ptr >= 'A') { 540 | digit=*src_ptr-'A'+(char)10; 541 | } 542 | else { 543 | digit=*src_ptr-'0'; 544 | } 545 | if (is_lower_digit) { 546 | number|=digit; 547 | *dst_ptr=number; /* write character */ 548 | dst_ptr++; 549 | is_lower_digit=0; 550 | } 551 | else { /* higher digit */ 552 | number=digit<<4; 553 | is_lower_digit=1; 554 | } 555 | } 556 | if (is_lower_digit) { /* write character with lower digit = 0, 557 | as per PostScript Language Reference */ 558 | *dst_ptr=number; 559 | dst_ptr++; 560 | /* is_lower_digit=0; */ 561 | } 562 | *dst_ptr=0; /* finish him! */ 563 | return; 564 | } 565 | 566 | static int is_ps_hex_string(char *string) { 567 | int got_end_marker=0; 568 | char *ptr; 569 | 570 | if (string[0] != '<') { /* if has no start marker */ 571 | log_event(CPDEBUG, "not a hex string, has no start marker: %s", string); 572 | return 0; /* not hex string, obviously */ 573 | } 574 | for (ptr=string+1;*ptr;ptr++) { /* begin after start marker */ 575 | if (got_end_marker) { /* got end marker and still something left */ 576 | log_event(CPDEBUG, "not a hex string, trailing characters after end marker: %s", ptr); 577 | return 0; /* that's bad! */ 578 | } 579 | else if (*ptr == '>') { /* here it is! */ 580 | got_end_marker=1; 581 | log_event(CPDEBUG, "got an end marker in the hex string, expecting 0-termination: %s", ptr); 582 | } 583 | else if ( !( 584 | isxdigit(*ptr) || 585 | *ptr == ' ' || 586 | *ptr == '\t' 587 | ) ) { 588 | log_event(CPDEBUG, "not a hex string, invalid character: %s", ptr); 589 | return 0; /* that's bad, too */ 590 | } 591 | } 592 | return got_end_marker; 593 | } 594 | 595 | static void alternate_replace_string(char *string) { 596 | unsigned int i; 597 | 598 | log_event(CPDEBUG, "removing alternate special characters from title: %s", string); 599 | for (i=0;i<(unsigned int)strlen(string);i++) 600 | if ( isascii(string[i]) && /* leaving non-ascii characters intact */ 601 | (!isalnum(string[i])) && 602 | string[i] != '-' && string[i] != '+' && string[i] != '.') 603 | string[i]='_'; 604 | return; 605 | } 606 | 607 | static void replace_string(char *string) { 608 | unsigned int i; 609 | 610 | log_event(CPDEBUG, "removing special characters from title: %s", string); 611 | for (i=0;i<(unsigned int)strlen(string);i++) 612 | if ( ( string[i] < '0' || string[i] > '9' ) && 613 | ( string[i] < 'A' || string[i] > 'Z' ) && 614 | ( string[i] < 'a' || string[i] > 'z' ) && 615 | string[i] != '-' && string[i] != '+' && string[i] != '.') 616 | string[i]='_'; 617 | return; 618 | } 619 | 620 | static int preparetitle(char *title) { 621 | char *cut; 622 | int i; 623 | 624 | if (title != NULL) { 625 | if (Conf_DecodeHexStrings) { 626 | log_event(CPSTATUS, "***Experimental Option: DecodeHexStrings"); 627 | log_event(CPDEBUG, "checking for hex strings: %s", title); 628 | if (is_ps_hex_string(title)) 629 | decode_ps_hex_string(title); 630 | log_event(CPDEBUG, "calling alternate_replace_string"); 631 | alternate_replace_string(title); 632 | } 633 | else { 634 | replace_string(title); 635 | } 636 | i=strlen(title); 637 | if (i>1) { 638 | while (title[--i]=='_'); 639 | if (i1) { 646 | log_event(CPDEBUG, "removing leading _ from title: %s", title); 647 | memmove(title, title+i-1, strlen(title)-i+2); 648 | } 649 | } 650 | while (strlen(title)>2 && title[0]=='(' && title[strlen(title)-1]==')') { 651 | log_event(CPDEBUG, "removing enclosing parentheses () from full title: %s", title); 652 | title[strlen(title)-1]='\0'; 653 | memmove(title, title+1, strlen(title)); 654 | } 655 | } 656 | cut=strrchr(title, '/'); 657 | if (cut != NULL) { 658 | log_event(CPDEBUG, "removing slashes from full title: %s", title); 659 | memmove(title, cut+1, strlen(cut+1)+1); 660 | } 661 | cut=strrchr(title, '\\'); 662 | if (cut != NULL) { 663 | log_event(CPDEBUG, "removing backslashes from full title: %s", title); 664 | memmove(title, cut+1, strlen(cut+1)+1); 665 | } 666 | cut=strrchr(title, '.'); 667 | if ((cut != NULL) && ((int)strlen(cut) <= Conf_Cut+1) && (cut != title)) { 668 | log_event(CPDEBUG, "removing file name extension: %s", cut); 669 | cut[0]='\0'; 670 | } 671 | if (strlen(title)>Conf_Truncate) { 672 | title[Conf_Truncate]='\0'; 673 | log_event(CPDEBUG, "truncating title: %s", title); 674 | } 675 | return strcmp(title, ""); 676 | } 677 | 678 | static char *fgets2(char *fbuffer, int fbufsize, FILE *ffpsrc) { 679 | /* like fgets() but linedelimiters are 0x0A, 0x0C, 0x0D (LF, FF, CR). */ 680 | int c, pos; 681 | char *result; 682 | 683 | if (!Conf_FixNewlines) 684 | return fgets(fbuffer, fbufsize, ffpsrc); 685 | 686 | result=NULL; 687 | pos=0; 688 | 689 | while (pos < fbufsize) { /* pos in [0..fbufsize-1] */ 690 | c=fgetc(ffpsrc); /* converts CR/LF to LF in some OSses */ 691 | if (c == EOF) /* EOF _or_ error */ 692 | break; 693 | fbuffer[pos++]=c; 694 | if (c == 0x0A || c == 0x0C || c == 0x0D) /* line is at an end */ 695 | break; 696 | } 697 | 698 | if (pos > 0 && !ferror(ffpsrc)) { /* at least one char read and no error */ 699 | fbuffer[pos]='\0'; 700 | result=fbuffer; 701 | } 702 | 703 | return result; 704 | } 705 | 706 | static int preparespoolfile(FILE *fpsrc, char *spoolfile, char *title, char *cmdtitle, 707 | int job, struct passwd *passwd) { 708 | cp_string buffer; 709 | int rec_depth,is_title=0; 710 | FILE *fpdest; 711 | size_t bytes = 0; 712 | 713 | if (fpsrc == NULL) { 714 | log_event(CPERROR, "failed to open source stream"); 715 | return 1; 716 | } 717 | log_event(CPDEBUG, "source stream ready"); 718 | fpdest=fopen(spoolfile, "w"); 719 | if (fpdest == NULL) { 720 | log_event(CPERROR, "failed to open spoolfile: %s", spoolfile); 721 | (void) fclose(fpsrc); 722 | return 1; 723 | } 724 | log_event(CPDEBUG, "destination stream ready: %s", spoolfile); 725 | if (chown(spoolfile, passwd->pw_uid, -1)) { 726 | log_event(CPERROR, "failed to set owner for spoolfile: %s", spoolfile); 727 | return 1; 728 | } 729 | log_event(CPDEBUG, "owner set for spoolfile: %s", spoolfile); 730 | rec_depth=0; 731 | if (Conf_FixNewlines) 732 | log_event(CPSTATUS, "***Experimental Option: FixNewlines"); 733 | else 734 | log_event(CPDEBUG, "using traditional fgets"); 735 | 736 | while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) { 737 | if (!strncmp(buffer, "%PDF", 4)) { 738 | log_event(CPDEBUG, "found beginning of PDF code: %s", buffer); 739 | input_is_pdf=1; 740 | break; 741 | } 742 | if (!strncmp(buffer, "%!", 2) && strncmp(buffer, "%!PS-AdobeFont", 14)) { 743 | log_event(CPDEBUG, "found beginning of postscript code: %s", buffer); 744 | break; 745 | } 746 | } 747 | 748 | (void) fputs(buffer, fpdest); 749 | 750 | if (input_is_pdf) { 751 | while((bytes = fread(buffer, sizeof(char), BUFSIZE, fpsrc)) > 0) 752 | fwrite(buffer, sizeof(char), bytes, fpdest); 753 | } else { 754 | log_event(CPDEBUG, "now extracting postscript code"); 755 | while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) { 756 | (void) fputs(buffer, fpdest); 757 | if (!is_title && !rec_depth) 758 | if (sscanf(buffer, "%%%%Title: %"TBUFSIZE"c", title)==1) { 759 | log_event(CPDEBUG, "found title in ps code: %s", title); 760 | is_title=1; 761 | } 762 | if (!strncmp(buffer, "%!", 2)) { 763 | log_event(CPDEBUG, "found embedded (e)ps code: %s", buffer); 764 | rec_depth++; 765 | } 766 | else if (!strncmp(buffer, "%%EOF", 5)) { 767 | if (!rec_depth) { 768 | log_event(CPDEBUG, "found end of postscript code: %s", buffer); 769 | break; 770 | } 771 | else { 772 | log_event(CPDEBUG, "found end of embedded (e)ps code: %s", buffer); 773 | rec_depth--; 774 | } 775 | } 776 | } 777 | } 778 | 779 | (void) fclose(fpdest); 780 | (void) fclose(fpsrc); 781 | log_event(CPDEBUG, "all data written to spoolfile: %s", spoolfile); 782 | 783 | if (cmdtitle == NULL || !strcmp(cmdtitle, "(stdin)")) 784 | buffer[0]='\0'; 785 | else 786 | strncpy(buffer, cmdtitle, BUFSIZE); 787 | if (title == NULL || !strcmp(title, "((stdin))")) 788 | title[0]='\0'; 789 | 790 | if (Conf_TitlePref) { 791 | log_event(CPDEBUG, "trying to use commandline title: %s", buffer); 792 | if (!preparetitle(buffer)) { 793 | log_event(CPDEBUG, "empty commandline title, using PS title: %s", title); 794 | if (!preparetitle(title)) 795 | log_event(CPDEBUG, "empty PS title"); 796 | } 797 | else 798 | snprintf(title, BUFSIZE, "%s", buffer); 799 | } 800 | else { 801 | log_event(CPDEBUG, "trying to use PS title: %s", title); 802 | if (!preparetitle(title)) { 803 | log_event(CPDEBUG, "empty PS title, using commandline title: %s", buffer); 804 | if (!preparetitle(buffer)) 805 | log_event(CPDEBUG, "empty commandline title"); 806 | else 807 | snprintf(title, BUFSIZE, "%s", buffer); 808 | } 809 | } 810 | 811 | if (!strcmp(title, "")) { 812 | if (Conf_Label == 2) 813 | snprintf(title, BUFSIZE, "untitled_document-job_%i", job); 814 | else 815 | snprintf(title, BUFSIZE, "job_%i-untitled_document", job); 816 | log_event(CPDEBUG, "no title found - using default value: %s", title); 817 | } 818 | else { 819 | if (Conf_Label) { 820 | strcpy(buffer, title); 821 | if (Conf_Label == 2) 822 | snprintf(title, BUFSIZE, "%s-job_%i", buffer, job); 823 | else 824 | snprintf(title, BUFSIZE, "job_%i-%s", job, buffer); 825 | } 826 | log_event(CPDEBUG, "title successfully retrieved: %s", title); 827 | } 828 | return 0; 829 | } 830 | 831 | int main(int argc, char *argv[]) { 832 | char *user, *dirname, *spoolfile, *outfile, *gscall, *ppcall; 833 | cp_string title; 834 | int size; 835 | mode_t mode; 836 | struct passwd *passwd; 837 | gid_t *groups; 838 | int ngroups; 839 | pid_t pid; 840 | 841 | if (setuid(0)) { 842 | (void) fputs("CUPS-PDF cannot be called without root privileges!\n", stderr); 843 | return 0; 844 | } 845 | 846 | if (argc==1) { 847 | announce_printers(); 848 | return 0; 849 | } 850 | if (argc<6 || argc>7) { 851 | (void) fputs("Usage: cups-pdf job-id user title copies options [file]\n", stderr); 852 | return 0; 853 | } 854 | 855 | if (init(argv)) 856 | return 5; 857 | log_event(CPDEBUG, "initialization finished: %s", CPVERSION); 858 | 859 | size=strlen(Conf_UserPrefix)+strlen(argv[2])+1; 860 | user=calloc(size, sizeof(char)); 861 | if (user == NULL) { 862 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 863 | return 5; 864 | } 865 | snprintf(user, size, "%s%s", Conf_UserPrefix, argv[2]); 866 | passwd=getpwnam(user); 867 | if (passwd == NULL && Conf_LowerCase) { 868 | log_event(CPDEBUG, "unknown user: %s", user); 869 | for (size=0;size<(int) strlen(argv[2]);size++) 870 | argv[2][size]=tolower(argv[2][size]); 871 | log_event(CPDEBUG, "trying lower case user name: %s", argv[2]); 872 | size=strlen(Conf_UserPrefix)+strlen(argv[2])+1; 873 | snprintf(user, size, "%s%s", Conf_UserPrefix, argv[2]); 874 | passwd=getpwnam(user); 875 | } 876 | if (passwd == NULL) { 877 | if (strlen(Conf_AnonUser)) { 878 | passwd=getpwnam(Conf_AnonUser); 879 | if (passwd == NULL) { 880 | log_event(CPERROR, "username for anonymous access unknown: %s", Conf_AnonUser); 881 | free(user); 882 | if (logfp!=NULL) 883 | (void) fclose(logfp); 884 | return 5; 885 | } 886 | log_event(CPDEBUG, "unknown user: %s", user); 887 | size=strlen(Conf_AnonDirName)+4; 888 | dirname=calloc(size, sizeof(char)); 889 | if (dirname == NULL) { 890 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 891 | free(user); 892 | if (logfp!=NULL) 893 | (void) fclose(logfp); 894 | return 5; 895 | } 896 | snprintf(dirname, size, "%s", Conf_AnonDirName); 897 | while (strlen(dirname) && ((dirname[strlen(dirname)-1] == '\n') || 898 | (dirname[strlen(dirname)-1] == '\r'))) 899 | dirname[strlen(dirname)-1]='\0'; 900 | log_event(CPDEBUG, "output directory name generated: %s", dirname); 901 | } 902 | else { 903 | log_event(CPSTATUS, "anonymous access denied: %s", user); 904 | free(user); 905 | if (logfp!=NULL) 906 | (void) fclose(logfp); 907 | return 0; 908 | } 909 | mode=(mode_t)(0666&~Conf_AnonUMask); 910 | } 911 | else { 912 | log_event(CPDEBUG, "user identified: %s", passwd->pw_name); 913 | if ((dirname=preparedirname(passwd, argv[2])) == NULL) { 914 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 915 | free(user); 916 | if (logfp!=NULL) 917 | (void) fclose(logfp); 918 | return 5; 919 | } 920 | while (strlen(dirname) && ((dirname[strlen(dirname)-1] == '\n') || 921 | (dirname[strlen(dirname)-1] == '\r'))) 922 | dirname[strlen(dirname)-1]='\0'; 923 | log_event(CPDEBUG, "output directory name generated: %s", dirname); 924 | mode=(mode_t)(0666&~Conf_UserUMask); 925 | } 926 | ngroups=32; 927 | groups=calloc(ngroups, sizeof(gid_t)); 928 | if (groups == NULL) { 929 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 930 | free(user); 931 | if (logfp!=NULL) 932 | (void) fclose(logfp); 933 | return 5; 934 | } 935 | size=getgrouplist(user, passwd->pw_gid, groups, &ngroups); 936 | if (size == -1) { 937 | free(groups); 938 | groups=calloc(ngroups, sizeof(gid_t)); 939 | size=getgrouplist(user, passwd->pw_gid, groups, &ngroups); 940 | } 941 | if (size < 0) { 942 | log_event(CPERROR, "getgrouplist failed"); 943 | free(user); 944 | free(groups); 945 | if (logfp!=NULL) 946 | (void) fclose(logfp); 947 | return 5; 948 | } 949 | free(user); 950 | if (prepareuser(passwd, dirname)) { 951 | free(groups); 952 | free(dirname); 953 | if (logfp!=NULL) 954 | (void) fclose(logfp); 955 | return 5; 956 | } 957 | log_event(CPDEBUG, "user information prepared"); 958 | 959 | size=strlen(Conf_Spool)+22; 960 | spoolfile=calloc(size, sizeof(char)); 961 | if (spoolfile == NULL) { 962 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 963 | free(groups); 964 | free(dirname); 965 | if (logfp!=NULL) 966 | (void) fclose(logfp); 967 | return 5; 968 | } 969 | snprintf(spoolfile, size, "%s/cups2pdf-%i", Conf_Spool, (int) getpid()); 970 | log_event(CPDEBUG, "spoolfile name created: %s", spoolfile); 971 | 972 | if (argc == 6) { 973 | if (preparespoolfile(stdin, spoolfile, title, argv[3], atoi(argv[1]), passwd)) { 974 | free(groups); 975 | free(dirname); 976 | free(spoolfile); 977 | if (logfp!=NULL) 978 | (void) fclose(logfp); 979 | return 5; 980 | } 981 | log_event(CPDEBUG, "input data read from stdin"); 982 | } 983 | else { 984 | if (preparespoolfile(fopen(argv[6], "r"), spoolfile, title, argv[3], atoi(argv[1]), passwd)) { 985 | free(groups); 986 | free(dirname); 987 | free(spoolfile); 988 | if (logfp!=NULL) 989 | (void) fclose(logfp); 990 | return 5; 991 | } 992 | log_event(CPDEBUG, "input data read from file: %s", argv[6]); 993 | } 994 | 995 | size=strlen(dirname)+strlen(title)+strlen(Conf_OutExtension)+3; 996 | outfile=calloc(size, sizeof(char)); 997 | if (outfile == NULL) { 998 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 999 | if (unlink(spoolfile)) 1000 | log_event(CPERROR, "failed to unlink spoolfile during clean-up: %s", spoolfile); 1001 | free(groups); 1002 | free(dirname); 1003 | free(spoolfile); 1004 | if (logfp!=NULL) 1005 | (void) fclose(logfp); 1006 | return 5; 1007 | } 1008 | if (strlen(Conf_OutExtension)) 1009 | snprintf(outfile, size, "%s/%s.%s", dirname, title, Conf_OutExtension); 1010 | else 1011 | snprintf(outfile, size, "%s/%s", dirname, title); 1012 | log_event(CPDEBUG, "output filename created: %s", outfile); 1013 | 1014 | size=strlen(Conf_GSCall)+strlen(Conf_GhostScript)+strlen(Conf_PDFVer)+strlen(outfile)+strlen(spoolfile)+6; 1015 | gscall=calloc(size, sizeof(char)); 1016 | if (gscall == NULL) { 1017 | (void) fputs("CUPS-PDF: failed to allocate memory\n", stderr); 1018 | if (unlink(spoolfile)) 1019 | log_event(CPERROR, "failed to unlink spoolfile during clean-up: %s", spoolfile); 1020 | free(groups); 1021 | free(dirname); 1022 | free(spoolfile); 1023 | free(outfile); 1024 | if (logfp!=NULL) 1025 | (void) fclose(logfp); 1026 | return 5; 1027 | } 1028 | if (input_is_pdf) { 1029 | snprintf(gscall, size, "cp \"%s\" \"%s\"", spoolfile, outfile); 1030 | } else { 1031 | snprintf(gscall, size, Conf_GSCall, Conf_GhostScript, Conf_PDFVer, outfile, spoolfile); 1032 | } 1033 | 1034 | log_event(CPDEBUG, "ghostscript commandline built: %s", gscall); 1035 | 1036 | (void) unlink(outfile); 1037 | log_event(CPDEBUG, "output file unlinked: %s", outfile); 1038 | 1039 | if (putenv(Conf_GSTmp)) { 1040 | log_event(CPERROR, "insufficient space in environment to set TMPDIR: %s", Conf_GSTmp); 1041 | if (unlink(spoolfile)) 1042 | log_event(CPERROR, "failed to unlink spoolfile during clean-up: %s", spoolfile); 1043 | free(groups); 1044 | free(dirname); 1045 | free(spoolfile); 1046 | free(outfile); 1047 | free(gscall); 1048 | if (logfp!=NULL) 1049 | (void) fclose(logfp); 1050 | return 5; 1051 | } 1052 | log_event(CPDEBUG, "TMPDIR set for GhostScript: %s", getenv("TMPDIR")); 1053 | 1054 | pid=fork(); 1055 | 1056 | if (!pid) { 1057 | log_event(CPDEBUG, "entering child process"); 1058 | 1059 | if (setgid(passwd->pw_gid)) 1060 | log_event(CPERROR, "failed to set GID for current user"); 1061 | else 1062 | log_event(CPDEBUG, "GID set for current user"); 1063 | if (setgroups(ngroups, groups)) 1064 | log_event(CPERROR, "failed to set supplementary groups for current user"); 1065 | else 1066 | log_event(CPDEBUG, "supplementary groups set for current user"); 1067 | if (setuid(passwd->pw_uid)) 1068 | log_event(CPERROR, "failed to set UID for current user: %s", passwd->pw_name); 1069 | else 1070 | log_event(CPDEBUG, "UID set for current user: %s", passwd->pw_name); 1071 | 1072 | (void) umask(0077); 1073 | size=system(gscall); 1074 | log_event(CPDEBUG, "ghostscript has finished: %d", size); 1075 | if (chmod(outfile, mode)) 1076 | log_event(CPERROR, "failed to set file mode for PDF file: %s (non fatal)", outfile); 1077 | else 1078 | log_event(CPDEBUG, "file mode set for user output: %s", outfile); 1079 | 1080 | if (strlen(Conf_PostProcessing)) { 1081 | size=strlen(Conf_PostProcessing)+strlen(outfile)+strlen(passwd->pw_name)+strlen(argv[2])+4; 1082 | ppcall=calloc(size, sizeof(char)); 1083 | if (ppcall == NULL) 1084 | log_event(CPERROR, "failed to allocate memory for postprocessing (non fatal)"); 1085 | else { 1086 | snprintf(ppcall, size, "%s %s %s %s", Conf_PostProcessing, outfile, passwd->pw_name, argv[2]); 1087 | log_event(CPDEBUG, "postprocessing commandline built: %s", ppcall); 1088 | size=system(ppcall); 1089 | snprintf(title,BUFSIZE,"%d",size); 1090 | log_event(CPDEBUG, "postprocessing has finished: %s", title); 1091 | free(ppcall); 1092 | } 1093 | } 1094 | else 1095 | log_event(CPDEBUG, "no postprocessing"); 1096 | 1097 | return 0; 1098 | } 1099 | log_event(CPDEBUG, "waiting for child to exit"); 1100 | (void) waitpid(pid,NULL,0); 1101 | 1102 | if (unlink(spoolfile)) 1103 | log_event(CPERROR, "failed to unlink spoolfile: %s (non fatal)", spoolfile); 1104 | else 1105 | log_event(CPDEBUG, "spoolfile unlinked: %s", spoolfile); 1106 | 1107 | free(groups); 1108 | free(dirname); 1109 | free(spoolfile); 1110 | free(outfile); 1111 | free(gscall); 1112 | 1113 | log_event(CPDEBUG, "all memory has been freed"); 1114 | 1115 | log_event(CPSTATUS, "PDF creation successfully finished for %s", passwd->pw_name); 1116 | 1117 | if (logfp!=NULL) 1118 | (void) fclose(logfp); 1119 | return 0; 1120 | } 1121 | -------------------------------------------------------------------------------- /cups-pdf.conf: -------------------------------------------------------------------------------- 1 | # cups-pdf.conf -- CUPS Backend Configuration (version 3.0.1, 2017-02-24) 2 | # 18.09.2005, Volker C. Behr 3 | # volker@cups-pdf.de 4 | # http://www.cups-pdf.de 5 | # 6 | # 7 | # This code may be freely distributed as long as this header 8 | # is preserved. Changes to the code should be clearly indicated. 9 | # 10 | # This code is distributed under the GPL. 11 | # (http://www.gnu.org/copyleft/gpl.html) 12 | # 13 | # For more detailed licensing information see cups-pdf.c in the 14 | # corresponding version number. 15 | 16 | ########################################################################### 17 | # # 18 | # This is the configuration file for CUPS-PDF. Values that are not set in # 19 | # here will use the defaults. Changes take effect immediately without the # 20 | # need for restarting any services. # 21 | # # 22 | # Take care not to add whitespaces at the end of a line! # 23 | # # 24 | # Options are marked where they can be set (setting via PPD requires the # 25 | # PPD file that comes with CUPS-PDF to be used!). # 26 | # Options passed via lpoptions that are not named for lpoptions here are # 27 | # ignored. # 28 | # Options precedence is as follows: # 29 | # 1st: lpoptions # 30 | # 2nd: PPD settings # 31 | # 3rd: config file (this file) # 32 | # 4th: default values # 33 | ########################################################################### 34 | 35 | 36 | ########################################################################### 37 | # # 38 | # Path Settings # 39 | # # 40 | ########################################################################### 41 | 42 | ### Key: Out (config) 43 | ## CUPS-PDF output directory 44 | ## special qualifiers: 45 | ## ${HOME} will be expanded to the user's home directory 46 | ## ${USER} will be expanded to the user name 47 | ## in case it is an NFS export make sure it is exported without 48 | ## root_squash! 49 | ### Default: /var/spool/cups-pdf/${USER} 50 | 51 | #Out /var/spool/cups-pdf/${USER} 52 | 53 | ### Key: AnonDirName (config) 54 | ## ABSOLUTE path for anonymously created PDF files 55 | ## if anonymous access is disabled this setting has no effect 56 | ### Default: /var/spool/cups-pdf/ANONYMOUS 57 | 58 | #AnonDirName /var/spool/cups-pdf/ANONYMOUS 59 | 60 | ### Key: Spool (config) 61 | ## CUPS-PDF spool directory - make sure there is no user 'SPOOL' on your 62 | ## system or change the path 63 | ### Default: /var/spool/cups-pdf/SPOOL 64 | 65 | #Spool /var/spool/cups-pdf/SPOOL 66 | 67 | 68 | ########################################################################### 69 | # # 70 | # Filename Settings # 71 | # # 72 | ########################################################################### 73 | 74 | ### Key: Truncate (config, ppd, lpoptions) 75 | ## truncate long filenames to a maximum of characters 76 | ## this does not consider the full path to the output but only the filename 77 | ## without the .pdf-extension or a job-id prefix (see 'Label') 78 | ## the minimal value is 8 79 | ### Default: 64 80 | 81 | #Truncate 64 82 | 83 | ### Key: Cut (config, lpoptions) 84 | ## removing file name extensions before appending .pdf to output 85 | ## extensions will only be removed if _both_ the following criteria are met: 86 | ## - the extension (w/o the dot) is not longer than characters 87 | ## - the remaining filename has a minimal length of 1 character 88 | ## set Cut to -1 in order to disable cutting 89 | ## recommended values: pure UNIX environment : -1 90 | ## mixed environments : 3 91 | ### Default: 3 92 | 93 | #Cut 3 94 | 95 | ### Key: Label (config, ppd, lpoptions) 96 | ## label all jobs with a unique job-id in order to avoid overwriting old 97 | ## files in case new ones with identical names are created; always true for 98 | ## untitled documents 99 | ## 0: label untitled documents only 100 | ## 1: label all documents with a preceeding "job_#-" 101 | ## 2: label all documents with a tailing "-job_#" 102 | ### Default: 0 103 | 104 | #Label 0 105 | 106 | ### Key: TitlePref (config, ppd, lpoptions) 107 | ## where to look first for a title when creating the output filename 108 | ## (title in PS file or title on commandline): 109 | ## 0: prefer title from %Title statement in the PS file 110 | ## 1: prefer title passed via commandline 111 | ### Default: 0 112 | 113 | #TitlePref 0 114 | 115 | 116 | ########################################################################### 117 | # # 118 | # User Settings # 119 | # # 120 | ########################################################################### 121 | 122 | ### Key: AnonUser (config) 123 | ## uid for anonymous PDF creation (this might be a security issue) 124 | ## this setting has no influence on AnonDirName (see there) 125 | ## set this to an empty value to disable anonymous 126 | ### Default: nobody 127 | 128 | #AnonUser nobody 129 | 130 | ### Key: LowerCase (config) 131 | ## This options allows to check user names given to CUPS-PDF additionally 132 | ## against their lower case variants. This is necessary since in some 133 | ## Windows environments only upper case user names are passed. Usually UNIX 134 | ## user names are all lower case and it is save to use this option 135 | ## but be aware that it can lead to mis-identifications in case 136 | ## you have user names that differ only in upper/lower case. 137 | ## check only against user name as passed to CUPS : 0 138 | ## check additionally against lower case user name : 1 139 | ### Default: 1 140 | 141 | #LowerCase 1 142 | 143 | ### Key: UserPrefix (config) 144 | ## some installations require a domain prefix added to the user name 145 | ## leave empty for no prefix 146 | ### Default: 147 | 148 | #UserPrefix 149 | 150 | ### Key: DirPrefix (config) 151 | ## if a prefix was defined above this switch toggels whether to include 152 | ## the prefix in the output directory's name (if not $HOME) or not 153 | ## 0: do not include, 1: include 154 | ### Default: 0 155 | 156 | #DirPrefix 0 157 | 158 | ### Key: RemovePrefix (config) 159 | ## some installation pass usernames with a prefix (usually a domain name) 160 | ## if you do not want this prefix to be used by the ${USER} variable for 161 | ## output directories put the part which is to be cut here 162 | ### Default: 163 | 164 | #RemovePrefix 165 | 166 | 167 | ########################################################################### 168 | # # 169 | # Security Settings # 170 | # # 171 | ########################################################################### 172 | 173 | ### Key: AnonUMask (config) 174 | ## umask for anonymous output 175 | ## these are the _inverse_ permissions to be granted 176 | ### Default: 0000 177 | 178 | #AnonUMask 0000 179 | 180 | ### Key: UserUMask (config, lptoptions) 181 | ## umask for user output of known users 182 | ## changing this can introduce security leaks if confidential 183 | ## information is processed! 184 | ### Default: 0077 185 | 186 | #UserUMask 0077 187 | 188 | ### Key: Grp (config) 189 | ## group cups-pdf is supposed to run as - this will also be the gid for all 190 | ## created directories and log files 191 | ### Default: lp 192 | 193 | #Grp lp 194 | 195 | ### Key: AllowUnsafeOptions (config) 196 | ## DON'T CHANGE THIS SETTING UNLESS YOU ABSOLUTELY KNOW WHAT YOU ARE DOING 197 | ## set to 1 in order to allow users to override any option - including 198 | ## those that pose SEVERE SECURITY RISKS, set to 0 for full security 199 | ### Default: 0 200 | 201 | #AllowUnsafeOptions 0 202 | 203 | 204 | ########################################################################### 205 | # # 206 | # Log Settings # 207 | # # 208 | ########################################################################### 209 | 210 | ### Key: Log (config) 211 | ## CUPS-PDF log directory 212 | ## set this to an empty value to disable all logging 213 | ### Default: /var/log/cups 214 | 215 | #Log /var/log/cups 216 | 217 | ### Key: LogType (config, ppd) 218 | ## log-mode 219 | ## 1: errors 220 | ## 2: status (i.e. activity) 221 | ## 4: debug - this will generate a lot of log-output! 222 | ## add up values to combine options, i.e. 7 is full logging 223 | ## if logging is disabled these setting have no effect 224 | ### Default: 3 225 | 226 | #LogType 3 227 | 228 | 229 | ########################################################################### 230 | # # 231 | # PDF Conversion Settings # 232 | # # 233 | ########################################################################### 234 | 235 | ### Key: GhostScript (config) 236 | ## location of GhostScript binary (gs) 237 | ## MacOSX: for using pstopdf (recommended) set this to /usr/bin/pstopdf 238 | ## or its proper location on your system 239 | ### Default: /usr/bin/gs 240 | 241 | #GhostScript /usr/bin/gs 242 | 243 | ### Key: GSTmp (config) 244 | ## location of temporary files during GhostScript operation 245 | ## this must be user-writable like /var/tmp or /tmp ! 246 | ### Default: /var/tmp 247 | 248 | #GSTmp /var/tmp 249 | 250 | ### Key: GSCall (config) 251 | ## command line for calling GhostScript (!!! DO NOT USE NEWLINES !!!) 252 | ## MacOSX: for using pstopdf set this to %s %s -o %s %s 253 | ### Default: %s -q -dCompatibilityLevel=%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile="%s" -dAutoRotatePages=/PageByPage -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dPDFSETTINGS=/prepress -c .setpdfwrite -f %s 254 | 255 | #GSCall %s -q -dCompatibilityLevel=%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile="%s" -dAutoRotatePages=/PageByPage -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dPDFSETTINGS=/prepress -c .setpdfwrite -f %s 256 | 257 | ### Key: PDFVer (config, ppd, lptopions) 258 | ## PDF version to be created - can be "1.5", "1.4", "1.3" or "1.2" 259 | ## MacOSX: for using pstopdf set this to an empty value 260 | ### Default: 1.4 261 | 262 | #PDFVer 1.4 263 | 264 | ### Key: PostProcessing (config, lptoptions) 265 | ## postprocessing script that will be called after the creation of the PDF 266 | ## as arguments the filename of the PDF, the username as determined by 267 | ## CUPS-PDF and the one as given to CUPS-PDF will be passed 268 | ## the script will be called with user privileges 269 | ## set this to an empty value to use no postprocessing 270 | ### Default: 271 | 272 | #PostProcessing 273 | 274 | 275 | ########################################################################### 276 | # # 277 | # Experimental Settings # 278 | # These settings activate experimental options. If you decide to use # 279 | # them I would appreciate any feedback - including an 'ok' if they # 280 | # work as expected - so I can eventually put them into the non- # 281 | # experimental sections. # 282 | # # 283 | ########################################################################### 284 | 285 | ### Key: DecodeHexStrings (config) 286 | ## this option will try to decode hex strings in the title to allow 287 | ## internationalized titles 288 | ## (have a look at pstitleconv on www.cups-pdf.de for a suitable filter 289 | ## for data from Windows clients) 290 | ## 0: disable, 1: enable 291 | ### Default: 0 292 | 293 | #DecodeHexStrings 0 294 | 295 | ### Key: FixNewlines (config) 296 | ## this option will try to fix various unusal line delimiters (e.g. 297 | ## form feeds) 298 | ## especially useful when using non-Linux-generated files 299 | ## 0: disable, 1: enable 300 | ### Default: 0 301 | 302 | #FixNewlines 0 303 | -------------------------------------------------------------------------------- /cups-pdf.h: -------------------------------------------------------------------------------- 1 | /* cups-pdf.h -- CUPS Backend Header File (version 3.0.1, 2017-02-24) 2 | 16.05.2003, Volker C. Behr 3 | volker@cups-pdf.de 4 | http://www.cups-pdf.de 5 | 6 | 7 | This code may be freely distributed as long as this header 8 | is preserved. Changes to the code should be clearly indicated. 9 | 10 | This code is distributed under the GPL. 11 | (http://www.gnu.org/copyleft/gpl.html) 12 | 13 | For more detailed licensing information see cups-pdf.c in the 14 | corresponding version number. */ 15 | 16 | 17 | /* User-customizable settings - if unsure leave the default values 18 | / they are reasonable for most systems. */ 19 | 20 | /* location of the configuration file */ 21 | #define CP_CONFIG_PATH "/etc/cups" 22 | 23 | 24 | /* --- DO NOT EDIT BELOW THIS LINE --- */ 25 | 26 | /* The following settings are for internal purposes only - all relevant 27 | / options listed below can be set via cups-pdf.conf at runtime */ 28 | 29 | #define CPVERSION "v3.0.1" 30 | 31 | #define CPERROR 1 32 | #define CPSTATUS 2 33 | #define CPDEBUG 4 34 | 35 | #define BUFSIZE 4096 36 | #define TBUFSIZE "4096" 37 | 38 | typedef char cp_string[BUFSIZE]; 39 | 40 | 41 | #define SEC_CONF 1 42 | #define SEC_PPD 2 43 | #define SEC_LPOPT 4 44 | 45 | /* order in the enum and the struct-array has to be identical! */ 46 | 47 | enum configOptions { AnonDirName, AnonUser, GhostScript, GSCall, Grp, GSTmp, Log, PDFVer, PostProcessing, Out, Spool, UserPrefix, RemovePrefix, OutExtension, Cut, Truncate, DirPrefix, Label, LogType, LowerCase, TitlePref, DecodeHexStrings, FixNewlines, AllowUnsafeOptions, AnonUMask, UserUMask, END_OF_OPTIONS }; 48 | 49 | struct { 50 | char *key_name; 51 | int security; 52 | union { 53 | cp_string sval; 54 | int ival; 55 | mode_t modval; 56 | } value; 57 | } configData[] = { 58 | { "AnonDirName", SEC_CONF|SEC_PPD, { "/var/spool/cups-pdf/ANONYMOUS" } }, 59 | { "AnonUser", SEC_CONF|SEC_PPD, { "nobody" } }, 60 | { "GhostScript", SEC_CONF|SEC_PPD, { "/usr/bin/gs" } }, 61 | { "GSCall", SEC_CONF|SEC_PPD, { "%s -q -dCompatibilityLevel=%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile=\"%s\" -dAutoRotatePages=/PageByPage -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dPDFSETTINGS=/prepress -c .setpdfwrite -f %s" } }, 62 | { "Grp", SEC_CONF|SEC_PPD, { "lp" } }, 63 | { "GSTmp", SEC_CONF|SEC_PPD, { "TMPDIR=/var/tmp" } }, 64 | { "Log", SEC_CONF|SEC_PPD, { "/var/log/cups" } }, 65 | { "PDFVer", SEC_CONF|SEC_PPD|SEC_LPOPT, { "1.4" } }, 66 | { "PostProcessing", SEC_CONF|SEC_PPD|SEC_LPOPT, { "" } }, 67 | { "Out", SEC_CONF|SEC_PPD, { "/var/spool/cups-pdf/${USER}" } }, 68 | { "Spool", SEC_CONF|SEC_PPD, { "/var/spool/cups-pdf/SPOOL" } }, 69 | { "UserPrefix", SEC_CONF|SEC_PPD, { "" } }, 70 | { "RemovePrefix", SEC_CONF|SEC_PPD, { "" } }, 71 | { "OutExtension", SEC_CONF|SEC_PPD|SEC_LPOPT, { "pdf" } }, 72 | { "Cut", SEC_CONF|SEC_PPD|SEC_LPOPT, {{ 3 }} }, 73 | { "Truncate", SEC_CONF|SEC_PPD|SEC_LPOPT, {{ 64 }} }, 74 | { "DirPrefix", SEC_CONF|SEC_PPD, {{ 0 }} }, 75 | { "Label", SEC_CONF|SEC_PPD|SEC_LPOPT, {{ 0 }} }, 76 | { "LogType", SEC_CONF|SEC_PPD, {{ 3 }} }, 77 | { "LowerCase", SEC_CONF|SEC_PPD, {{ 1 }} }, 78 | { "TitlePref", SEC_CONF|SEC_PPD|SEC_LPOPT, {{ 0 }} }, 79 | { "DecodeHexStrings", SEC_CONF|SEC_PPD, {{ 0 }} }, 80 | { "FixNewlines", SEC_CONF|SEC_PPD, {{ 0 }} }, 81 | { "AllowUnsafeOptions", SEC_CONF|SEC_PPD, {{ 0 }} }, 82 | { "AnonUmask", SEC_CONF|SEC_PPD, {{ 0000 }} }, 83 | { "UserUMask", SEC_CONF|SEC_PPD|SEC_LPOPT, {{ 0077 }} }, 84 | }; 85 | 86 | #define Conf_AnonDirName configData[AnonDirName].value.sval 87 | #define Conf_AnonUser configData[AnonUser].value.sval 88 | #define Conf_GhostScript configData[GhostScript].value.sval 89 | #define Conf_GSCall configData[GSCall].value.sval 90 | #define Conf_Grp configData[Grp].value.sval 91 | #define Conf_GSTmp configData[GSTmp].value.sval 92 | #define Conf_Log configData[Log].value.sval 93 | #define Conf_PDFVer configData[PDFVer].value.sval 94 | #define Conf_PostProcessing configData[PostProcessing].value.sval 95 | #define Conf_Out configData[Out].value.sval 96 | #define Conf_Spool configData[Spool].value.sval 97 | #define Conf_UserPrefix configData[UserPrefix].value.sval 98 | #define Conf_RemovePrefix configData[RemovePrefix].value.sval 99 | #define Conf_OutExtension configData[OutExtension].value.sval 100 | #define Conf_Cut configData[Cut].value.ival 101 | #define Conf_Truncate configData[Truncate].value.ival 102 | #define Conf_DirPrefix configData[DirPrefix].value.ival 103 | #define Conf_Label configData[Label].value.ival 104 | #define Conf_LogType configData[LogType].value.ival 105 | #define Conf_LowerCase configData[LowerCase].value.ival 106 | #define Conf_TitlePref configData[TitlePref].value.ival 107 | #define Conf_DecodeHexStrings configData[DecodeHexStrings].value.ival 108 | #define Conf_FixNewlines configData[FixNewlines].value.ival 109 | #define Conf_AllowUnsafeOptions configData[AllowUnsafeOptions].value.ival 110 | #define Conf_AnonUMask configData[AnonUMask].value.modval 111 | #define Conf_UserUMask configData[UserUMask].value.modval 112 | --------------------------------------------------------------------------------