Remove UXPDS support
[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 libraries 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 <unistd.h>
42 #include <pwd.h>
43 #include <ctype.h>
44 #include <unistd.h>
45 #include <sys/param.h> /* MAXPATHLEN */
46 #include <sys/stat.h>  /* mkdir */
47 #include <sys/types.h>
48
49
50 #include <X11/Xlibint.h>  /* _XGetHostname() */
51 #include <X11/Xos.h>     /* FIX: remove? */
52 #include <X11/Intrinsic.h>   /* for Xt macros */
53 /* dont use X11/StringDefs.h because it brings in the _XtStrings global */
54
55 #include "HelpPrintI.h"
56
57 /*#define DEBUG */
58
59 /*=========== file/dir constants ===========*/
60 #define DTAPPDEFAULTS_DIR       CDE_INSTALLATION_TOP "/app-defaults/C/"
61 #define XAPPDEFAULTS_DIR        "/usr/lib/X11/app-defaults/"
62 #define XDEFAULTS_FILE          "/.Xdefaults"
63 #define XDEFAULTS_HOST_FILE     "/.Xdefaults-"
64 #define TMP_DIR_STR             "/.dt/tmp"
65 #define DTHELPPRINTSH_FILE      "/usr/dt/bin/dthelpprint.sh"
66
67 /*=========== helper constants ===========*/
68 #define EOS           '\0'
69 #define DOT_STR       "."
70 #define DIR_SLASH     '/'
71 #define EMPTY_STR     s_EmptyStr
72 #define DIR_SLASH_STR s_DirSlashStr
73
74 #define RSRCSPECLEN   100
75
76 #define INSET    5       /* message catalog set */
77
78 /*=========== helper variables ===========*/
79 static char s_EmptyStr[1] = { EOS };
80 static char s_DirSlashStr[] = "/";
81
82 /*======== helper macro ==========*/
83 #define _STR(s)   #s
84 #define STR(s)    _STR(s)
85
86 /*======== default values ==============*/
87 #define DFLT_DISPLAY            ""
88 #define DFLT_PRINTER            0
89 #define DFLT_COPY_CNT           "1"
90 #define DFLT_OUTPUT_FILE        ""
91 #define DFLT_PAPER_SIZE         RV_letter
92 #define DFLT_RSRCNAME           "dthelpprint"
93 #define DFLT_RSRCCLASS          "Dthelpprint"
94 #define DFLT_HELPTYPE           STR(DtHELP_TYPE_TOPIC)
95 #define DFLT_LOCATIONID         "_hometopic"
96 #define DFLT_ALLTOPICS          0
97 #define DFLT_SUBTOPICS          0
98 #define DFLT_ONETOPIC           0
99 #define DFLT_TOC                0
100 #define DFLT_INDEX              0
101 #define DFLT_FRONTMATTER        0
102 /* The default Header / Footer values are designed for 
103    English labels and a 70 column content. */
104 #define DFLT_TOC_HEADER         "$LMARGIN$VOLUME\n\n"
105 #define DFLT_TOC_FOOTER         "\n$LMARGIN                                                      $SECTNUM\n"
106 #define DFLT_BODY_HEADER        "$LMARGIN$VOLUME$VOLUMEFILL             $PAGENUMFILLPage $PAGENUM\n\n"
107 #define DFLT_BODY_FOOTER        "\n$LMARGIN$TOPIC$TOPICFILL     $SECTNUMFILLSection $SECTNUM\n"
108 #define DFLT_INDEX_HEADER       "$LMARGIN$VOLUME$VOLUMEFILL             $PAGENUMFILLPage $PAGENUM\n\n"
109 #define DFLT_INDEX_FOOTER       "\n$LMARGIN                                                                  $SECTNUM\n"
110 #define DFLT_TOPICTITLE         "Help"
111 #define DFLT_SH_CMD             DTHELPPRINTSH_FILE
112 #define DFLT_ICONV_CMD_AND_ARGS "iconv -f %s -t %s %s > %s"
113 #define DFLT_LP_CMD             0
114 #define DFLT_PR_CMD             "pr"
115 /* pr arg values order:  STRING job title, INT page height, STRING filename */
116 #define DFLT_PR_ARGS            "-h \"%s\" -f -l%d %s"  
117 /* pr offset arg value order:  INT col offset */
118 #define DFLT_PR_OFFSET_ARG      "-o%d"
119 #define DFLT_ECHO_CMD           "echo"
120 /* echo arg values order:  STRING string */
121 #define DFLT_ECHO_ARGS          "\"%s\""
122 #define DFLT_FOLD_CMD           "fold"
123 /* fold arg values order:  INT column width, STRING filename */
124 #define DFLT_FOLD_ARGS          "-w %d %s"
125 #define DFLT_MAN_CMD            "man"
126 /* man arg values order:  STRING man page */
127 #define DFLT_MAN_ARGS           "%s"
128 /* redirect arg value order: STRING filename */
129 #define DFLT_REDIR_CMD_AND_ARGS " > %s"
130 #define DFLT_DEBUG_HELPPRINT    0
131
132 /*======== resource type constants ==============*/
133 /*** N.b.: These are currently not supported. ***/
134 #define XtRBool         "Bool"
135 #define XtRBoolean      "Boolean"
136 #define XtRDimension    "Dimension"
137 #define XtRDisplay      "Display"
138 #define XtRFile         "File"
139 #define XtRFloat        "Float"
140 #define XtRFont         "Font"
141 #define XtRImmediate    "Immediate"
142 #define XtRInt          "Int"
143 #define XtROrientation  "Orientation"
144 #define XtRScreen       "Screen"
145 #define XtRShort        "Short"
146 #define XtRString       "String"
147
148 #if 0
149 /*======== helper structures ==============*/
150 typedef struct _XtResource {
151    String       resource_name;
152    String       resource_class;
153    String       resource_type;
154    Cardinal     resource_size;
155    Cardinal     resource_offset;
156    String       default_type;
157    XtPointer    default_addr;
158 } XtResource, * XtResourceList;
159
160 #endif
161
162 /*======== variables ==============*/
163
164 /* if resource_name or resource_class are NULL, use function arg values */
165 static XtResource s_OptionResources[] = {
166   { RN_display,
167     RC_display,
168     XtRString,
169     sizeof(String),
170     XtOffset (_DtHPrOptionsPtr, display),
171     XtRImmediate,
172     (XtPointer) DFLT_DISPLAY },
173    
174   { RN_printer,
175     RC_printer,
176     XtRString,
177     sizeof(String),
178     XtOffset (_DtHPrOptionsPtr, printer),
179     XtRImmediate,
180     (XtPointer) DFLT_PRINTER },
181    
182   { RN_copies,
183     RC_copies,
184     XtRString,
185     sizeof(String),
186     XtOffset (_DtHPrOptionsPtr, copies),
187     XtRImmediate,
188     (XtPointer) DFLT_COPY_CNT },
189    
190   { RN_outputFile,
191     RC_outputFile,
192     XtRString,
193     sizeof(String),
194     XtOffset (_DtHPrOptionsPtr, outputFile),
195     XtRImmediate,
196     (XtPointer) DFLT_OUTPUT_FILE },
197    
198   { RN_printer "." RN_paperSize,   /* see CalculatePageSize() to grok this */
199     RC_printer "." RC_paperSize,   /* see CalculatePageSize() to grok this */
200     XtRString,
201     sizeof(String),
202     XtOffset (_DtHPrOptionsPtr, paperSize),
203     XtRImmediate,
204     (XtPointer) DFLT_PAPER_SIZE },
205    
206   { RN_rsrcname,
207     RC_rsrcname,
208     XtRString,
209     sizeof(String),
210     XtOffset (_DtHPrOptionsPtr, rsrcname),
211     XtRImmediate,
212     (XtPointer) DFLT_RSRCNAME },
213    
214   { RN_rsrcclass,
215     RC_rsrcclass,
216     XtRString,
217     sizeof(String),
218     XtOffset (_DtHPrOptionsPtr, rsrcclass),
219     XtRImmediate,
220     (XtPointer) DFLT_RSRCCLASS },
221    
222   { RN_helpType,
223     RC_helpType,
224     XtRString,
225     sizeof(String),
226     XtOffset (_DtHPrOptionsPtr, helpType),
227     XtRImmediate,
228     (XtPointer) DFLT_HELPTYPE },
229    
230   { RN_helpVolume,
231     RC_helpVolume,
232     XtRString,
233     sizeof(String),
234     XtOffset (_DtHPrOptionsPtr, helpVolume),
235     XtRImmediate,
236     (XtPointer) 0 },
237    
238   { RN_locationId,
239     RC_locationId,
240     XtRString,
241     sizeof(String),
242     XtOffset (_DtHPrOptionsPtr, locationId),
243     XtRImmediate,
244     (XtPointer) DFLT_LOCATIONID },
245    
246   { RN_allTopics,
247     RC_allTopics,
248     XtRString,
249     sizeof(String),
250     XtOffset (_DtHPrOptionsPtr, allTopics),
251     XtRImmediate,
252     (XtPointer) DFLT_ALLTOPICS },
253    
254   { RN_subTopics,
255     RC_subTopics,
256     XtRString,
257     sizeof(String),
258     XtOffset (_DtHPrOptionsPtr, subTopics),
259     XtRImmediate,
260     (XtPointer) DFLT_SUBTOPICS },
261    
262   /* recurse shadows subTopics for legacy reasons.  
263      recurse was the VUE 3.0 helpprint option for subTopics */
264   { RN_recurse,
265     RC_recurse,
266     XtRString,
267     sizeof(String),
268     XtOffset (_DtHPrOptionsPtr, subTopics),
269     XtRImmediate,
270     (XtPointer) DFLT_SUBTOPICS },
271    
272   { RN_oneTopic,
273     RC_oneTopic,
274     XtRString,
275     sizeof(String),
276     XtOffset (_DtHPrOptionsPtr, oneTopic),
277     XtRImmediate,
278     (XtPointer) DFLT_ONETOPIC },
279    
280   { RN_toc,
281     RC_toc,
282     XtRString,
283     sizeof(String),
284     XtOffset (_DtHPrOptionsPtr, toc),
285     XtRImmediate,
286     (XtPointer) DFLT_TOC },
287    
288   { RN_index,
289     RC_index,
290     XtRString,
291     sizeof(String),
292     XtOffset (_DtHPrOptionsPtr, index),
293     XtRImmediate,
294     (XtPointer) DFLT_INDEX },
295    
296   { RN_frontMatter,
297     RC_frontMatter,
298     XtRString,
299     sizeof(String),
300     XtOffset (_DtHPrOptionsPtr, frontMatter),
301     XtRImmediate,
302     (XtPointer) DFLT_FRONTMATTER },
303    
304   { RN_evenTocFooter,
305     RC_evenTocFooter,
306     XtRString,
307     sizeof(String),
308     XtOffset (_DtHPrOptionsPtr, tocHF.evenFooter),
309     XtRImmediate,
310     (XtPointer) DFLT_TOC_FOOTER },
311    
312   { RN_oddTocFooter,
313     RC_oddTocFooter,
314     XtRString,
315     sizeof(String),
316     XtOffset (_DtHPrOptionsPtr, tocHF.oddFooter),
317     XtRImmediate,
318     (XtPointer) DFLT_TOC_FOOTER },
319    
320   { RN_evenTocHeader,
321     RC_evenTocHeader,
322     XtRString,
323     sizeof(String),
324     XtOffset (_DtHPrOptionsPtr, tocHF.evenHeader),
325     XtRImmediate,
326     (XtPointer) DFLT_TOC_HEADER },
327    
328   { RN_oddTocHeader,
329     RC_oddTocHeader,
330     XtRString,
331     sizeof(String),
332     XtOffset (_DtHPrOptionsPtr, tocHF.oddHeader),
333     XtRImmediate,
334     (XtPointer) DFLT_TOC_HEADER },
335    
336   { RN_evenBodyFooter,
337     RC_evenBodyFooter,
338     XtRString,
339     sizeof(String),
340     XtOffset (_DtHPrOptionsPtr, bodyHF.evenFooter),
341     XtRImmediate,
342     (XtPointer) DFLT_BODY_FOOTER },
343    
344   { RN_oddBodyFooter,
345     RC_oddBodyFooter,
346     XtRString,
347     sizeof(String),
348     XtOffset (_DtHPrOptionsPtr, bodyHF.oddFooter),
349     XtRImmediate,
350     (XtPointer) DFLT_BODY_FOOTER },
351    
352   { RN_evenBodyHeader,
353     RC_evenBodyHeader,
354     XtRString,
355     sizeof(String),
356     XtOffset (_DtHPrOptionsPtr, bodyHF.evenHeader),
357     XtRImmediate,
358     (XtPointer) DFLT_BODY_HEADER },
359    
360   { RN_oddBodyHeader,
361     RC_oddBodyHeader,
362     XtRString,
363     sizeof(String),
364     XtOffset (_DtHPrOptionsPtr, bodyHF.oddHeader),
365     XtRImmediate,
366     (XtPointer) DFLT_BODY_HEADER },
367    
368   { RN_evenIndexFooter,
369     RC_evenIndexFooter,
370     XtRString,
371     sizeof(String),
372     XtOffset (_DtHPrOptionsPtr, indexHF.evenFooter),
373     XtRImmediate,
374     (XtPointer) DFLT_INDEX_FOOTER },
375    
376   { RN_oddIndexFooter,
377     RC_oddIndexFooter,
378     XtRString,
379     sizeof(String),
380     XtOffset (_DtHPrOptionsPtr, indexHF.oddFooter),
381     XtRImmediate,
382     (XtPointer) DFLT_INDEX_FOOTER },
383    
384   { RN_evenIndexHeader,
385     RC_evenIndexHeader,
386     XtRString,
387     sizeof(String),
388     XtOffset (_DtHPrOptionsPtr, indexHF.evenHeader),
389     XtRImmediate,
390     (XtPointer) DFLT_INDEX_HEADER },
391    
392   { RN_oddIndexHeader,
393     RC_oddIndexHeader,
394     XtRString,
395     sizeof(String),
396     XtOffset (_DtHPrOptionsPtr, indexHF.oddHeader),
397     XtRImmediate,
398     (XtPointer) DFLT_INDEX_HEADER },
399    
400   { RN_manPage,
401     RC_manPage,
402     XtRString,
403     sizeof(String),
404     XtOffset (_DtHPrOptionsPtr, manPage),
405     XtRImmediate,
406     (XtPointer) 0 },
407    
408   { RN_stringData,
409     RC_stringData,
410     XtRString,
411     sizeof(String),
412     XtOffset (_DtHPrOptionsPtr, stringData),
413     XtRImmediate,
414     (XtPointer) 0 },
415    
416   { RN_helpFile,
417     RC_helpFile,
418     XtRString,
419     sizeof(String),
420     XtOffset (_DtHPrOptionsPtr, helpFile),
421     XtRImmediate,
422     (XtPointer) 0 },
423    
424   { RN_topicTitle,
425     RC_topicTitle,
426     XtRString,
427     sizeof(String),
428     XtOffset (_DtHPrOptionsPtr, topicTitle),
429     XtRImmediate,
430     (XtPointer) DFLT_TOPICTITLE },
431
432   { RN_echoCommand,
433     RC_echoCommand,
434     XtRString,
435     sizeof(String),
436     XtOffset (_DtHPrOptionsPtr, echoCommand),
437     XtRImmediate,
438     (XtPointer) DFLT_ECHO_CMD },
439    
440   { RN_echoArgs,
441     RC_echoArgs,
442     XtRString,
443     sizeof(String),
444     XtOffset (_DtHPrOptionsPtr, echoArgs),
445     XtRImmediate,
446     (XtPointer) DFLT_ECHO_ARGS },
447    
448   { RN_foldCommand,
449     RC_foldCommand,
450     XtRString,
451     sizeof(String),
452     XtOffset (_DtHPrOptionsPtr, foldCommand),
453     XtRImmediate,
454     (XtPointer) DFLT_FOLD_CMD },
455    
456   { RN_foldArgs,
457     RC_foldArgs,
458     XtRString,
459     sizeof(String),
460     XtOffset (_DtHPrOptionsPtr, foldArgs),
461     XtRImmediate,
462     (XtPointer) DFLT_FOLD_ARGS },
463    
464   { RN_prCommand,
465     RC_prCommand,
466     XtRString,
467     sizeof(String),
468     XtOffset (_DtHPrOptionsPtr, prCommand),
469     XtRImmediate,
470     (XtPointer) DFLT_PR_CMD },
471    
472   { RN_prArgs,
473     RC_prArgs,
474     XtRString,
475     sizeof(String),
476     XtOffset (_DtHPrOptionsPtr, prArgs),
477     XtRImmediate,
478     (XtPointer) DFLT_PR_ARGS },
479    
480   { RN_prOffsetArg,
481     RC_prOffsetArg,
482     XtRString,
483     sizeof(String),
484     XtOffset (_DtHPrOptionsPtr, prOffsetArg),
485     XtRImmediate,
486     (XtPointer) DFLT_PR_OFFSET_ARG },
487    
488   { RN_manCommand,
489     RC_manCommand,
490     XtRString,
491     sizeof(String),
492     XtOffset (_DtHPrOptionsPtr, manCommand),
493     XtRImmediate,
494     (XtPointer) DFLT_MAN_CMD },
495    
496   { RN_manArgs,
497     RC_manArgs,
498     XtRString,
499     sizeof(String),
500     XtOffset (_DtHPrOptionsPtr, manArgs),
501     XtRImmediate,
502     (XtPointer) DFLT_MAN_ARGS },
503    
504   { RN_redirectCmdAndArgs,
505     RC_redirectCmdAndArgs,
506     XtRString,
507     sizeof(String),
508     XtOffset (_DtHPrOptionsPtr, redirectCmdAndArgs),
509     XtRImmediate,
510     (XtPointer) DFLT_REDIR_CMD_AND_ARGS },
511    
512   { RN_lpCommand,
513     RC_lpCommand,
514     XtRString,
515     sizeof(String),
516     XtOffset (_DtHPrOptionsPtr, lpCommand),
517     XtRImmediate,
518     (XtPointer) DFLT_LP_CMD },
519    
520   { RN_shCommand,
521     RC_shCommand,
522     XtRString,
523     sizeof(String),
524     XtOffset (_DtHPrOptionsPtr, shCommand),
525     XtRImmediate,
526     (XtPointer) DFLT_SH_CMD },
527    
528   { RN_iconvCmdAndArgs,
529     RC_iconvCmdAndArgs,
530     XtRString,
531     sizeof(String),
532     XtOffset (_DtHPrOptionsPtr, iconvCmdAndArgs),
533     XtRImmediate,
534     (XtPointer) DFLT_ICONV_CMD_AND_ARGS },
535    
536   { RN_debugHelpPrint,
537     RC_debugHelpPrint,
538     XtRString,
539     sizeof(String),
540     XtOffset (_DtHPrOptionsPtr, debugHelpPrint),
541     XtRImmediate,
542     (XtPointer) DFLT_DEBUG_HELPPRINT },
543    
544 #if 0   /* Because we aren't using Xt and only emulating it,
545            we can't handle data type other than String.  These
546            are all Integer values, so I process them by hand
547            below in CalculatePageSize(). */
548   { RN_colsWidth,
549     RC_colsWidth,
550     XtRString,
551     sizeof(String),
552     XtOffset (_DtHPrOptionsPtr, colsWidth),
553     XtRImmediate,
554     (XtPointer) 0 },
555    
556   { RN_rowsHeight,
557     RC_rowsHeight,
558     XtRString,
559     sizeof(String),
560     XtOffset (_DtHPrOptionsPtr, rowsHeight),
561     XtRImmediate,
562     (XtPointer) 0 },
563    
564   { RN_colsLeftMargin,
565     RC_colsLeftMargin,
566     XtRString,
567     sizeof(String),
568     XtOffset (_DtHPrOptionsPtr, colsLeftMargin),
569     XtRImmediate,
570     (XtPointer) 0 },
571    
572   { RN_colsRightMargin,
573     RC_colsRightMargin,
574     XtRString,
575     sizeof(String),
576     XtOffset (_DtHPrOptionsPtr, colsRightMargin),
577     XtRImmediate,
578     (XtPointer) 0 },
579    
580   { RN_rowsTopMargin,
581     RC_rowsTopMargin,
582     XtRString,
583     sizeof(String),
584     XtOffset (_DtHPrOptionsPtr, rowsTopMargin),
585     XtRImmediate,
586     (XtPointer) 0 },
587    
588   { RN_rowsBottomMargin,
589     RC_rowsBottomMargin,
590     XtRString,
591     sizeof(String),
592     XtOffset (_DtHPrOptionsPtr, rowsBottomMargin),
593     XtRImmediate,
594     (XtPointer) 0 },
595 #endif
596    
597 }; /* resources */
598
599
600
601 \f
602 #if DOC
603 ===================================================================
604 $PFUNBEG$:  GetHomeDir()
605 $1LINER$:   Gets home directory of user owning current app
606 $DESCRIPT$:
607 Gets the home directory by 
608    1. using the HOME environment variable
609 or 2. using the USER env variable and the 
610       directory in the password file for that user
611 or 3. using getuid() and the 
612       directory in the password file for that user
613
614 The home directory is stored in the string that is passed
615 in.  No overflow checking is possible, so the string should
616 be MAXPATHLEN bytes long.
617 $RETURNS$:
618 Returns the 'dest' pointer
619 $ARGS$:
620 dest: pointer to string to hold home directory
621 ========================================================$SKIP$=====*/
622 #endif /*DOC*/
623
624 static char *GetHomeDir (
625         char *dest)
626 {       /*$CODE$*/
627         uid_t uid;
628         struct passwd *pw;
629         char *ptr;
630
631         if((ptr = getenv("HOME")) != NULL)
632         {
633             snprintf(dest, MAXPATHLEN, "%s", ptr);
634         }
635         else
636         {
637             if((ptr = getenv("USER")) != NULL)
638             {
639                 char user[MAXPATHLEN];
640                 snprintf(user, MAXPATHLEN, "%s", ptr);
641                 pw = getpwnam(user);
642             }
643             else
644             {
645                 uid = getuid();
646                 pw = getpwuid(uid);
647             }
648             if (pw)
649                 snprintf(dest, MAXPATHLEN, "%s", pw->pw_dir);
650             else
651                 *dest = '\0';
652         }
653         return dest;
654 }   /*$END$*/
655
656
657
658
659 \f
660 #if DOC
661 ===================================================================
662 $PFUNBEG$:  Usage()
663 $1LINER$:  Prints usage message and returns
664 $DESCRIPT$:
665 This routine prints a generic help message
666 $RETURNS$:
667 $ARGS$:
668 ========================================================$SKIP$=====*/
669 #endif /*DOC*/
670
671 static
672 void Usage(void)
673 {       /*$CODE$*/
674    static char * usage[] = 
675    {
676       "dthelpprint - Print program for Help\n\n",
677       "Usage: dthelpprint [options]\n",
678       "Options controlling how to print:\n",
679       "\t" AN_printer " printername  printer to use\n",
680       "\t" AN_copies " number        number of copies to print\n",
681       "\t" AN_outputFile " filename  write output to this file\n",
682       "\t" AN_paperSize " size       format content to this paper size\n",
683       "\t\tsize = {" RV_letter "|" RV_legal "|\n" ,
684       "\t\t        " RV_executive "|" RV_a4 "|" RV_b5 "}\n",
685       "\t" AN_display " displayname  display from which to get resources\n",
686       "\t" AN_rsrcname " name            program name used when getting resources\n",
687       "\t" AN_rsrcclass " name           class name used when getting resources\n",
688       "\t" AN_xrm " resourcestring   additional resources\n",
689       "Options controlling what to print:\n",
690       "\t" AN_helpType " type        type of Help data\n",
691       "\t\ttype = 0 (help volume), 1 (string), 2 (man page), 3 (help file)\n",
692       "\t" AN_helpVolume " volume    full path of help volume file\n",
693       "\t" AN_locationId " location  name of Help topic in the volume\n",
694       "\t" AN_allTopics "            print all topics, toc, & index in the help volume\n",
695       "\t" AN_subTopics "            print topic locationId and all subtopics\n",
696       "\t" AN_oneTopic "             print topic locationId\n",
697       "\t" AN_toc "                  print help volume table of contents\n",
698       "\t" AN_index "                print help volume index\n",
699       "\t" AN_frontMatter "          print help volume front matter\n",
700       "\t" AN_manPage " manpagename  name of man page\n",
701       "\t" AN_stringData " string    Help text to print\n",
702       "\t" AN_helpFile " filename    file containing Help text\n",
703       "\t" AN_topicTitle " title     title string for Help text\n",
704       NULL
705    };
706     int i;
707     for (i=0; usage[i]; i++)
708        printf("%s", _DTGETMESSAGE(INSET,i,usage[i]));
709 }       /*$END$*/
710
711 \f
712 #if DOC
713 ===================================================================
714 $PFUNBEG$:  CalculatePageSize()
715 $1LINER$:  calculates the page size based on resource values
716 $DESCRIPT$:
717 Reads the resources from the database and calculates
718 the page dimensions and stores them in the resources structure.
719 $RETURNS$:
720 $ARGS$:
721 ========================================================$SKIP$=====*/
722 #endif /*DOC*/
723
724 static
725 void CalculatePageSize(
726    XrmDatabase     appDB,
727    _DtHPrOptions * options,
728    char *          appname,
729    char *          appclass)
730 {       /*$CODE$*/
731
732    struct unprintableMargins
733    {
734       int leftUnprintableMargin;
735       int rightUnprintableMargin;
736       int topUnprintableMargin;
737       int bottomUnprintableMargin;
738    };
739
740    static struct unprintableMargins blankMargins = { 6,   2,   2,   1 };
741
742 #define LETTER          0
743 #define LEGAL           1
744 #define EXECUTIVE       2
745 #define A4              3
746 #define B5              4
747 #define MAXVALIDSIZE    4
748
749    /* page size info */
750    struct page 
751    {
752       int width;
753       int height;
754       int leftMargin;
755       int rightMargin;
756       int topMargin;
757       int bottomMargin;
758    };
759
760    static struct page  pagesize[] = 
761    {  /* sizes are in characters of standard HPLJIII courier */
762       /* Note that the text margin counts do *NOT* take into account the 
763          printless margins, which are the margins on which the printer 
764          is unable to print. */
765       /* WI: paper size width; HI: paper size height;
766          LM: desired text left margin; RM: desired text right margin
767          TM: desired text top margin; BM: desired text bottom margin
768       */
769       /*WI, HI, LM, RM, TM, BM */
770       { 91, 69, 10, 10, 6,  6 }, /* letter */
771       { 91, 88, 10, 10, 6,  6 }, /* legal */
772       { 77, 66, 10, 10, 6,  6 }, /* executive */
773       { 88, 73, 10, 10, 6,  6 }, /* A4 */
774       { 76, 63, 10, 10, 6,  6 }  /* B5 */
775    };
776    
777 #if 0   /* save these dimensions here */
778       /* Known Dimensions for standard HPLJIII courier: 
779             char size: 2.37 mm width x 4.04 mm height
780       US-letter:  8.5x11 in       : 91 col x 69 rows
781       US-legal:   8.5x14 in       : 91 col x 88 rows
782       executive:  7.25x10.5 in    : 77 col x 66 rows
783       A4:         210x297 mm      : 88 col x 73 rows
784       B5:         182x257 mm      : 76 col x 63 rows
785       */
786
787       /* Known Dimensions in 100ths of a mm */
788       { 21590, 27940, 2540, 2540, 2540, 2540 },  /* letter */
789       { 21590, 35560, 2540, 2540, 2540, 2540 },  /* legal */
790       { 18415, 26670, 2540, 2540, 2540, 2540 },  /* exec */
791       { 21000, 29700, 2540, 2540, 2540, 2540 },  /* a4 */
792       { 18200, 25700, 2540, 2540, 2540, 2540 }   /* b5 */
793 static float dphm = 300.*2540.;
794 #endif
795
796    int  (*stricmp)(const char *,const char *);
797    char *name;
798    char name_prefix[RSRCSPECLEN];
799    char name_prefix_temp[sizeof(name_prefix)];
800    char class_prefix[RSRCSPECLEN];
801    char class_prefix_temp[sizeof(class_prefix)];
802    char resource_name[RSRCSPECLEN];
803    char resource_class[RSRCSPECLEN];
804    char *str_type[20];
805    XrmValue value;
806    int papersize = -1;
807    char buf[20];
808    int width,height;
809    int lmargin,rmargin,tmargin,bmargin;
810    int adjLmargin,adjRmargin,adjTmargin,adjBmargin;
811    int textWidth, textHeight;
812    int i;
813    
814    /* build printer resource name and class */
815    snprintf(name_prefix, sizeof(name_prefix), "%s%s", appname, RN_printer);    /* e.g. dthelpprint.printer */
816    snprintf(class_prefix, sizeof(class_prefix), "%s%s", appclass, RC_printer); /* e.g. Dthelpprint.Printer */
817    
818    /********************/
819    /* Get printer name */
820    /********************/
821    
822    snprintf(resource_name, sizeof(resource_name), "%s%s", name_prefix, RN_rsrcname);    /* e.g. dthelpprint.printer.name */
823    snprintf(resource_class, sizeof(resource_class), "%s%s", class_prefix, 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       snprintf(name_prefix_temp, sizeof(name_prefix_temp), "%s%s%s", name_prefix, DOT_STR, name);    /* e.g. dthelpprint.printer.<name> */
831       strcpy(name_prefix, name_prefix_temp);
832       snprintf(class_prefix_temp, sizeof(class_prefix_temp), "%s%s%s", class_prefix, DOT_STR, name); /* e.g. Dthelpprint.Printer.<name> */
833       strcpy(class_prefix, class_prefix_temp);
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)
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       snprintf(resource_name, sizeof(resource_name), "%s%s", name_prefix, rsrc->resource_name);
1460       snprintf(resource_class, sizeof(resource_class), "%s%s", class_prefix, rsrc->resource_class);
1461       if (XrmGetResource(db, resource_name,
1462                       resource_class, str_type, &value) == True)
1463          *XtRefOffset(options,rsrc->resource_offset) = value.addr;
1464       else 
1465          *XtRefOffset(options,rsrc->resource_offset) = rsrc->default_addr;
1466
1467       if (debugHelpPrint)
1468       {
1469          if (*XtRefOffset(options,rsrc->resource_offset))
1470              printf("options%s: %s\n",  (char *) rsrc->resource_name, 
1471                          (char *) *XtRefOffset(options,rsrc->resource_offset));
1472          else
1473              printf("options%s: <NULL>\n", (char *) rsrc->resource_name);
1474       }
1475    }
1476    /* and calculate the page sizes */
1477    CalculatePageSize(db, options, name_prefix, class_prefix);
1478
1479 } /*$END$*/
1480
1481
1482 \f
1483 #if DOC
1484 ===================================================================
1485 $FUNBEG$:  _DtHPrCreateTmpFile()
1486 $1LINER$:  Creates a tmp file in $HOME/.dt/tmp
1487 $DESCRIPT$:
1488 The file is put in $HOME/.dt/tmp so that the
1489 file can be referenced from other systems.  This
1490 assumes that the user home directory is mounted
1491 on those systems.
1492 $RETURNS$:
1493 $ARGS$:
1494 ========================================================$SKIP$=====*/
1495 #endif /*DOC*/
1496
1497 char * _DtHPrCreateTmpFile(
1498         char * prefix,
1499         char * suffix)
1500 {       /*$CODE$*/
1501    static int filecnt = 0;
1502    char   dirname[MAXPATHLEN+1];
1503    char * tmppath;
1504    char * newtmpfile;
1505    int    len;
1506    char * tmp;
1507
1508    if (NULL == prefix) prefix = EMPTY_STR;
1509    if (NULL == suffix) suffix = EMPTY_STR;
1510
1511    GetHomeDir(dirname);
1512    tmppath = dirname + strlen(dirname) + 1;
1513    strcat(dirname, TMP_DIR_STR);
1514
1515    /* create the directory */
1516    for ( tmppath = strchr(tmppath,DIR_SLASH);
1517          tmppath != NULL;
1518          tmppath = strchr(++tmppath,DIR_SLASH) )
1519    {
1520       *tmppath = EOS;
1521       mkdir(dirname,0777);
1522       *tmppath = DIR_SLASH;
1523    }
1524    mkdir(dirname,0777);
1525
1526 #define FILENAMELEN 25
1527    /* generate the new tmp file */
1528    newtmpfile=malloc((strlen(dirname) + FILENAMELEN + 2) * sizeof(char));
1529    if (NULL == newtmpfile)
1530    {
1531       fprintf(stderr, "%s", _DTGETMESSAGE(INSET,45,
1532                      "Error: Unable to allocate memory for temporary file\n"));
1533    }
1534    else
1535    {
1536       sprintf(newtmpfile, _DTGETMESSAGE(INSET,50,"%1$s/%2$s%3$d_%4$d%5$s"), 
1537                 dirname, prefix, getpid(), filecnt++, suffix );
1538    }
1539
1540    return newtmpfile;
1541 }       /*$END$*/
1542