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