~ubuntu-branches/ubuntu/raring/9base/raring

« back to all changes in this revision

Viewing changes to troff/dwbinit.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-11-07 12:25:14 UTC
  • mfrom: (6.2.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091107122514-tcw4u4ha2w2xbbnn
Tags: 1:4-1
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
  packages and changelog.
* Adding README.source.
* Merging upstream version 4.
* Adding sh4 to explicit architecture list (Closes: #545772).
* Moving maintainer homepage field from control to copyright.
* Updating README.source.
* Updating homepage field in control.
* Removing manpage patch, went upstream.
* Removing kfreebsd.patch, went upstream.
* Generalizing manpage moving in rules.
* Moving base directory from /usr/lib/9base to /usr/lib/plan9 for
  consistency reasons.
* Prefixing manpages with plan9 instead of 9base for consistency
  reasons.
* Bumping versioned build-depends on debhelper.
* Making internal mkMAP and sendcover scripts executable.
* Adding patch to adjust shebang in newly included troff commands.
* Updating lintian-overrides.
* Making buildd-depends on quilt versioned.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Pathname management routines for DWB C programs.
 
4
 *
 
5
 * Applications should initialize a dwbinit array with the string
 
6
 * pointers and arrays that need to be updated, and then hand that
 
7
 * array to DWBinit before much else happens in their main program.
 
8
 * DWBinit calls DWBhome to get the current home directory. DWBhome
 
9
 * uses the last definition of DWBENV (usually "DWBHOME") in file
 
10
 * DWBCONFIG (e.g., /usr/lib/dwb3.4) or the value assigned to that
 
11
 * variable in the environment if the DWBCONFIG file doesn't exist,
 
12
 * can't be read, or doesn't define DWBENV.
 
13
 *
 
14
 * DWBCONFIG must be a simple shell script - comments, a definition
 
15
 * of DWBHOME, and perhaps an export or echo is about all that's
 
16
 * allowed. The parsing in DWBhome is simple and makes no attempt
 
17
 * to duplicate the shell. It only looks for DWBHOME= as the first
 
18
 * non-white space string on a line, so
 
19
 *
 
20
 *      #
 
21
 *      # A sample DWBCONFIG shell script
 
22
 *      #
 
23
 *
 
24
 *      DWBHOME=/usr/add-on/dwb3.4
 
25
 *      export DWBHOME
 
26
 *
 
27
 * means DWBhome would return "/usr/add-on/dwb3.4" for the DWB home
 
28
 * directory. A DWBCONFIG file means there can only be one working
 
29
 * copy of a DWB release on a system, which seems like a good idea.
 
30
 * Using DWBCONFIG also means programs will always include correct
 
31
 * versions of files (e.g., prologues or macro packages).
 
32
 *
 
33
 * Relying on an environment variable guarantees nothing. You could
 
34
 * execute a version of dpost, but your environment might point at
 
35
 * incorrect font tables or prologues. Despite the obvious problems
 
36
 * we've also implemented an environment variable approach, but it's
 
37
 * only used if there's no DWBCONFIG file.
 
38
 *
 
39
 * DWBinit calls DWBhome to get the DWB home directory prefix and
 
40
 * then marches through its dwbinit argument, removing the default
 
41
 * home directory and prepending the new home. DWBinit stops when
 
42
 * it reaches an element that has NULL for its address and value
 
43
 * fields. Pointers in a dwbinit array are reallocated and properly
 
44
 * initialized; arrays are simply reinitialized if there's room.
 
45
 * All pathnames that are to be adjusted should be relative. For
 
46
 * example,
 
47
 *
 
48
 *      char    *fontdir = "lib/font";
 
49
 *      char    xyzzy[25] = "etc/xyzzy";
 
50
 *
 
51
 * would be represented in a dwbinit array as,
 
52
 *
 
53
 *      dwbinit allpaths[] = {
 
54
 *              &fontdir, NULL, 0,
 
55
 *              NULL, xyzzy, sizeof(xyzzy),
 
56
 *              NULL, NULL, 0
 
57
 *      };
 
58
 *              
 
59
 * The last element must have NULL entries for the address and
 
60
 * value fields. The main() routine would then do,
 
61
 *
 
62
 *      #include "dwbinit.h"
 
63
 *
 
64
 *      main() {
 
65
 *
 
66
 *              DWBinit("program name", allpaths);
 
67
 *              ...
 
68
 *      }
 
69
 *
 
70
 * Debugging is enabled if DWBDEBUG is in the environment and has
 
71
 * the value ON. Output is occasionally useful and probably should
 
72
 * be documented.
 
73
 *
 
74
 */
 
75
 
 
76
#include <u.h>
 
77
#include <stdio.h>
 
78
#include <ctype.h>
 
79
#include <string.h>
 
80
#include <stdlib.h>
 
81
 
 
82
#include "dwbinit.h"
 
83
 
 
84
#ifndef DWBCONFIG
 
85
#define DWBCONFIG       "/dev/null"
 
86
#endif
 
87
 
 
88
#ifndef DWBENV
 
89
#define DWBENV          "DWBHOME"
 
90
#endif
 
91
 
 
92
#ifndef DWBHOME
 
93
#define DWBHOME         ""
 
94
#endif
 
95
 
 
96
#ifndef DWBDEBUG
 
97
#define DWBDEBUG        "DWBDEBUG"
 
98
#endif
 
99
 
 
100
#ifndef DWBPREFIX
 
101
#define DWBPREFIX       "\\*(.P"
 
102
#endif
 
103
 
 
104
/*****************************************************************************/
 
105
 
 
106
void DWBdebug(dwbinit *ptr, int level)
 
107
{
 
108
 
 
109
    char        *path;
 
110
    char        *home;
 
111
    static char *debug = NULL;
 
112
 
 
113
/*
 
114
 *
 
115
 * Debugging output, but only if DWBDEBUG is defined to be ON in the
 
116
 * environment. Dumps general info the first time through.
 
117
 *
 
118
 */
 
119
 
 
120
    if ( debug == NULL && (debug = getenv(DWBDEBUG)) == NULL )
 
121
        debug = "OFF";
 
122
 
 
123
    if ( strcmp(debug, "ON") == 0 ) {
 
124
        if ( level == 0 ) {
 
125
            fprintf(stderr, "Environment variable: %s\n", DWBENV);
 
126
            fprintf(stderr, "Configuration file: %s\n", DWBCONFIG);
 
127
            fprintf(stderr, "Default home: %s\n", DWBHOME);
 
128
            if ( (home = DWBhome()) != NULL )
 
129
                fprintf(stderr, "Current home: %s\n", home);
 
130
        }   /* End if */
 
131
 
 
132
        fprintf(stderr, "\n%s pathnames:\n", level == 0 ? "Original" : "Final");
 
133
        for ( ; ptr->value != NULL || ptr->address != NULL; ptr++ ) {
 
134
            if ( (path = ptr->value) == NULL ) {
 
135
                path = *ptr->address;
 
136
                fprintf(stderr, " pointer: %s\n", path);
 
137
            } else fprintf(stderr, " array[%d]: %s\n", ptr->length, path);
 
138
            if ( level == 0 && *path == '/' )
 
139
                fprintf(stderr, "  WARNING - absolute path\n");
 
140
        }   /* End for */
 
141
    }   /* End if */
 
142
 
 
143
}   /* End of DWBdebug */
 
144
 
 
145
/*****************************************************************************/
 
146
 
 
147
extern  char    *unsharp(char*);
 
148
 
 
149
char *DWBhome(void)
 
150
{
 
151
 
 
152
    FILE        *fp;
 
153
    char        *ptr;
 
154
    char        *path;
 
155
    int         len;
 
156
    char        buf[200];
 
157
    char        *home = NULL;
 
158
 
 
159
/*
 
160
 *
 
161
 * Return the DWB home directory. Uses the last definition of DWBENV
 
162
 * (usually "DWBHOME") in file DWBCONFIG (perhaps /usr/lib/dwb3.4) or
 
163
 * the value assigned to the variable named by the DWBENV string in
 
164
 * the environment if DWBCONFIG doesn't exist or doesn't define DWBENV.
 
165
 * Skips the file lookup if DWBCONFIG can't be read. Returns NULL if
 
166
 * there's no home directory.
 
167
 *
 
168
 */
 
169
 
 
170
    if ( (fp = fopen(DWBCONFIG, "r")) != NULL ) {
 
171
        len = strlen(DWBENV);
 
172
        while ( fgets(buf, sizeof(buf), fp) != NULL ) {
 
173
            for ( ptr = buf; isspace((uchar)*ptr); ptr++ ) ;
 
174
            if ( strncmp(ptr, DWBENV, len) == 0 && *(ptr+len) == '=' ) {
 
175
                path = ptr + len + 1;
 
176
                for ( ptr = path; !isspace((uchar)*ptr) && *ptr != ';'; ptr++ ) ;
 
177
                *ptr = '\0';
 
178
                if ( home != NULL )
 
179
                    free(home);
 
180
                if ( (home = malloc(strlen(path)+1)) != NULL )
 
181
                    strcpy(home, path);
 
182
            }   /* End if */
 
183
        }   /* End while */
 
184
        fclose(fp);
 
185
    }   /* End if */
 
186
 
 
187
    if ( home == NULL ) {
 
188
        if ( (home = getenv(DWBENV)) == NULL ) {
 
189
            if ( (home = DWBHOME) == NULL || *home == '\0' || *home == ' ' )
 
190
                home = NULL;
 
191
        }   /* End if */
 
192
        home = unsharp(home);
 
193
    }   /* End if */
 
194
 
 
195
    while (home && *home == '/' && *(home +1) == '/')   /* remove extra slashes */
 
196
        home++;
 
197
    return(home);
 
198
 
 
199
}   /* End of DWBhome */
 
200
 
 
201
/*****************************************************************************/
 
202
 
 
203
void DWBinit(char *prog, dwbinit *paths)
 
204
{
 
205
 
 
206
    char        *prefix;
 
207
    char        *value;
 
208
    char        *path;
 
209
    int         plen;
 
210
    int         length;
 
211
    dwbinit     *opaths = paths;
 
212
 
 
213
/*
 
214
 *
 
215
 * Adjust the pathnames listed in paths, using the home directory
 
216
 * returned by DWBhome(). Stops when it reaches an element that has
 
217
 * NULL address and value fields. Assumes pathnames are relative,
 
218
 * but changes everything. DWBdebug issues a warning if an original
 
219
 * path begins with a /.
 
220
 *
 
221
 * A non-NULL address refers to a pointer, which is reallocated and
 
222
 * then reinitialized. A NULL address implies a non-NULL value field
 
223
 * and describes a character array that we only reinitialize. The
 
224
 * length field for an array is the size of that array. The length
 
225
 * field of a pointer is an increment that's added to the length
 
226
 * required to store the new pathname string - should help when we
 
227
 * want to change character arrays to pointers in applications like
 
228
 * troff.
 
229
 *
 
230
 */
 
231
 
 
232
    if ( (prefix = DWBhome()) == NULL ) {
 
233
        fprintf(stderr, "%s: no DWB home directory\n", prog);
 
234
        exit(1);
 
235
    }   /* End if */
 
236
 
 
237
    DWBdebug(opaths, 0);
 
238
    plen = strlen(prefix);
 
239
 
 
240
    for ( ; paths->value != NULL || paths->address != NULL; paths++ ) {
 
241
        if ( paths->address == NULL ) {
 
242
            length = 0;
 
243
            value = paths->value;
 
244
        } else {
 
245
            length = paths->length;
 
246
            value = *paths->address;
 
247
        }   /* End else */
 
248
 
 
249
        length += plen + 1 + strlen(value);     /* +1 is for the '/' */
 
250
 
 
251
        if ( (path = malloc(length+1)) == NULL ) {
 
252
            fprintf(stderr, "%s: can't allocate pathname memory\n", prog);
 
253
            exit(1);
 
254
        }   /* End if */
 
255
 
 
256
        if ( *value != '\0' ) {
 
257
            char *eop = prefix;
 
258
            while(*eop++)
 
259
                ;
 
260
            eop -= 2;
 
261
            if (*value != '/' && *eop != '/') {
 
262
                sprintf(path, "%s/%s", prefix, value);
 
263
            } else if (*value == '/' && *eop == '/') {
 
264
                value++;
 
265
                sprintf(path, "%s%s", prefix, value);
 
266
            } else
 
267
                sprintf(path, "%s%s", prefix, value);
 
268
        } else
 
269
                sprintf(path, "%s", prefix);
 
270
 
 
271
        if ( paths->address == NULL ) {
 
272
            if ( strlen(path) >= paths->length ) {
 
273
                fprintf(stderr, "%s: no room for %s\n", prog, path);
 
274
                exit(1);
 
275
            }   /* End if */
 
276
            strcpy(paths->value, path);
 
277
            free(path);
 
278
        } else *paths->address = path;
 
279
    }   /* End for */
 
280
 
 
281
    DWBdebug(opaths, 1);
 
282
 
 
283
}   /* End of DWBinit */
 
284
 
 
285
/*****************************************************************************/
 
286
 
 
287
void DWBprefix( char *prog, char *path, int length)
 
288
{
 
289
 
 
290
    char        *home;
 
291
    char        buf[512];
 
292
    int         len = strlen(DWBPREFIX);
 
293
 
 
294
/*
 
295
 *
 
296
 * Replace a leading DWBPREFIX string in path by the current DWBhome().
 
297
 * Used by programs that pretend to handle .so requests. Assumes path
 
298
 * is an array with room for length characters. The implementation is
 
299
 * not great, but should be good enough for now. Also probably should
 
300
 * have DWBhome() only do the lookup once, and remember the value if
 
301
 * called again.
 
302
 * 
 
303
 */
 
304
 
 
305
    if ( strncmp(path, DWBPREFIX, len) == 0 ) {
 
306
        if ( (home = DWBhome()) != NULL ) {
 
307
            if ( strlen(home) + strlen(path+len) < length ) {
 
308
                sprintf(buf, "%s%s", home, path+len);
 
309
                strcpy(path, buf);              /* assuming there's room in path */
 
310
            } else fprintf(stderr, "%s: no room to grow path %s", prog, path);
 
311
        }   /* End if */
 
312
    }   /* End if */
 
313
 
 
314
}   /* End of DWBprefix */
 
315
 
 
316
/*****************************************************************************/
 
317