source: trunk/gui/shared/PrintUtl.VRS@ 6

Last change on this file since 6 was 6, checked in by Alex Taylor, 14 years ago

Initial commit of CUPSWIZ gui

File size: 15.7 KB
Line 
1/*:VRX GetDriverSource
2*/
3/* Figure out where to look for the PrinterPak driver files used as the install
4 * source. Preference is given to the local repository (PDR_DIR); if it's not
5 * there, we look in a couple of other places where it might have ended up.
6 * Note that we don't look for the actual installed driver files under \OS2\DLL;
7 * if the application wants to fall back to those in some way, then it will have
8 * to take care of that logic itself.
9 *
10 * Various global values are assumed to be set already:
11 * - globals.!prdrv: filespec of \OS2\INSTALL\PRDRV.LST
12 * - globals.!repository: value indicated by PM_INSTALL->PDR_DIR in OS2.INI
13 *
14 * Returns the path, or '' if not found. Also, 'pmdx' will be 0-9 if the
15 * driver is in the repository (indicating the repository subdirectory), or
16 * '' if the driver is not in the repository.
17 */
18GetDriverSource: PROCEDURE EXPOSE globals. pmdx
19 ARG driver
20 IF driver == '' THEN RETURN ''
21
22 drv_file = ''
23 IF globals.!repository <> '' THEN DO
24
25 /* See if the driver is defined in the local repository. (This is the
26 * directory where installable printer drivers are kept. OS/2 gets them
27 * from here when you select 'Printer driver included with OS/2'.)
28 */
29 pmdx = GetDriverPMDD( driver, globals.!prdrv )
30 IF pmdx == '' THEN DO
31 /* Hmm, the driver isn't listed in PRDRV.LST. Let's check to see if
32 * it's in the default repository location anyway.
33 */
34 IF WORDPOS( driver, 'ECUPS ECUPS-HP PSPRINT PSPRINT2') > 0 THEN
35 pmdx = '9'
36 ELSE
37 pmdx = '0'
38 drv_file = STREAM( globals.!repository'\PMDD_'pmdx'\'driver'.DRV', 'C', 'QUERY EXISTS')
39 IF drv_file <> '' THEN DO
40 /* We found the driver in the repository, even though it isn't
41 * defined as such. So let's add the proper definition to
42 * PRDRV.LST now.
43 */
44 CALL LINEOUT globals.!prdrv, LEFT( driver'.DRV', 14 ) pmdx ||,
45 ' (added automatically)'
46 CALL LINEOUT globals.!prdrv
47 END
48 ELSE
49 pmdx = ''
50 END
51 ELSE DO
52 /* The driver is listed; now make sure it's actually there.
53 */
54 drv_file = STREAM( globals.!repository'\PMDD_'pmdx'\'driver'.DRV', 'C', 'QUERY EXISTS')
55 END
56 END
57
58 IF drv_file == '' THEN DO
59 /* If the driver really isn't in the repository, there are a couple of
60 * other places that various install utilities might have put it...
61 */
62 PARSE VALUE VRGetIni('PM_INSTALL', driver'_DIR', 'USER') WITH drvr_dir '00'x .
63 IF drvr_dir == '' THEN
64 PARSE VALUE VRGetIni('InstPDR', 'PATH_TO_'driver, 'USER') WITH drvr_dir '00'x .
65 IF drvr_dir <> '' THEN
66 drv_file = drvr_dir'\'driver'.DRV'
67 END
68
69RETURN drv_file
70
71
72/*:VRX GetDriverPMDD
73*/
74/* Check to see which repository directory the specified driver resides in.
75 * Returns the number suffix of the PMDD_* subdirectory name, or '' if either
76 * the driver or the index file could not be located.
77 */
78GetDriverPMDD: PROCEDURE
79 PARSE ARG driver, prdrv_lst
80
81 IF prdrv_lst <> '' THEN DO
82 CALL LINEIN prdrv_lst, 1, 0
83 DO WHILE LINES( prdrv_lst ) > 0
84 PARSE VALUE LINEIN( prdrv_lst ) WITH (driver)'.DRV' pmdx .
85 IF pmdx <> '' THEN LEAVE
86 END
87 CALL STREAM prdrv_lst, 'C', 'CLOSE'
88 END
89 ELSE pmdx = ''
90
91RETURN pmdx
92
93
94/*:VRX VerifyDriverEAs
95*/
96/* Make sure the driver has its extended attributes. If not, look for an
97 * accompanying .EA or .EA_ file, and join it to the driver.
98 */
99VerifyDriverEAs: PROCEDURE EXPOSE globals.
100 PARSE ARG driver
101 eas.0 = 0
102 CALL SysQueryEAList driver, 'eas.'
103 IF eas.0 == 0 THEN DO
104 ea_file = SUBSTR( driver, 1, LASTPOS('.', driver )) || 'EA'
105 IF STREAM( ea_file, 'C', 'QUERY EXISTS') == '' THEN
106 ea_file = ea_file || '_'
107 IF STREAM( ea_file, 'C', 'QUERY EXISTS') == '' THEN
108 RETURN 0
109
110 ADDRESS CMD '@UNLOCK' driver '2>NUL 1>NUL'
111 ADDRESS CMD '@EAUTIL' driver ea_file '/j /p 2>NUL 1>NUL'
112 END
113RETURN 1
114
115
116/*:VRX CopyDriverToSource
117*/
118/* Copy driver files to the source (repository) directory used for installation.
119 */
120CopyDriverToSource: PROCEDURE EXPOSE globals.
121 PARSE ARG driver, newdrvdir
122
123 drv_dir = VRParseFilePath( driver, 'DP')
124 IF drv_dir == '' THEN RETURN 0
125
126 IF VerifyDriverEAs( driver ) == 0 THEN RETURN 0
127
128 CALL LINEOUT globals.!log1, 'Copying driver files from' drv_dir 'to' newdrvdir'...'
129
130 /* Read the list of required driver files from the EAs, and copy them
131 * all to the target directory.
132 */
133 IF SysGetEA( driver, 'REQUIREDDRIVERFILES', 'reqfiles') == 0 THEN DO
134 PARSE VAR reqfiles 5 filelist
135 filelist = TRANSLATE( filelist, ' ', ',')
136 DO i = 1 TO WORDS( filelist )
137 copyfile = drv_dir'\' || WORD( filelist, i )
138 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
139 CALL LINEOUT globals.!log1, ' -' copyfile '(REQUIRED):' ok
140 END
141 DROP copyfile
142 DROP filelist
143 END
144 ELSE RETURN 0
145
146 /* If there are optional files defined as well, try to copy those also.
147 */
148 IF SysGetEA( driver, 'OPTIONALDRIVERFILES', 'reqfiles') == 0 THEN DO
149 PARSE VAR reqfiles 5 filelist
150 filelist = TRANSLATE( filelist, ' ', ',')
151 DO i = 1 TO WORDS( filelist )
152 copyfile = drv_dir'\' || WORD( filelist, i )
153 IF STREAM( copyfile, 'C', 'QUERY EXISTS') == '' THEN ITERATE
154 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
155 CALL LINEOUT globals.!log1, ' -' copyfile '(OPTIONAL):' ok
156 END
157 DROP copyfile
158 DROP filelist
159 END
160
161RETURN 1
162
163
164/*:VRX PrinterExistsInDRV
165*/
166/* Determine if the specified PrinterPak driver already contains support
167 * for the specified printer model.
168 */
169PrinterExistsInDRV: PROCEDURE EXPOSE globals.
170 PARSE UPPER ARG driver_name, printer_name
171 printer_name = TRANSLATE( printer_name, '_', '.')
172
173 printer_drv = globals.!bootdrv'\OS2\DLL\'driver_name'\'driver_name'.DRV'
174 /* ?? TODO: install driver_name if not found (prompt first) ?? */
175
176 IF SysGetEA( printer_drv, '.EXPAND', 'exist_ea') <> 0 THEN RETURN 0
177 PARSE VAR exist_ea 1 _eatype 3 .
178 IF C2X( _eatype ) <> 'FDFF' THEN RETURN 0
179
180 PARSE VAR exist_ea 3 _ealen 5 exist_models
181 total_len = C2D( REVERSE( _ealen ))
182
183 /* The variable exist_models now contains a null-separated list of printer
184 * models supported by the driver (including those from previously-imported
185 * PPD files). Next we check each one against our requested printer name.
186 */
187 start = 1
188 found = 0
189 DO WHILE ( found == 0 ) & ( start < total_len )
190 _strend = POS('0'x, exist_models, start )
191 IF _strend == 0 THEN LEAVE
192 _model = TRANSLATE( SUBSTR( exist_models, start, _strend - start ))
193 IF _model == printer_name THEN
194 found = 1
195 ELSE
196 start = _strend + 1
197 END
198
199RETURN found
200
201
202/*:VRX CreateDriverList
203*/
204/* Generate a driver listfile from the .EXPAND EA
205 */
206CreateDriverList: PROCEDURE EXPOSE globals.
207 ARG driver, listfile
208
209 IF STREAM( listfile, 'C', 'QUERY EXISTS') <> '' THEN
210 CALL SysFileDelete listfile
211
212 drv_name = FILESPEC('NAME', driver )
213 IF SysGetEA( driver, '.EXPAND', 'eaval') == 0 THEN DO
214 PARSE VAR eaval 3 ealen 5 models
215 offs = 1
216 datalen = C2D( REVERSE( ealen ))
217 DO WHILE offs <= datalen
218 start = SUBSTR( models, offs )
219 inc = POS('00'x, start )
220 IF inc > 1 THEN DO
221 current_name = STRIP( SUBSTR( start, 1, inc-1 ))
222 CALL LINEOUT listfile, current_name':' current_name '('drv_name')'
223 END
224 offs = offs + inc
225 END
226 CALL LINEOUT listfile
227 END
228
229RETURN 1
230
231
232/*:VRX AddPort_CUPS
233*/
234/* Adds a new CUPS port. Returns 0 on full success, 1 if the port was created
235 * but could not be configured, and an OS/2 or PM error code otherwise.
236 */
237AddPort_CUPS: PROCEDURE EXPOSE globals.
238 PARSE ARG portname, hostname, queuename
239 ADDRESS CMD '@cupsport' portname hostname queuename '>>' globals.!log2
240 IF rc == 1 THEN DO
241 CALL VRSetIni 'PM_'portname, 'INITIALIZATION', hostname'#'queuename||'00'x, 'SYSTEM', 'NoClose'
242 CALL VRSetIni 'PM_'portname, 'DESCRIPTION', hostname':'queuename||'00'x, 'SYSTEM'
243 END
244RETURN rc
245
246
247/*:VRX DeletePort
248*/
249/* Deletes a printer port (any type).
250 */
251DeletePort: PROCEDURE EXPOSE globals.
252 PARSE ARG portname
253 CALL SysIni 'SYSTEM', 'PM_'portname, 'DELETE:'
254 CALL SysIni 'SYSTEM', 'PM_SPOOLER_PORT', portname, 'DELETE:'
255RETURN 1
256
257
258/*:VRX GetNextPortName
259*/
260/* Get the next unique (non-existing) port name for the specified port driver.
261 */
262GetNextPortName: PROCEDURE
263 ARG portdrv
264
265 maxports = 64 /* should be smarter about this if possible */
266 exists = 1
267 x = 0
268 DO WHILE ( x < maxports ) & ( exists == 1 )
269 x = x + 1
270 portname = portdrv || x
271 nextport = SysIni('SYSTEM', 'PM_SPOOLER_PORT', portname )
272 IF LEFT( nextport, 6 ) == 'ERROR:' THEN exists = 0
273 END
274 IF exists == 1 THEN
275 portname = ''
276
277RETURN portname
278
279
280/*:VRX GetQueueName
281*/
282/* Generate a unique queue name from the specified printer name.
283 */
284GetQueueName: PROCEDURE
285 ARG queuename
286
287 DO UNTIL badchar = 0
288 badchar = VERIFY( queuename, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789 ')
289 IF badchar > 0 THEN
290 queuename = OVERLAY(' ', queuename, badchar, 1 )
291 END
292 queuename = LEFT( SPACE( queuename, 0 ), 8 )
293
294 tail = 0
295 PARSE VALUE VRGetIni('PM_SPOOLER', 'DIR', 'SYSTEM') WITH spldir ';' .
296 DO WHILE VRFileExists( spldir'\'queuename ) == 1
297 tail = tail + 1
298 queuename = STRIP( LEFT( queuename, 8 - LENGTH( tail ))) || tail
299 END
300
301RETURN queuename
302
303
304/*:VRX RSPCreatePort
305*/
306/* Create/update a RINSTPRN response file to create the specified port.
307 */
308RSPCreatePort: PROCEDURE
309 PARSE ARG rsp, portdriver, portname, hostname, printername
310
311 CALL LINEOUT rsp, '* Creates a new printer port.'
312 CALL LINEOUT rsp, '*'
313 CALL LINEOUT rsp, 'ADDPORT'
314 CALL LINEOUT rsp, ' NAME =' portname
315 CALL LINEOUT rsp, ' PORTDRIVER =' portdriver
316 CALL LINEOUT rsp, ' DESCRIPTION =' hostname':'printername
317 CALL LINEOUT rsp, ' INITIALIZATION =' hostname'#'printername
318 CALL LINEOUT rsp, ' TERMINATION = ;'
319 CALL LINEOUT rsp, ' TIMEOUT = 45;'
320 CALL LINEOUT rsp, 'ENDPORT'
321 CALL LINEOUT rsp, ''
322 CALL LINEOUT rsp
323RETURN 1
324
325
326/*:VRX RSPCreatePrinter
327*/
328/* Create a RINSTPRN response file to create the specified printer.
329 */
330RSPCreatePrinter: PROCEDURE
331 PARSE ARG rsp, driver, model, portname, queuename, printername
332
333 IF STREAM( rsp, 'C', 'QUERY EXISTS') <> '' THEN
334 CALL SysFileDelete rsp
335
336/* temporary for testing */
337 PARSE UPPER VALUE VALUE('LANG',,'OS2ENVIRONMENT') WITH 1 . 4 _ctry 6 .
338 IF _ctry == 'CA' | _ctry == 'US' THEN
339 page = 'Letter'
340 ELSE
341 page = 'A4'
342 o9n = 'PORTRAIT'
343/* */
344
345 CALL LINEOUT rsp, '* Installs the' driver 'PrinterPak driver.'
346 CALL LINEOUT rsp, '*'
347 CALL LINEOUT rsp, 'ADDPRINTDRIVER'
348 CALL LINEOUT rsp, ' NAME =' driver
349 CALL LINEOUT rsp, 'ENDPRINTDRIVER'
350 CALL LINEOUT rsp, ''
351 CALL LINEOUT rsp, '* Installs support for the' model 'device.'
352 CALL LINEOUT rsp, '*'
353 CALL LINEOUT rsp, 'ADDPRINTDEVICE'
354 CALL LINEOUT rsp, ' NAME =' model
355 CALL LINEOUT rsp, ' DRIVER =' driver
356 CALL LINEOUT rsp, 'ENDPRINTDEVICE'
357 CALL LINEOUT rsp, ''
358 CALL LINEOUT rsp, '* Creates both a printer queue and a desktop object for this printer.'
359 CALL LINEOUT rsp, '*'
360 CALL LINEOUT rsp, 'ADDQUEUE'
361 CALL LINEOUT rsp, ' NAME =' queuename
362 CALL LINEOUT rsp, ' COMMENT =' printername
363 CALL LINEOUT rsp, ' DRIVERNAME =' driver'.'model
364 CALL LINEOUT rsp, ' PORT =' portname
365 CALL LINEOUT rsp, ' DEFINEQUEUEPROPS'
366 CALL LINEOUT rsp, ' FORMNAME =' page
367 CALL LINEOUT rsp, ' ORIENTATION =' o9n
368 CALL LINEOUT rsp, ' ENDQUEUEPROPS'
369 CALL LINEOUT rsp, 'ENDQUEUE'
370 CALL LINEOUT rsp
371RETURN 1
372
373
374/*:VRX GetNameFromPPD
375*/
376GetNameFromPPD: PROCEDURE
377 ARG ppd_file
378
379 IF STREAM( ppd_file, 'C', 'QUERY EXISTS') == '' THEN RETURN ''
380 nickname = ''
381 IF VRParseFilePath( ppd_file, 'E') == 'GZ' THEN DO
382 nq = RXQUEUE('CREATE')
383 oq = RXQUEUE('SET', nq )
384 ADDRESS CMD '@gzip -c -d' ppd_file '| RXQUEUE' nq
385 DO QUEUED()
386 PARSE PULL line
387 line = STRIP( line )
388 IF LEFT( line, 15 ) == '*ShortNickName:' THEN DO
389 PARSE VAR line . ':' _nick '0D'x .
390 nickname = STRIP( _nick )
391 nickname = STRIP( nickname, 'B', '"')
392 LEAVE
393 END
394 END
395 CALL RXQUEUE 'SET', oq
396 CALL RXQUEUE 'DELETE', nq
397 END
398 ELSE DO
399 CALL LINEIN ppd_file, 1, 0
400 DO WHILE LINES( ppd_file ) <> 0
401 line = STRIP( LINEIN( ppd_file ))
402 IF LEFT( line, 15 ) == '*ShortNickName:' THEN DO
403 PARSE VAR line . ':' _nick '0D'x .
404 nickname = STRIP( _nick )
405 nickname = STRIP( nickname, 'B', '"')
406 LEAVE
407 END
408 END
409 CALL STREAM ppd_file, 'C', 'CLOSE'
410 END
411
412RETURN nickname
413
414/*:VRX CleanPPD
415*/
416/* Clean out lines from Gutenprint and Foomatic PPD files that are known to
417 * cause problems when importing with PIN. (Partially based on work Paul
418 * Smedley and Peter Brown).
419 */
420CleanPPD: PROCEDURE
421 PARSE ARG in_ppd, logfile
422 IF logfile <> '' THEN
423 logfile = STREAM( logfile, 'C', 'QUERY EXISTS')
424
425 out_ppd = VRParseFilePath( in_ppd, 'DPN') || '.TMP'
426 IF STREAM( out_ppd, 'C', 'QUERY EXISTS') \= '' THEN
427 CALL SysFileDelete out_ppd
428
429 IF logfile <> '' THEN
430 CALL CHAROUT logfile, 'Doing cleanup on' in_ppd '...'
431
432 skip_next = 0
433 DO WHILE LINES( in_ppd ) \= 0
434 line = LINEIN( in_ppd )
435 SELECT
436 WHEN skip_next == 1 THEN DO
437 line = STRIP( TRANSLATE( line ))
438 IF line == '*END' THEN skip_next = 0
439 END
440 WHEN LEFT( line, 11 ) == '*StpDefault' THEN NOP
441 WHEN LEFT( line, 7 ) == '*StpStp' THEN NOP
442 WHEN LEFT( line, 18 ) == '*StpResolutionMap:' THEN NOP
443 WHEN LEFT( line, 14 ) == '*OPOptionHints' THEN NOP
444 WHEN LEFT( line, 9 ) == '*Foomatic' THEN DO
445 line = STRIP( line )
446 IF RIGHT( line, 2 ) == '&&' THEN skip_next = 1
447 END
448 OTHERWISE DO
449 CALL LINEOUT out_ppd, line
450 skip_next = 0
451 END
452 END
453 END
454 CALL STREAM in_ppd, 'C', 'CLOSE'
455 CALL STREAM out_ppd, 'C', 'CLOSE'
456
457 ok = VRCopyFile( out_ppd, in_ppd )
458 IF logfile <> '' THEN DO
459 IF ok == 1 THEN
460 CALL LINEOUT logfile, 'OK'
461 ELSE DO
462 CALL LINEOUT logfile, 'Failed!'
463 CALL LINEOUT logfile, ' ->' VRError()
464 END
465 CALL LINEOUT logfile, ''
466 END
467 CALL SysFileDelete out_ppd
468
469RETURN
470
Note: See TracBrowser for help on using the repository browser.