1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5extern char *rindex (const char *, int);	/* not always in <string.h> */
6
7#include "defs.h"
8#include "manfile.h"
9#include "man-config.h"
10#include "to_cat.h"
11#include "util.h"
12
13/*
14 * Given PATH/man1/name.1, return a pointer to the '/' following PATH.
15 */
16static char *
17mantail_of(char *name) {
18     char *s0, *s1, *s;
19
20     s0 = s1 = 0;
21     for (s = name; *s; s++) {
22	     if (*s == '/') {
23		     s0 = s1;
24		     s1 = s;
25	     }
26     }
27     return s0;
28}
29
30/*
31 * Given PATH/man1/name.1, return PATH, newly allocated.
32 * The argument must be writable, not a constant string.
33 */
34const char *
35mandir_of(const char *name) {
36     char *p, *q;
37
38     q = my_strdup(name);
39     p = mantail_of(q);
40     if (p) {
41	  *p = 0;
42	  return q;
43     }
44     free(q);
45     return NULL;
46}
47
48/*
49 * Change a name of the form PATH/man1/name.1[.Z]
50 *                      into PATH/cat1/name.1.EXT
51 * or (FSSTND) change /usr/PA/man/PB/man1/name.1
52 *               into /var/catman/PA/PB/cat1/name.1.EXT
53 * or (FHS) change /usr/PATH/share/man/LOC/man1/name.1
54 *            into /var/cache/man/PATH/LOC/cat1/name.1.EXT
55 * (here the /LOC part is absent or a single [locale] dir).
56 *
57 * Returns 0 on failure.
58 */
59
60const char *
61convert_to_cat (const char *name0, const char *ext, int standards) {
62     char *name, *freename, *cat_name = 0;
63     char *t0, *t2, *t3, *t4;
64     struct dirs *dlp;
65     int len;
66
67     freename = name = my_strdup (name0);
68
69     t0 = rindex (name, '.');
70     if (t0 && get_expander(t0)) /* remove compressee extension */
71	  *t0 = 0;
72
73     t2 = mantail_of (name);
74     if (t2 == NULL)
75	  return 0;
76     *t2 = 0;			/* remove man1/name.1 part */
77
78     if (strncmp(t2+1, "man", 3) != 0)
79	  return 0;
80     t2[1] = 'c';
81     t2[3] = 't';
82
83     len = (ext ? strlen(ext) : 0);
84
85     /* Explicitly given cat file? */
86     for (dlp = cfdirlist.nxt; dlp; dlp = dlp->nxt) {
87	  if (!strcmp (name, dlp->mandir)) {
88	       if (!dlp->catdir[0])
89		    break;
90	       *t2 = '/';
91	       len += strlen (dlp->catdir) + strlen (t2) + 1;
92	       cat_name = (char *) my_malloc (len);
93	       strcpy (cat_name, dlp->catdir);
94	       strcat (cat_name, t2);
95	       goto gotit;
96	  }
97     }
98
99     if (standards & FHS) {
100	  if (*name != '/')
101	       return 0;
102
103	  /* possibly strip locale part */
104	  t3 = t2;
105	  if ((t4 = rindex(name,'/')) != NULL && strcmp(t4, "/man")) {
106	       *t3 = '/';
107	       t3 = t4;
108	       *t3 = 0;
109	  }
110
111	  if(t3 - name >= 4 && !strcmp(t3 - 4, "/man")) {
112	       /* fhs is applicable; strip leading /usr and trailing share */
113	       if(!strncmp(name, "/usr/", 5))
114	            name += 4;
115	       t4 = t3 - 4;
116	       *t4 = 0;
117	       if(t4 - name >= 6 && !strcmp(t4 - 6, "/share"))
118		    t4[-6] = 0;
119	       *t3 = '/';
120
121	       len += strlen("/var/cache/man") + strlen(name) + strlen(t3) + 1;
122	       cat_name = (char *) my_malloc (len);
123	       strcpy (cat_name, "/var/cache/man");
124	       strcat (cat_name, name);
125	       strcat (cat_name, t3);
126	       goto gotit;
127	  }
128
129	  return 0;
130     }
131
132     if ((standards & FSSTND) && !strncmp(name, "/usr/", 5)) {
133	  /* search, starting at the end, for a part `man' to delete */
134	  t3 = t2;
135	  while ((t4 = rindex(name, '/')) != NULL && strcmp(t4, "/man")) {
136	       *t3 = '/';
137	       t3 = t4;
138	       *t3 = 0;
139	  }
140	  *t3 = '/';
141	  if (t4) {
142	       *t4 = 0;
143	       len += strlen("/var/catman") + strlen (name+4) + strlen (t3) + 1;
144	       cat_name = (char *) my_malloc (len);
145	       strcpy (cat_name, "/var/catman");
146	       strcat (cat_name, name+4);
147	       strcat (cat_name, t3);
148	       goto gotit;
149	  }
150     } else
151	  *t2 = '/';
152
153     if (ext) {			/* allocate room for extension */
154	  len += strlen(name) + 1;
155	  cat_name = (char *) my_malloc (len);
156	  strcpy (cat_name, name);
157     } else
158	  cat_name = name;
159
160gotit:
161
162     if ((standards & DO_HP) && get_expander(cat_name)) {
163	  /* nothing - we have cat1.Z/file.1 */
164     } else if (ext)
165	  strcat (cat_name, ext);
166
167     if (name != cat_name)
168	  free (freename);
169
170     return cat_name;
171}
172