dthelp: compiler warning and coverity warning fixes
[oweals/cde.git] / cde / programs / dthelp / dthelpprint / Initialize.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifdef DOC
24 /*===================================================================
25 $FILEBEG$:   Initialize.c
26 $COMPONENT$: dthelpprint
27 $PROJECT$:   Cde1
28 $SYSTEM$:    HPUX 9.0; AIX 3.2; SunOS 5.3
29 $REVISION$:  $XConsortium: Initialize.c /main/5 1996/10/30 11:35:21 drk $
30 $COPYRIGHT$:
31    (c) Copyright 1993, 1994 Hewlett-Packard Company
32    (c) Copyright 1993, 1994 International Business Machines Corp.
33    (c) Copyright 1993, 1994 Sun Microsystems, Inc.
34    (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
35 ==$END$==============================================================*/
36 #endif /*DOC*/
37  
38 #include <stdio.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <pwd.h>
42 #include <ctype.h>
43 #include <unistd.h>
44 #include <sys/param.h> /* MAXPATHLEN */
45 #include <sys/stat.h>  /* mkdir */
46
47
48 #include <X11/Xlibint.h>  /* _XGetHostname() */
49 #include <X11/Xos.h>     /* FIX: remove? */
50 #include <X11/Intrinsic.h>   /* for Xt macros */
51 /* dont use X11/StringDefs.h because it brings in the _XtStrings global */
52
53 #include "HelpPrintI.h"
54
55 /*#define DEBUG */
56
57 /*=========== file/dir constants ===========*/
58 #define DTAPPDEFAULTS_DIR       CDE_INSTALLATION_TOP "/app-defaults/C/"
59 #define XAPPDEFAULTS_DIR        "/usr/lib/X11/app-defaults/"
60 #define XDEFAULTS_FILE          "/.Xdefaults"
61 #define XDEFAULTS_HOST_FILE     "/.Xdefaults-"
62 #define TMP_DIR_STR             "/.dt/tmp"
63 #define DTHELPPRINTSH_FILE      "/usr/dt/bin/dthelpprint.sh"
64
65 /*=========== helper constants ===========*/
66 #define EOS           '\0'
67 #define DOT_STR       "."
68 #define DIR_SLASH     '/'
69 #define EMPTY_STR     s_EmptyStr
70 #define DIR_SLASH_STR s_DirSlashStr
71
72 #define RSRCSPECLEN   100
73
74 #define INSET    5       /* message catalog set */
75
76 /*=========== helper variables ===========*/
77 static char s_EmptyStr[1] = { EOS };
78 static char s_DirSlashStr[] = "/";
79
80 /*======== helper macro ==========*/
81 #define _STR(s)   #s
82 #define STR(s)    _STR(s)
83
84 /*======== default values ==============*/
85 #define DFLT_DISPLAY            ""
86 #define DFLT_PRINTER            0
87 #define DFLT_COPY_CNT           "1"
88 #define DFLT_OUTPUT_FILE        ""
89 #define DFLT_PAPER_SIZE         RV_letter
90 #define DFLT_RSRCNAME           "dthelpprint"
91 #define DFLT_RSRCCLASS          "Dthelpprint"
92 #define DFLT_HELPTYPE           STR(DtHELP_TYPE_TOPIC)
93 #define DFLT_LOCATIONID         "_hometopic"
94 #define DFLT_ALLTOPICS          0
95 #define DFLT_SUBTOPICS          0
96 #define DFLT_ONETOPIC           0
97 #define DFLT_TOC                0
98 #define DFLT_INDEX              0
99 #define DFLT_FRONTMATTER        0
100 /* The default Header / Footer values are designed for 
101    English labels and a 70 column content. */
102 #define DFLT_TOC_HEADER         "$LMARGIN$VOLUME\n\n"
103 #define DFLT_TOC_FOOTER         "\n$LMARGIN                                                      $SECTNUM\n"
104 #define DFLT_BODY_HEADER        "$LMARGIN$VOLUME$VOLUMEFILL             $PAGENUMFILLPage $PAGENUM\n\n"
105 #define DFLT_BODY_FOOTER        "\n$LMARGIN$TOPIC$TOPICFILL     $SECTNUMFILLSection $SECTNUM\n"
106 #define DFLT_INDEX_HEADER       "$LMARGIN$VOLUME$VOLUMEFILL             $PAGENUMFILLPage $PAGENUM\n\n"
107 #define DFLT_INDEX_FOOTER       "\n$LMARGIN                                                                  $SECTNUM\n"
108 #define DFLT_TOPICTITLE         "Help"
109 #define DFLT_SH_CMD             DTHELPPRINTSH_FILE
110 #define DFLT_ICONV_CMD_AND_ARGS "iconv -f %s -t %s %s > %s"
111 #define DFLT_LP_CMD             0
112 #define DFLT_PR_CMD             "pr"
113 /* pr arg values order:  STRING job title, INT page height, STRING filename */
114 #define DFLT_PR_ARGS            "-h \"%s\" -f -l%d %s"  
115 /* pr offset arg value order:  INT col offset */
116 #define DFLT_PR_OFFSET_ARG      "-o%d"
117 #define DFLT_ECHO_CMD           "echo"
118 /* echo arg values order:  STRING string */
119 #define DFLT_ECHO_ARGS          "\"%s\""
120 #define DFLT_FOLD_CMD           "fold"
121 /* fold arg values order:  INT column width, STRING filename */
122 #define DFLT_FOLD_ARGS          "-w %d %s"
123 #define DFLT_MAN_CMD            "man"
124 /* man arg values order:  STRING man page */
125 #define DFLT_MAN_ARGS           "%s"
126 /* redirect arg value order: STRING filename */
127 #define DFLT_REDIR_CMD_AND_ARGS " > %s"
128 #define DFLT_DEBUG_HELPPRINT    0
129
130 /*======== resource type constants ==============*/
131 /*** N.b.: These are currently not supported. ***/
132 #define XtRBool         "Bool"
133 #define XtRBoolean      "Boolean"
134 #define XtRDimension    "Dimension"
135 #define XtRDisplay      "Display"
136 #define XtRFile         "File"
137 #define XtRFloat        "Float"
138 #define XtRFont         "Font"
139 #define XtRImmediate    "Immediate"
140 #define XtRInt          "Int"
141 #define XtROrientation  "Orientation"
142 #define XtRScreen       "Screen"
143 #define XtRShort        "Short"
144 #define XtRString       "String"
145
146 #if 0
147 /*======== helper structures ==============*/
148 typedef struct _XtResource {
149    String       resource_name;
150    String       resource_class;
151    String       resource_type;
152    Cardinal     resource_size;
153    Cardinal     resource_offset;
154    String       default_type;
155    XtPointer    default_addr;
156 } XtResource, * XtResourceList;
157
158 #endif
159
160 /*======== variables ==============*/
161
162 /* if resource_name or resource_class are NULL, use function arg values */
163 static XtResource s_OptionResources[] = {
164   { RN_display,
165     RC_display,
166     XtRString,
167     sizeof(String),
168     XtOffset (_DtHPrOptionsPtr, display),
169     XtRImmediate,
170     (XtPointer) DFLT_DISPLAY },
171    
172   { RN_printer,
173     RC_printer,
174     XtRString,
175     sizeof(String),
176     XtOffset (_DtHPrOptionsPtr, printer),
177     XtRImmediate,
178     (XtPointer) DFLT_PRINTER },
179    
180   { RN_copies,
181     RC_copies,
182     XtRString,
183     sizeof(String),
184     XtOffset (_DtHPrOptionsPtr, copies),
185     XtRImmediate,
186     (XtPointer) DFLT_COPY_CNT },
187    
188   { RN_outputFile,
189     RC_outputFile,
190     XtRString,
191     sizeof(String),
192     XtOffset (_DtHPrOptionsPtr, outputFile),
193     XtRImmediate,
194     (XtPointer) DFLT_OUTPUT_FILE },
195    
196   { RN_printer "." RN_paperSize,   /* see CalculatePageSize() to grok this */
197     RC_printer "." RC_paperSize,   /* see CalculatePageSize() to grok this */
198     XtRString,
199     sizeof(String),
200     XtOffset (_DtHPrOptionsPtr, paperSize),
201     XtRImmediate,
202     (XtPointer) DFLT_PAPER_SIZE },
203    
204   { RN_rsrcname,
205     RC_rsrcname,
206     XtRString,
207     sizeof(String),
208     XtOffset (_DtHPrOptionsPtr, rsrcname),
209     XtRImmediate,
210     (XtPointer) DFLT_RSRCNAME },
211    
212   { RN_rsrcclass,
213     RC_rsrcclass,
214     XtRString,
215     sizeof(String),
216     XtOffset (_DtHPrOptionsPtr, rsrcclass),
217     XtRImmediate,
218     (XtPointer) DFLT_RSRCCLASS },
219    
220   { RN_helpType,
221     RC_helpType,
222     XtRString,
223     sizeof(String),
224     XtOffset (_DtHPrOptionsPtr, helpType),
225     XtRImmediate,
226     (XtPointer) DFLT_HELPTYPE },
227    
228   { RN_helpVolume,
229     RC_helpVolume,
230     XtRString,
231     sizeof(String),
232     XtOffset (_DtHPrOptionsPtr, helpVolume),
233     XtRImmediate,
234     (XtPointer) 0 },
235    
236   { RN_locationId,
237     RC_locationId,
238     XtRString,
239     sizeof(String),
240     XtOffset (_DtHPrOptionsPtr, locationId),
241     XtRImmediate,
242     (XtPointer) DFLT_LOCATIONID },
243    
244   { RN_allTopics,
245     RC_allTopics,
246     XtRString,
247     sizeof(String),
248     XtOffset (_DtHPrOptionsPtr, allTopics),
249     XtRImmediate,
250     (XtPointer) DFLT_ALLTOPICS },
251    
252   { RN_subTopics,
253     RC_subTopics,
254     XtRString,
255     sizeof(String),
256     XtOffset (_DtHPrOptionsPtr, subTopics),
257     XtRImmediate,
258     (XtPointer) DFLT_SUBTOPICS },
259    
260   /* recurse shadows subTopics for legacy reasons.  
261      recurse was the VUE 3.0 helpprint option for subTopics */
262   { RN_recurse,
263     RC_recurse,
264     XtRString,
265     sizeof(String),
266     XtOffset (_DtHPrOptionsPtr, subTopics),
267     XtRImmediate,
268     (XtPointer) DFLT_SUBTOPICS },
269    
270   { RN_oneTopic,
271     RC_oneTopic,
272     XtRString,
273     sizeof(String),
274     XtOffset (_DtHPrOptionsPtr, oneTopic),
275     XtRImmediate,
276     (XtPointer) DFLT_ONETOPIC },
277    
278   { RN_toc,
279     RC_toc,
280     XtRString,
281     sizeof(String),
282     XtOffset (_DtHPrOptionsPtr, toc),
283     XtRImmediate,
284     (XtPointer) DFLT_TOC },
285    
286   { RN_index,
287     RC_index,
288     XtRString,
289     sizeof(String),
290     XtOffset (_DtHPrOptionsPtr, index),
291     XtRImmediate,
292     (XtPointer) DFLT_INDEX },
293    
294   { RN_frontMatter,
295     RC_frontMatter,
296     XtRString,
297     sizeof(String),
298     XtOffset (_DtHPrOptionsPtr, frontMatter),
299     XtRImmediate,
300     (XtPointer) DFLT_FRONTMATTER },
301    
302   { RN_evenTocFooter,
303     RC_evenTocFooter,
304     XtRString,
305     sizeof(String),
306     XtOffset (_DtHPrOptionsPtr, tocHF.evenFooter),
307     XtRImmediate,
308     (XtPointer) DFLT_TOC_FOOTER },
309    
310   { RN_oddTocFooter,
311     RC_oddTocFooter,
312     XtRString,
313     sizeof(String),
314     XtOffset (_DtHPrOptionsPtr, tocHF.oddFooter),
315     XtRImmediate,
316     (XtPointer) DFLT_TOC_FOOTER },
317    
318   { RN_evenTocHeader,
319     RC_evenTocHeader,
320     XtRString,
321     sizeof(String),
322     XtOffset (_DtHPrOptionsPtr, tocHF.evenHeader),
323     XtRImmediate,
324     (XtPointer) DFLT_TOC_HEADER },
325    
326   { RN_oddTocHeader,
327     RC_oddTocHeader,
328     XtRString,
329     sizeof(String),
330     XtOffset (_DtHPrOptionsPtr, tocHF.oddHeader),
331     XtRImmediate,
332     (XtPointer) DFLT_TOC_HEADER },
333    
334   { RN_evenBodyFooter,
335     RC_evenBodyFooter,
336     XtRString,
337     sizeof(String),
338     XtOffset (_DtHPrOptionsPtr, bodyHF.evenFooter),
339     XtRImmediate,
340     (XtPointer) DFLT_BODY_FOOTER },
341    
342   { RN_oddBodyFooter,
343     RC_oddBodyFooter,
344     XtRString,
345     sizeof(String),
346     XtOffset (_DtHPrOptionsPtr, bodyHF.oddFooter),
347     XtRImmediate,
348     (XtPointer) DFLT_BODY_FOOTER },
349    
350   { RN_evenBodyHeader,
351     RC_evenBodyHeader,
352     XtRString,
353     sizeof(String),
354     XtOffset (_DtHPrOptionsPtr, bodyHF.evenHeader),
355     XtRImmediate,
356     (XtPointer) DFLT_BODY_HEADER },
357    
358   { RN_oddBodyHeader,
359     RC_oddBodyHeader,
360     XtRString,
361     sizeof(String),
362     XtOffset (_DtHPrOptionsPtr, bodyHF.oddHeader),
363     XtRImmediate,
364     (XtPointer) DFLT_BODY_HEADER },
365    
366   { RN_evenIndexFooter,
367     RC_evenIndexFooter,
368     XtRString,
369     sizeof(String),
370     XtOffset (_DtHPrOptionsPtr, indexHF.evenFooter),
371     XtRImmediate,
372     (XtPointer) DFLT_INDEX_FOOTER },
373    
374   { RN_oddIndexFooter,
375     RC_oddIndexFooter,
376     XtRString,
377     sizeof(String),
378     XtOffset (_DtHPrOptionsPtr, indexHF.oddFooter),
379     XtRImmediate,
380     (XtPointer) DFLT_INDEX_FOOTER },
381    
382   { RN_evenIndexHeader,
383     RC_evenIndexHeader,
384     XtRString,
385     sizeof(String),
386     XtOffset (_DtHPrOptionsPtr, indexHF.evenHeader),
387     XtRImmediate,
388     (XtPointer) DFLT_INDEX_HEADER },
389    
390   { RN_oddIndexHeader,
391     RC_oddIndexHeader,
392     XtRString,
393     sizeof(String),
394     XtOffset (_DtHPrOptionsPtr, indexHF.oddHeader),
395     XtRImmediate,
396     (XtPointer) DFLT_INDEX_HEADER },
397    
398   { RN_manPage,
399     RC_manPage,
400     XtRString,
401     sizeof(String),
402     XtOffset (_DtHPrOptionsPtr, manPage),
403     XtRImmediate,
404     (XtPointer) 0 },
405    
406   { RN_stringData,
407     RC_stringData,
408     XtRString,
409     sizeof(String),
410     XtOffset (_DtHPrOptionsPtr, stringData),
411     XtRImmediate,
412     (XtPointer) 0 },
413    
414   { RN_helpFile,
415     RC_helpFile,
416     XtRString,
417     sizeof(String),
418     XtOffset (_DtHPrOptionsPtr, helpFile),
419     XtRImmediate,
420     (XtPointer) 0 },
421    
422   { RN_topicTitle,
423     RC_topicTitle,
424     XtRString,
425     sizeof(String),
426     XtOffset (_DtHPrOptionsPtr, topicTitle),
427     XtRImmediate,
428     (XtPointer) DFLT_TOPICTITLE },
429
430   { RN_echoCommand,
431     RC_echoCommand,
432     XtRString,
433     sizeof(String),
434     XtOffset (_DtHPrOptionsPtr, echoCommand),
435     XtRImmediate,
436     (XtPointer) DFLT_ECHO_CMD },
437    
438   { RN_echoArgs,
439     RC_echoArgs,
440     XtRString,
441     sizeof(String),
442     XtOffset (_DtHPrOptionsPtr, echoArgs),
443     XtRImmediate,
444     (XtPointer) DFLT_ECHO_ARGS },
445    
446   { RN_foldCommand,
447     RC_foldCommand,
448     XtRString,
449     sizeof(String),
450     XtOffset (_DtHPrOptionsPtr, foldCommand),
451     XtRImmediate,
452     (XtPointer) DFLT_FOLD_CMD },
453    
454   { RN_foldArgs,
455     RC_foldArgs,
456     XtRString,
457     sizeof(String),
458     XtOffset (_DtHPrOptionsPtr, foldArgs),
459     XtRImmediate,
460     (XtPointer) DFLT_FOLD_ARGS },
461    
462   { RN_prCommand,
463     RC_prCommand,
464     XtRString,
465     sizeof(String),
466     XtOffset (_DtHPrOptionsPtr, prCommand),
467     XtRImmediate,
468     (XtPointer) DFLT_PR_CMD },
469    
470   { RN_prArgs,
471     RC_prArgs,
472     XtRString,
473     sizeof(String),
474     XtOffset (_DtHPrOptionsPtr, prArgs),
475     XtRImmediate,
476     (XtPointer) DFLT_PR_ARGS },
477    
478   { RN_prOffsetArg,
479     RC_prOffsetArg,
480     XtRString,
481     sizeof(String),
482     XtOffset (_DtHPrOptionsPtr, prOffsetArg),
483     XtRImmediate,
484     (XtPointer) DFLT_PR_OFFSET_ARG },
485    
486   { RN_manCommand,
487     RC_manCommand,
488     XtRString,
489     sizeof(String),
490     XtOffset (_DtHPrOptionsPtr, manCommand),
491     XtRImmediate,
492     (XtPointer) DFLT_MAN_CMD },
493    
494   { RN_manArgs,
495     RC_manArgs,
496     XtRString,
497     sizeof(String),
498     XtOffset (_DtHPrOptionsPtr, manArgs),
499     XtRImmediate,
500     (XtPointer) DFLT_MAN_ARGS },
501    
502   { RN_redirectCmdAndArgs,
503     RC_redirectCmdAndArgs,
504     XtRString,
505     sizeof(String),
506     XtOffset (_DtHPrOptionsPtr, redirectCmdAndArgs),
507     XtRImmediate,
508     (XtPointer) DFLT_REDIR_CMD_AND_ARGS },
509    
510   { RN_lpCommand,
511     RC_lpCommand,
512     XtRString,
513     sizeof(String),
514     XtOffset (_DtHPrOptionsPtr, lpCommand),
515     XtRImmediate,
516     (XtPointer) DFLT_LP_CMD },
517    
518   { RN_shCommand,
519     RC_shCommand,
520     XtRString,
521     sizeof(String),
522     XtOffset (_DtHPrOptionsPtr, shCommand),
523     XtRImmediate,
524     (XtPointer) DFLT_SH_CMD },
525    
526   { RN_iconvCmdAndArgs,
527     RC_iconvCmdAndArgs,
528     XtRString,
529     sizeof(String),
530     XtOffset (_DtHPrOptionsPtr, iconvCmdAndArgs),
531     XtRImmediate,
532     (XtPointer) DFLT_ICONV_CMD_AND_ARGS },
533    
534   { RN_debugHelpPrint,
535     RC_debugHelpPrint,
536     XtRString,
537     sizeof(String),
538     XtOffset (_DtHPrOptionsPtr, debugHelpPrint),
539     XtRImmediate,
540     (XtPointer) DFLT_DEBUG_HELPPRINT },
541    
542 #if 0   /* Because we aren't using Xt and only emulating it,
543            we can't handle data type other than String.  These
544            are all Integer values, so I process them by hand
545            below in CalculatePageSize(). */
546   { RN_colsWidth,
547     RC_colsWidth,
548     XtRString,
549     sizeof(String),
550     XtOffset (_DtHPrOptionsPtr, colsWidth),
551     XtRImmediate,
552     (XtPointer) 0 },
553    
554   { RN_rowsHeight,
555     RC_rowsHeight,
556     XtRString,
557     sizeof(String),
558     XtOffset (_DtHPrOptionsPtr, rowsHeight),
559     XtRImmediate,
560     (XtPointer) 0 },
561    
562   { RN_colsLeftMargin,
563     RC_colsLeftMargin,
564     XtRString,
565     sizeof(String),
566     XtOffset (_DtHPrOptionsPtr, colsLeftMargin),
567     XtRImmediate,
568     (XtPointer) 0 },
569    
570   { RN_colsRightMargin,
571     RC_colsRightMargin,
572     XtRString,
573     sizeof(String),
574     XtOffset (_DtHPrOptionsPtr, colsRightMargin),
575     XtRImmediate,
576     (XtPointer) 0 },
577    
578   { RN_rowsTopMargin,
579     RC_rowsTopMargin,
580     XtRString,
581     sizeof(String),
582     XtOffset (_DtHPrOptionsPtr, rowsTopMargin),
583     XtRImmediate,
584     (XtPointer) 0 },
585    
586   { RN_rowsBottomMargin,
587     RC_rowsBottomMargin,
588     XtRString,
589     sizeof(String),
590     XtOffset (_DtHPrOptionsPtr, rowsBottomMargin),
591     XtRImmediate,
592     (XtPointer) 0 },
593 #endif
594    
595 }; /* resources */
596
597
598
599 \f
600 #if DOC
601 ===================================================================
602 $PFUNBEG$:  GetHomeDir()
603 $1LINER$:   Gets home directory of user owning current app
604 $DESCRIPT$:
605 Gets the home directory by 
606    1. using the HOME environment variable
607 or 2. using the USER env variable and the 
608       directory in the password file for that user
609 or 3. using getuid() and the 
610       directory in the password file for that user
611
612 The home directory is stored in the string that is passed
613 in.  No overflow checking is possible, so the string should
614 be MAXPATHLEN bytes long.
615 $RETURNS$:
616 Returns the 'dest' pointer
617 $ARGS$:
618 dest: pointer to string to hold home directory
619 ========================================================$SKIP$=====*/
620 #endif /*DOC*/
621
622 static char *GetHomeDir (
623         char *dest)
624 {       /*$CODE$*/
625         uid_t uid;
626         extern char *getenv();
627         extern uid_t getuid();
628         extern struct passwd *getpwuid(), *getpwnam();
629         struct passwd *pw;
630         register char *ptr;
631
632         if((ptr = getenv("HOME")) != NULL) 
633         {
634                 (void) strcpy(dest, ptr);
635         } 
636         else 
637         {
638                 if((ptr = getenv("USER")) != NULL) 
639                 {
640                         pw = getpwnam(ptr);
641                 } 
642                 else 
643                 {
644                         uid = getuid();
645                         pw = getpwuid(uid);
646                 }
647                 if (pw) (void) strcpy(dest, pw->pw_dir);
648                 else    *dest = '\0';
649         }
650         return dest;
651 }   /*$END$*/
652
653
654
655
656 \f
657 #if DOC
658 ===================================================================
659 $PFUNBEG$:  Usage()
660 $1LINER$:  Prints usage message and returns
661 $DESCRIPT$:
662 This routine prints a generic help message
663 $RETURNS$:
664 $ARGS$:
665 ========================================================$SKIP$=====*/
666 #endif /*DOC*/
667
668 static
669 void Usage(void)
670 {       /*$CODE$*/
671    static char * usage[] = 
672    {
673       "dthelpprint - Print program for Help\n\n",
674       "Usage: dthelpprint [options]\n",
675       "Options controlling how to print:\n",
676       "\t" AN_printer " printername  printer to use\n",
677       "\t" AN_copies " number        number of copies to print\n",
678       "\t" AN_outputFile " filename  write output to this file\n",
679       "\t" AN_paperSize " size       format content to this paper size\n",
680       "\t\tsize = {" RV_letter "|" RV_legal "|\n" ,
681       "\t\t        " RV_executive "|" RV_a4 "|" RV_b5 "}\n",
682       "\t" AN_display " displayname  display from which to get resources\n",
683       "\t" AN_rsrcname " name            program name used when getting resources\n",
684       "\t" AN_rsrcclass " name           class name used when getting resources\n",
685       "\t" AN_xrm " resourcestring   additional resources\n",
686       "Options controlling what to print:\n",
687       "\t" AN_helpType " type        type of Help data\n",
688       "\t\ttype = 0 (help volume), 1 (string), 2 (man page), 3 (help file)\n",
689       "\t" AN_helpVolume " volume    full path of help volume file\n",
690       "\t" AN_locationId " location  name of Help topic in the volume\n",
691       "\t" AN_allTopics "            print all topics, toc, & index in the help volume\n",
692       "\t" AN_subTopics "            print topic locationId and all subtopics\n",
693       "\t" AN_oneTopic "             print topic locationId\n",
694       "\t" AN_toc "                  print help volume table of contents\n",
695       "\t" AN_index "                print help volume index\n",
696       "\t" AN_frontMatter "          print help volume front matter\n",
697       "\t" AN_manPage " manpagename  name of man page\n",
698       "\t" AN_stringData " string    Help text to print\n",
699       "\t" AN_helpFile " filename    file containing Help text\n",
700       "\t" AN_topicTitle " title     title string for Help text\n",
701       NULL
702    };
703     int i;
704     for (i=0; usage[i]; i++)
705        printf("%s", _DTGETMESSAGE(INSET,i,usage[i]));
706 }       /*$END$*/
707
708 \f
709 #if DOC
710 ===================================================================
711 $PFUNBEG$:  CalculatePageSize()
712 $1LINER$:  calculates the page size based on resource values
713 $DESCRIPT$:
714 Reads the resources from the database and calculates
715 the page dimensions and stores them in the resources structure.
716 $RETURNS$:
717 $ARGS$:
718 ========================================================$SKIP$=====*/
719 #endif /*DOC*/
720
721 static
722 void CalculatePageSize(
723    XrmDatabase     appDB,
724    _DtHPrOptions * options,
725    char *          appname,
726    char *          appclass)
727 {       /*$CODE$*/
728
729    struct unprintableMargins
730    {
731       int leftUnprintableMargin;
732       int rightUnprintableMargin;
733       int topUnprintableMargin;
734       int bottomUnprintableMargin;
735    };
736
737    static struct unprintableMargins blankMargins = { 6,   2,   2,   1 };
738
739 #define LETTER          0
740 #define LEGAL           1
741 #define EXECUTIVE       2
742 #define A4              3
743 #define B5              4
744 #define MAXVALIDSIZE    4
745
746    /* page size info */
747    struct page 
748    {
749       int width;
750       int height;
751       int leftMargin;
752       int rightMargin;
753       int topMargin;
754       int bottomMargin;
755    };
756
757    static struct page  pagesize[] = 
758    {  /* sizes are in characters of standard HPLJIII courier */
759       /* Note that the text margin counts do *NOT* take into account the 
760          printless margins, which are the margins on which the printer 
761          is unable to print. */
762       /* WI: paper size width; HI: paper size height;
763          LM: desired text left margin; RM: desired text right margin
764          TM: desired text top margin; BM: desired text bottom margin
765       */
766       /*WI, HI, LM, RM, TM, BM */
767       { 91, 69, 10, 10, 6,  6 }, /* letter */
768       { 91, 88, 10, 10, 6,  6 }, /* legal */
769       { 77, 66, 10, 10, 6,  6 }, /* executive */
770       { 88, 73, 10, 10, 6,  6 }, /* A4 */
771       { 76, 63, 10, 10, 6,  6 }  /* B5 */
772    };
773    
774 #if 0   /* save these dimensions here */
775       /* Known Dimensions for standard HPLJIII courier: 
776             char size: 2.37 mm width x 4.04 mm height
777       US-letter:  8.5x11 in       : 91 col x 69 rows
778       US-legal:   8.5x14 in       : 91 col x 88 rows
779       executive:  7.25x10.5 in    : 77 col x 66 rows
780       A4:         210x297 mm      : 88 col x 73 rows
781       B5:         182x257 mm      : 76 col x 63 rows
782       */
783
784       /* Known Dimensions in 100ths of a mm */
785       { 21590, 27940, 2540, 2540, 2540, 2540 },  /* letter */
786       { 21590, 35560, 2540, 2540, 2540, 2540 },  /* legal */
787       { 18415, 26670, 2540, 2540, 2540, 2540 },  /* exec */
788       { 21000, 29700, 2540, 2540, 2540, 2540 },  /* a4 */
789       { 18200, 25700, 2540, 2540, 2540, 2540 }   /* b5 */
790 static float dphm = 300.*2540.;
791 #endif
792
793    int  (*stricmp)(const char *,const char *);
794    char *name;
795    char name_prefix[RSRCSPECLEN];
796    char class_prefix[RSRCSPECLEN];
797    char resource_name[RSRCSPECLEN];
798    char resource_class[RSRCSPECLEN];
799    char *str_type[20];
800    XrmValue value;
801    int papersize = -1;
802    char buf[20];
803    int width,height;
804    int lmargin,rmargin,tmargin,bmargin;
805    int adjLmargin,adjRmargin,adjTmargin,adjBmargin;
806    int textWidth, textHeight;
807    int i;
808    
809    /* build printer resource name and class */
810    strcpy(name_prefix, appname);            /* e.g. dthelpprint */
811    strcat(name_prefix, RN_printer);         /* e.g. dthelpprint.printer */
812    
813    strcpy(class_prefix, appclass);          /* e.g. Dthelpprint */
814    strcat(class_prefix, RC_printer);        /* e.g. Dthelpprint.Printer */
815    
816    /********************/
817    /* Get printer name */
818    /********************/
819    
820    strcpy(resource_name, name_prefix);   /* e.g. dthelpprint.printer */
821    strcat(resource_name, RN_rsrcname);   /* e.g. dthelpprint.printer.name */
822    strcpy(resource_class, class_prefix); /* e.g. Dthelpprint.Printer */
823    strcat(resource_class, RC_rsrcname);  /* e.g. Dthelpprint.Printer.Name */
824    if (XrmGetResource(appDB, resource_name, resource_class,
825                       str_type, &value) == True)
826       name = value.addr;
827    else name = EMPTY_STR;
828    if (name[0] != EOS)
829    {
830       strcat(name_prefix, DOT_STR);
831       strcat(name_prefix, name);         /* e.g. dthelpprint.printer.<name> */
832       strcat(class_prefix, DOT_STR);
833       strcat(class_prefix, name);        /* e.g. Dthelpprint.Printer.<name> */
834    }
835    
836    /**************************/
837    /*   Get explicit width   */
838    /**************************/
839    strcpy(resource_name, name_prefix);
840    strcat(resource_name, RN_colsWidth); 
841                         /* e.g. dthelpprint.printer{.<name>}.colsWidth */
842    strcpy(resource_class, class_prefix);
843    strcat(resource_class, RC_colsWidth);
844                         /* e.g. Dthelpprint.Printer{.<name>}.ColsWidth */
845    
846    if (XrmGetResource(appDB, resource_name, resource_class,
847                       str_type, &value) == True)
848    {
849       width = atoi (value.addr);
850       if (width < 0) width = 0;
851    }
852    else width = 0;
853    
854    /**************************/
855    /*   Get explicit height  */
856    /**************************/
857    strcpy(resource_name, name_prefix);
858    strcat(resource_name, RN_rowsHeight); 
859                          /* e.g. dthelpprint.printer{.<name>}.rowsHeight */
860    strcpy(resource_class, class_prefix);
861    strcat(resource_class, RC_rowsHeight);
862                          /* e.g. Dthelpprint.Printer{.<name>}.RowsHeight */
863    
864    if (XrmGetResource(appDB, resource_name, resource_class, 
865                       str_type, &value) == True)
866    {
867       height = atoi (value.addr);
868       if (height < 0) height = 0;
869    }
870    else height = 0;
871    
872    /**********************************************************/
873    /* get the paper size (will provide default height/width) */
874    /**********************************************************/
875    strcpy(resource_name, name_prefix);
876    strcat(resource_name, RN_paperSize);  
877                          /* e.g. dthelpprint.printer{.<name>}.paperSize */
878    strcpy(resource_class, class_prefix);
879    strcat(resource_class, RC_paperSize); 
880                          /* e.g. Dthelpprint.Printer{.<name>}.PaperSize */
881    
882 #if defined(_AIX) || defined (USL) || defined(__uxp__)
883    stricmp = strcmp;    /* AIX and USL dont have strcasecmp */
884 #else
885    stricmp = strcasecmp;
886 #endif
887    if (XrmGetResource(appDB, resource_name, resource_class, 
888                       str_type, &value) == True)
889    {
890       if ((*stricmp)(value.addr, RV_letter) == 0) papersize = LETTER;
891       else if ((*stricmp)(value.addr, RV_b5) == 0) papersize = B5;
892       else if ((*stricmp)(value.addr, RV_a4) == 0) papersize = A4;
893       else if ((*stricmp)(value.addr, RV_legal) == 0) papersize = LEGAL;
894       else if ((*stricmp)(value.addr, RV_executive) == 0) papersize = EXECUTIVE;
895       else 
896       {
897          fprintf(stderr, _DTGETMESSAGE(INSET,40,
898                            "%s Warning: Illegal paper size '%s'.  " 
899                             RV_letter " used.\n"),
900                        options->programName, value.addr);
901          papersize = LETTER;
902       }
903    }  /* if the paper size resource is defined */
904
905    /* if specified only a width or height, but not both */
906    if ( papersize < 0 && (width == 0 || height == 0) )
907    {
908       fprintf(stderr, _DTGETMESSAGE(INSET,41,
909                     "%s Warning: Missing paper size, height, or width value.  "
910                      RV_letter " used.\n"), 
911                     options->programName);
912       papersize = LETTER;
913    }
914
915    /* if an invaild papersize, dflt to letter */
916    if ( papersize < 0 || papersize > MAXVALIDSIZE ) papersize = LETTER;
917    
918    /* use page size width and height if not specified */
919    if (width == 0) width = pagesize[papersize].width;
920    if (height == 0) height = pagesize[papersize].height;
921    
922    /* Adjust margins */
923    
924    /****************/
925    /* Left margins */
926    /****************/
927    strcpy(resource_name, name_prefix);
928    strcat(resource_name, RN_colsLeftMargin);     
929                          /* e.g. dthelpprint.printer{.<name>}.colsLeftMargin */
930    strcpy(resource_class, class_prefix);
931    strcat(resource_class, RC_colsLeftMargin);    
932                          /* e.g. Dthelpprint.Printer{.<name>}.ColsLeftMargin */
933    
934    /* get the value */
935    if (XrmGetResource(appDB, resource_name, resource_class, 
936                       str_type, &value) == True)
937       i = atoi (value.addr); /* custom margin */
938    else
939       i = pagesize[papersize].leftMargin; /* papersize margin */
940    lmargin = 0;
941    if (i < width) lmargin = i;
942
943    /* available text width, part 1 */
944    textWidth = width - lmargin;
945
946    /* all printed text subject to this offset */
947    adjLmargin = lmargin - blankMargins.leftUnprintableMargin;
948    if (adjLmargin < 0) adjLmargin = 0;
949    
950    /*****************/
951    /* Right margins */
952    /*****************/
953    strcpy(resource_name, name_prefix);
954    strcat(resource_name, RN_colsRightMargin);     
955                          /* e.g. dthelpprint.printer{.<name>}.colsRightMargin */
956    strcpy(resource_class, class_prefix);
957    strcat(resource_class, RC_colsRightMargin);    
958                          /* e.g. Dthelpprint.Printer{.<name>}.ColsRightMargin */
959    
960    /* get the value */
961    if (XrmGetResource(appDB, resource_name, resource_class, 
962                       str_type, &value) == True)
963       i = atoi (value.addr); /* custom margin */
964    else
965       i = pagesize[papersize].rightMargin; /* size margin */
966    rmargin = 0;
967    if (i < textWidth) rmargin = i;
968
969    /* available text width, part 2 */
970    textWidth -= rmargin;
971
972    /* all printed text subject to this offset */
973    adjRmargin = rmargin - blankMargins.rightUnprintableMargin;
974    if (adjRmargin < 0) adjRmargin = 0;
975    
976    /***************/
977    /* Top Margin */
978    /*****************/
979    strcpy(resource_name, name_prefix);
980    strcat(resource_name, RN_rowsTopMargin);     
981                          /* e.g. dthelpprint.printer{.<name>}.rowsTopMargin */
982    strcpy(resource_class, class_prefix);
983    strcat(resource_class, RC_rowsTopMargin);    
984                          /* e.g. Dthelpprint.Printer{.<name>}.RowsTopMargin */
985    
986    /* get the value */
987    if (XrmGetResource(appDB, resource_name, resource_class, 
988                       str_type, &value) == True)
989       i = atoi (value.addr); /* custom margin */
990    else
991       i = pagesize[papersize].topMargin; /* papersize margin */
992    tmargin = 0;
993    if (i < height) tmargin = i;
994
995    /* available text height, part 1 */
996    textHeight = height - tmargin;
997    
998    /* all printed text subject to this offset */
999    adjTmargin = tmargin - blankMargins.topUnprintableMargin;
1000    if (adjTmargin < 0) adjTmargin = 0;
1001    
1002    /*****************/
1003    /* Bottom Margin */
1004    /*****************/
1005    strcpy(resource_name, name_prefix);
1006    strcat(resource_name, RN_rowsBottomMargin);     
1007                        /* e.g. dthelpprint.printer{.<name>}.rowsBottommargin */
1008    strcpy(resource_class, class_prefix);
1009    strcat(resource_class, RC_rowsBottomMargin);    
1010                        /* e.g. Dthelpprint.Printer{.<name>}.RowsBottommargin */
1011    
1012    /* get the value */
1013    if (XrmGetResource(appDB, resource_name, resource_class,
1014                       str_type, &value) == True)
1015       i = atoi (value.addr); /* custom margin */
1016    else
1017       i = pagesize[papersize].bottomMargin;     /* size margin */
1018    bmargin = 0;
1019    if ( i < textHeight ) bmargin = i;
1020
1021    /* available text height, part 2 */
1022    textHeight -= bmargin;
1023    
1024    /* all printed text subject to this offset */
1025    adjBmargin = tmargin - blankMargins.bottomUnprintableMargin;
1026    if (adjBmargin < 0) adjBmargin = 0;
1027    
1028    /*** set the values ***/
1029    options->rowsHeight = height;
1030    options->colsWidth = width;
1031    options->colsLeftMargin = lmargin;
1032    options->colsRightMargin = rmargin;
1033    options->rowsTopMargin = tmargin;
1034    options->rowsBottomMargin = bmargin;
1035    options->rowsTextHeight = textHeight;
1036    options->colsTextWidth = textWidth;
1037    options->colsAdjLeftMargin = adjLmargin;
1038    options->colsAdjRightMargin = adjRmargin;
1039    options->rowsAdjTopMargin = adjTmargin;
1040    options->rowsAdjBottomMargin = adjBmargin;
1041
1042    if (options->debugHelpPrint)
1043    {
1044       printf("options.%s: %d\n","rowsHeight",options->rowsHeight);
1045       printf("options.%s: %d\n","colsWidth",options->colsWidth);
1046       printf("options.%s: %d\n","colsLeftMargin",options->colsLeftMargin);
1047       printf("options.%s: %d\n","colsRightMargin",options->colsRightMargin);
1048       printf("options.%s: %d\n","rowsTopMargin",options->rowsTopMargin);
1049       printf("options.%s: %d\n","rowsBottomMargin",options->rowsBottomMargin);
1050       printf("options.%s: %d\n","rowsTextHeight",options->rowsTextHeight);
1051       printf("options.%s: %d\n","colsTextWidth",options->colsTextWidth);
1052       printf("options.%s: %d\n","colsAdjLeftMargin",options->colsAdjLeftMargin);
1053       printf("options.%s: %d\n","colsAdjRightMargin",options->colsAdjRightMargin);
1054       printf("options.%s: %d\n","rowsAdjTopMargin",options->rowsAdjTopMargin);
1055       printf("options.%s: %d\n","rowsAdjBottomMargin",options->rowsAdjBottomMargin);
1056    }
1057 }       /*$END$*/
1058         
1059 \f
1060 #if DOC
1061 ===================================================================
1062 $FUNBEG$:  _DtHPrBuildResourceDb()
1063 $1LINER$:  Parses command line and constructs a single db of resources
1064 $DESCRIPT$:
1065 This routine parses the command line and reads various data bases
1066 to create a single data base that copntains all resources associated
1067 with this application.
1068
1069 It generates the resulting resource database by merging the
1070 following databases:
1071       help-print specific cmdline & environment var->resources database
1072           $PRINTER -> RN_printer, RC_printer
1073           $DISPLAY -> RN_display, RC_display
1074           AN_rsrcname -> RN_appname
1075           AC_rsrcname -> RC_appname
1076           AN_rsrcclass -> RN_appclass
1077           AC_rsrcclass -> RC_appclass
1078       app-specific class resource file on local host
1079           /usr/lib/X11/app-defaults/<appclass>
1080       app-specific user resource file on local host
1081           $HOME/<appclass>
1082       display server resources or user preferences file on local host
1083           XResourceManagerString() or $HOME/.Xdefaults
1084       screen resources from display server
1085           XScreenResourcesString()
1086       user environment resource file on local host
1087           $XENVIRONMENT or $HOME/.Xdefaults-<host>
1088       application command line
1089
1090 This function is a replacement for XtAppInitialize/XtInitialize()
1091 and XtDisplayInitialize() to remove dependency on Xt.
1092 $RETURNS$:
1093 argc is modified to be the number of remaining args
1094 argv is modified to point to the remaining args
1095 appDB is filled with the option settings used by the rest of the program
1096 $ARGS$:
1097 ========================================================$SKIP$=====*/
1098 #endif /*DOC*/
1099
1100 void _DtHPrBuildResourceDb(
1101    int *         argc,
1102    char * *      argv,
1103    XrmDatabase * appDB,
1104    Display * *   pDpy)
1105 {       /*$CODE$*/
1106    static XrmOptionDescRec optionsTable[] = {
1107 /* how to print */
1108       {AN_display,      RN_display,     XrmoptionSepArg, (caddr_t) NULL},
1109       {AN_printer,      RN_printer,     XrmoptionSepArg, (caddr_t) NULL},
1110       {AN_copies,       RN_copies,      XrmoptionSepArg, (caddr_t) NULL},
1111       {AN_outputFile,   RN_outputFile,  XrmoptionSepArg, (caddr_t) NULL},
1112       {AN_paperSize,    RN_printer "." RN_paperSize,
1113                                         XrmoptionSepArg, (caddr_t) NULL},
1114       {AN_xrm,          NULL,           XrmoptionResArg, (caddr_t) NULL},
1115       {AN_rsrcname,     RN_rsrcname,    XrmoptionSepArg, (caddr_t) NULL},
1116       {AN_rsrcclass,    RN_rsrcclass,   XrmoptionSepArg, (caddr_t) NULL},
1117       {AN_evenTocFooter,  RN_evenTocFooter,     XrmoptionSepArg, (caddr_t) NULL},
1118       {AN_oddTocFooter,   RN_oddTocFooter,      XrmoptionSepArg, (caddr_t) NULL},
1119       {AN_evenTocHeader,  RN_evenTocHeader,     XrmoptionSepArg, (caddr_t) NULL},
1120       {AN_oddTocHeader,   RN_oddTocHeader,      XrmoptionSepArg, (caddr_t) NULL},
1121       {AN_evenBodyFooter, RN_evenBodyFooter,    XrmoptionSepArg, (caddr_t) NULL},
1122       {AN_oddBodyFooter,  RN_oddBodyFooter,     XrmoptionSepArg, (caddr_t) NULL},
1123       {AN_evenBodyHeader, RN_evenBodyHeader,    XrmoptionSepArg, (caddr_t) NULL},
1124       {AN_oddBodyHeader,  RN_oddBodyHeader,     XrmoptionSepArg, (caddr_t) NULL},
1125       {AN_evenIndexFooter,RN_evenIndexFooter,   XrmoptionSepArg, (caddr_t) NULL},
1126       {AN_oddIndexFooter, RN_oddIndexFooter,    XrmoptionSepArg, (caddr_t) NULL},
1127       {AN_evenIndexHeader,RN_evenIndexHeader,   XrmoptionSepArg, (caddr_t) NULL},
1128       {AN_oddIndexHeader, RN_oddIndexHeader,    XrmoptionSepArg, (caddr_t) NULL},
1129 /* what to print */
1130       {AN_helpType,     RN_helpType,    XrmoptionSepArg, (caddr_t) NULL},
1131       {AN_helpVolume,   RN_helpVolume,  XrmoptionSepArg, (caddr_t) NULL},
1132       {AN_locationId,   RN_locationId,  XrmoptionSepArg, (caddr_t) NULL},
1133       {AN_allTopics,    RN_allTopics,   XrmoptionNoArg,  (caddr_t) "True"},
1134       {AN_subTopics,    RN_subTopics,   XrmoptionNoArg,  (caddr_t) "True"},
1135       {AN_recurse,      RN_recurse,     XrmoptionNoArg,  (caddr_t) "True"},
1136       {AN_oneTopic,     RN_oneTopic,    XrmoptionNoArg,  (caddr_t) "True"},
1137       {AN_toc,          RN_toc,         XrmoptionNoArg,  (caddr_t) "True"},
1138       {AN_index,        RN_index,       XrmoptionNoArg,  (caddr_t) "True"},
1139       {AN_frontMatter,  RN_frontMatter, XrmoptionNoArg,  (caddr_t) "True"},
1140       {AN_manPage,      RN_manPage,     XrmoptionSepArg, (caddr_t) NULL},
1141       {AN_stringData,   RN_stringData,  XrmoptionSepArg, (caddr_t) NULL},
1142       {AN_helpFile,     RN_helpFile,    XrmoptionSepArg, (caddr_t) NULL},
1143       {AN_topicTitle,   RN_topicTitle,  XrmoptionSepArg, (caddr_t) NULL},
1144       };
1145    static int numOptions = XtNumber(optionsTable);  /*number entries in table*/
1146          
1147    XrmDatabase appClassDB = NULL;
1148    XrmDatabase appUserDB = NULL;
1149    XrmDatabase dispDB = NULL;
1150    XrmDatabase homeDB = NULL;
1151    XrmDatabase scrnDB = NULL;
1152    XrmDatabase envDB = NULL;
1153    XrmDatabase commandLineDB = NULL;
1154    char        filename[MAXPATHLEN+1];
1155    XrmValue    value;
1156    char *      str_type[20];
1157    char *      invocationName=NULL;
1158    char        name_prefix[RSRCSPECLEN];
1159    char        class_prefix[RSRCSPECLEN];
1160    char        resource_name[RSRCSPECLEN];
1161    char        resource_class[RSRCSPECLEN];
1162    char *      commandLineName = NULL;
1163    char *      environment = NULL;
1164    char *      display = NULL;
1165    char *      dispDBStr = NULL;
1166    char *      scrnDBStr = NULL;
1167    int         i;
1168    char *      tmp_string;
1169    
1170    /** n.b.: If *appDB == NULL, the first XrmPutResource() call
1171        creates a database and stored its ref in appDB.  We dont
1172        need to explicitly create the db.  **/
1173
1174    str_type[0] = NULL;
1175
1176    if (*argc < 2) 
1177    {
1178       Usage();  /* print message if no arguments */
1179       exit(1);
1180    }
1181    
1182    /** Parse the commandline and put options into a db **/
1183    /* Do this now so that we can recover options from 
1184       the db for immediate use. */
1185
1186    /* search arguments for AN_rsrcname option */
1187    for (i=1; i<(*argc-1); i++)
1188    {
1189       if ( strcmp(argv[i], AN_rsrcname)==0 )  
1190       {
1191          invocationName=argv[i+1];
1192          break;
1193       }
1194    }
1195    if (invocationName == NULL)
1196    {
1197       /* search for last '/' of string */
1198       if ( _DtHelpCeStrrchr(argv[0],DIR_SLASH_STR,MB_CUR_MAX,&commandLineName) == 0 )
1199          invocationName = commandLineName+1;
1200       else    /* Starts at character after the last slash */
1201          invocationName = argv[0]; 
1202    }
1203    
1204    XrmParseCommand(&commandLineDB, optionsTable, numOptions, invocationName, 
1205                    argc, argv);
1206    
1207    if (*argc != 1) 
1208    {
1209       Usage();  /* print message if any arguments left */
1210       exit(1);
1211    }
1212    
1213    /** now create a baseline appDB with a few minimal resources in it **/
1214
1215    /* Set name and class initial values */
1216    strcpy(name_prefix, invocationName);                  /* e.g. dthelpprint */
1217    strcpy(class_prefix, HELPPRINT_APPLICATION_CLASS);    /* e.g. Dthelpprint */
1218
1219    /* get DB values */
1220    strcpy(resource_name, name_prefix);
1221    strcat(resource_name, RN_rsrcclass);   /* e.g. dthelpprint.class */
1222    strcpy(resource_class, class_prefix);
1223    strcat(resource_class, RC_rsrcclass);  /* e.g. Dthelpprint.Class */
1224    if (XrmGetResource(commandLineDB, resource_name, resource_class, 
1225                       str_type, &value) == True)
1226    {
1227       strcpy(class_prefix, value.addr);
1228    }
1229    else 
1230    {
1231       value.size = strlen(HELPPRINT_APPLICATION_CLASS)+1;
1232       value.addr = HELPPRINT_APPLICATION_CLASS;
1233    }
1234    /* CHK: Note that *str_type may be NULL here.  Is this ok? */
1235    XrmPutResource(appDB, RN_appclass, NULL, &value);
1236    XrmPutResource(appDB, RC_appclass, NULL, &value);
1237    
1238    strcpy(resource_name, name_prefix);
1239    strcat(resource_name, RN_rsrcname);    /* e.g. dthelpprint.name */
1240    strcpy(resource_class, class_prefix);
1241    strcat(resource_class, RC_rsrcname);   /* e.g. Dthelpprint.Name */
1242    if (invocationName != NULL)      /* always true */
1243    {
1244       value.size = strlen(invocationName)+1;
1245       value.addr = invocationName;           /* e.g. dthelpprint */
1246       /* CHK: state of *str_type unknown here.  Is this ok? */
1247       XrmPutResource(appDB, RN_appname, NULL, &value);
1248       XrmPutResource(appDB, RC_appname, NULL, &value);
1249    }
1250    /* CHK: currently, this and the next 'elses' are never executed */
1251    else if( XrmGetResource((XrmDatabase)commandLineDB, resource_name, 
1252                       resource_class, str_type, &value) == True)
1253    {
1254       strcpy(name_prefix, value.addr);
1255    }
1256    else 
1257    {
1258       value.size = strlen(HELPPRINT_APPLICATION_NAME)+1;
1259       value.addr = HELPPRINT_APPLICATION_NAME;           /* i.e. dthelpprint */
1260       XrmPutResource(appDB, RN_appname, NULL, &value);
1261       XrmPutResource(appDB, RC_appname, NULL, &value);
1262       strcpy(name_prefix, value.addr);
1263    }
1264    
1265    
1266    /**  Get environment variables and put values in appDB as resource **/
1267    
1268    if ((tmp_string = getenv("DISPLAY")) != NULL) 
1269    {
1270       i = strlen(tmp_string);
1271       value.addr=malloc(i+1);    /* FIX: use tmp_string here directly? */
1272       value.size = i+1;
1273       strcpy(value.addr, tmp_string);
1274       strcpy(resource_name, name_prefix);
1275       strcat(resource_name, RN_display);   /* e.g. dthelpprint.display */
1276       strcpy(resource_class, class_prefix);
1277       strcat(resource_class, RC_display);  /* e.g. Dthelpprint.Display */
1278       XrmPutResource(appDB, resource_name, NULL, &value);
1279       XrmPutResource(appDB, resource_class, NULL, &value);
1280    }
1281
1282    if ((tmp_string = getenv("PRINTER")) != NULL) 
1283    {
1284       i = strlen(tmp_string);
1285       value.addr=malloc(i+1);     /* FIX: use tmp_string here directly? */
1286       value.size = i+1;
1287       strcpy(value.addr, tmp_string);
1288       strcpy(resource_name, name_prefix);
1289       strcat(resource_name, RN_printer);    /* e.g. dthelpprint.printer */
1290       strcpy(resource_class, class_prefix);
1291       strcat(resource_class, RC_printer);    /* e.g. Dthelpprint.Printer */
1292       XrmPutResource(appDB, resource_name, NULL, &value);
1293       XrmPutResource(appDB, resource_class, NULL, &value);
1294    }
1295    
1296    /*** Build the display resource db ***/
1297
1298    /* Sequence and logic of db overlays taken from the X11R5 description
1299       of XtDisplayInitialize()  (p. 172, Xt Ref Man) and enhanced to use 
1300       appDB baseline values.  Note that it is my opinion that the
1301       description in the manual DOES NOT match the implementation
1302       of XtScreenDatabase(), which is the actual routine used
1303       by XtDisplayInitialize().  The following is the order
1304       of database merges:
1305           help-print specific environment var->resources database
1306           DT app-specific class resource file on local host
1307           X app-specific class resource file on local host
1308           app-specific user resource file on local host
1309           display server resources or user
1310               preferences file on local host
1311           screen resources from display server
1312           user environment resource file on local host
1313           application command line
1314
1315       N.B. This code does not pay attention to XFILESEARCHPATH and
1316       does not consider languages other than C in /usr/dt/app-defaults/%L.
1317    */
1318
1319    /* Overlay the central Dt app-defaults */
1320    (void) strcpy(filename, DTAPPDEFAULTS_DIR);
1321    strcat(filename, class_prefix);/*eg. /usr/dt/app-defaults/C/Dthelpprint*/
1322    appClassDB = XrmGetFileDatabase(filename);
1323    if (appClassDB != NULL)
1324       (void) XrmMergeDatabases(appClassDB, appDB);
1325    
1326    /* Overlay the central X app-defaults (if exists) */
1327    (void) strcpy(filename, XAPPDEFAULTS_DIR);
1328    strcat(filename, class_prefix);/*eg. /usr/lib/X11/app-defaults/Dthelpprint*/
1329    appClassDB = XrmGetFileDatabase(filename);
1330    if (appClassDB != NULL)
1331       (void) XrmMergeDatabases(appClassDB, appDB);
1332    
1333    /* Overlay the user class resources  */
1334    GetHomeDir(filename);
1335    strcat(filename, DIR_SLASH_STR);
1336    strcat(filename, class_prefix);          /* e.g. $HOME/Dthelpprint */
1337    appUserDB = XrmGetFileDatabase(filename);
1338    if (appUserDB != NULL)
1339       (void) XrmMergeDatabases(appUserDB, appDB);
1340
1341    /** to get the display's resources, we need to open the display first **/
1342    /* to get the display name, we first look in the commandLineDB,
1343       and if not found there, in the appDB loaded thus far. */
1344    strcpy(resource_name, name_prefix);
1345    strcat(resource_name, RN_display);   /* e.g. dthelpprint.display */
1346    strcpy(resource_class, class_prefix);
1347    strcat(resource_class, RC_display);  /* e.g. Dthelpprint.Display */
1348    if (   XrmGetResource((XrmDatabase)commandLineDB, resource_name, 
1349                       resource_class, str_type, &value) == True
1350        || XrmGetResource((XrmDatabase)*appDB, resource_name, 
1351                       resource_class, str_type, &value) == True)
1352       display = value.addr;
1353    else
1354       display = NULL;
1355    /* if display == NULL, uses DISPLAY env var */
1356    *pDpy = XOpenDisplay(display);  /* FIX: should this be .printer ?? */
1357    if (*pDpy == NULL)
1358    {  /* Bad display */
1359                                    /* FIX: chg msg to match above semantics */
1360       fprintf(stderr, _DTGETMESSAGE(INSET,42,
1361                   "%s Warning: Unable to open display %s\n"), 
1362                   argv[0], (NULL == display ? "" : display) );
1363    } /* if bad display */
1364    else
1365    {  /* Good display */
1366       /* try to overlay the display's resources (i.e. the xrdb-managed ones) */
1367       dispDBStr = XResourceManagerString(*pDpy);
1368       if (dispDBStr) dispDB = XrmGetStringDatabase(dispDBStr);
1369       else  /* if no display resources, overlay $HOME/.Xdefaults file */
1370       {
1371          filename[0] = EOS;
1372          (void) GetHomeDir (filename);
1373          (void) strcat (filename, XDEFAULTS_FILE);  /* e.g. $HOME/.Xdefaults */
1374          dispDB = XrmGetFileDatabase (filename);
1375       }
1376       if (dispDB != NULL)
1377          (void) XrmMergeDatabases(dispDB, appDB);
1378       
1379       scrnDBStr = XScreenResourceString(DefaultScreenOfDisplay(*pDpy));
1380       if (scrnDBStr) scrnDB = XrmGetStringDatabase(scrnDBStr);
1381       if (scrnDB != NULL)
1382          (void) XrmMergeDatabases(scrnDB, appDB);
1383    } /* else good display */
1384
1385    /* Overlay either file from XENVIRONMENT or $HOME/.Xdefaults-<host> */
1386    if ((environment = getenv ("XENVIRONMENT")) == NULL) 
1387    {    /* no XENVIRONMENT variable */
1388       int len;
1389       filename[0] = EOS;
1390       (void) GetHomeDir (filename);
1391       (void) strcat (filename, XDEFAULTS_HOST_FILE);
1392       len = strlen (filename);
1393       (void) _XGetHostname (filename+len, 1024-len);
1394       environment = filename;               /* e.g. $HOME/.Xdefaults-<host> */
1395    }
1396    envDB = XrmGetFileDatabase (environment);
1397    if (envDB != NULL)
1398       (void) XrmMergeDatabases(envDB, appDB);
1399  
1400    /* Overlay command line */
1401    if (*appDB == NULL) *appDB = commandLineDB;
1402    else XrmMergeDatabases (commandLineDB, appDB);
1403    
1404 }       /*$END$*/
1405
1406
1407  
1408 \f
1409 #if DOC
1410 ===================================================================
1411 $FUNBEG$:  _DtHPrGetResources()
1412 $1LINER$:  Retrieves options from a Xrm db and assigns value to a struct
1413 $DESCRIPT$:
1414 Retrieves options from a Xrm db and assigns value to a struct
1415
1416 This is a poor-man emulation to the mechanism Xt provides for
1417 setting values of widgets. 
1418
1419 $RETURNS$:
1420 $ARGS$:
1421 ========================================================$SKIP$=====*/
1422 #endif /*DOC*/
1423
1424 void _DtHPrGetResources(
1425    XrmDatabase     db,
1426    _DtHPrOptions * options)
1427 {       /*$CODE$*/
1428    XtResource * rsrc;
1429    XrmValue value;
1430    char *  str_type[20];
1431    char    resource_name[256];
1432    char    resource_class[256];
1433    char *  name_prefix;
1434    char *  class_prefix;
1435    int     debugHelpPrint;
1436    int     cnt;
1437
1438    /* Get name and class */
1439    if (XrmGetResource(db, RN_appname, RC_appname,
1440                       str_type, &value) == True)
1441       name_prefix = value.addr;
1442    else name_prefix = HELPPRINT_APPLICATION_NAME;     /*e.g. dthelpprint*/
1443
1444    if (XrmGetResource(db, RN_appclass, RC_appclass,
1445                       str_type, &value) == True)
1446       class_prefix = value.addr;
1447    else class_prefix = HELPPRINT_APPLICATION_CLASS;   /*e.g. Dthelpprint*/
1448
1449    if (XrmGetResource(db, STAR_RN_debugHelpPrint, STAR_RC_debugHelpPrint,
1450                       str_type, &value) == True)
1451       debugHelpPrint = 1;
1452    else debugHelpPrint = 0;
1453
1454    /* walk thru all resources and get their values */
1455    for ( rsrc = s_OptionResources, cnt = XtNumber(s_OptionResources); 
1456          cnt > 0; 
1457          cnt--, rsrc++ )
1458    {
1459       strcpy(resource_name, name_prefix);
1460       strcat(resource_name, rsrc->resource_name);
1461       strcpy(resource_class, class_prefix);
1462       strcat(resource_class, rsrc->resource_class);
1463       if (XrmGetResource(db, resource_name,
1464                       resource_class, str_type, &value) == True)
1465          *XtRefOffset(options,rsrc->resource_offset) = value.addr;
1466       else 
1467          *XtRefOffset(options,rsrc->resource_offset) = rsrc->default_addr;
1468
1469       if (debugHelpPrint)
1470       {
1471          if (*XtRefOffset(options,rsrc->resource_offset))
1472              printf("options%s: %s\n",  (char *) rsrc->resource_name, 
1473                          (char *) *XtRefOffset(options,rsrc->resource_offset));
1474          else
1475              printf("options%s: <NULL>\n", (char *) rsrc->resource_name);
1476       }
1477    }
1478    /* and calculate the page sizes */
1479    CalculatePageSize(db, options, name_prefix, class_prefix);
1480
1481 } /*$END$*/
1482
1483
1484 \f
1485 #if DOC
1486 ===================================================================
1487 $FUNBEG$:  _DtHPrCreateTmpFile()
1488 $1LINER$:  Creates a tmp file in $HOME/.dt/tmp
1489 $DESCRIPT$:
1490 The file is put in $HOME/.dt/tmp so that the
1491 file can be referenced from other systems.  This
1492 assumes that the user home directory is mounted
1493 on those systems.
1494 $RETURNS$:
1495 $ARGS$:
1496 ========================================================$SKIP$=====*/
1497 #endif /*DOC*/
1498
1499 char * _DtHPrCreateTmpFile(
1500         char * prefix,
1501         char * suffix)
1502 {       /*$CODE$*/
1503    static int filecnt = 0;
1504    char   dirname[MAXPATHLEN+1];
1505    char * tmppath;
1506    char * newtmpfile;
1507    int    len;
1508    char * tmp;
1509
1510    if (NULL == prefix) prefix = EMPTY_STR;
1511    if (NULL == suffix) suffix = EMPTY_STR;
1512
1513    GetHomeDir(dirname);
1514    tmppath = dirname + strlen(dirname) + 1;
1515    strcat(dirname, TMP_DIR_STR);
1516
1517    /* create the directory */
1518    for ( tmppath = strchr(tmppath,DIR_SLASH);
1519          tmppath != NULL;
1520          tmppath = strchr(++tmppath,DIR_SLASH) )
1521    {
1522       *tmppath = EOS;
1523       mkdir(dirname,0777);
1524       *tmppath = DIR_SLASH;
1525    }
1526    mkdir(dirname,0777);
1527
1528 #define FILENAMELEN 25
1529    /* generate the new tmp file */
1530    newtmpfile=malloc((strlen(dirname) + FILENAMELEN + 2) * sizeof(char));
1531    if (NULL == newtmpfile)
1532    {
1533       fprintf(stderr, "%s", _DTGETMESSAGE(INSET,45,
1534                      "Error: Unable to allocate memory for temporary file\n"));
1535    }
1536    else
1537    {
1538       sprintf(newtmpfile, _DTGETMESSAGE(INSET,50,"%1$s/%2$s%3$d_%4$d%5$s"), 
1539                 dirname, prefix, getpid(), filecnt++, suffix );
1540    }
1541
1542    return newtmpfile;
1543 }       /*$END$*/
1544