1 /* util2.c
2 */
3 /* This software is copyrighted as detailed in the LICENSE file. */
4
5
6 #include "EXTERN.h"
7 #include "common.h"
8 #include "list.h"
9 #include "hash.h"
10 #include "ngdata.h"
11 #include "nntpclient.h"
12 #include "datasrc.h"
13 #include "nntp.h"
14 #include "nntpauth.h"
15 #include "util.h"
16 #include "util3.h"
17 #include "INTERN.h"
18 #include "util2.h"
19
20 #ifdef TILDENAME
21 static char* tildename = NULL;
22 static char* tildedir = NULL;
23 #endif
24
25 /* copy a string to a safe spot */
26
27 char*
savestr(str)28 savestr(str)
29 char* str;
30 {
31 register char* newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
32
33 strcpy(newaddr,str);
34 return newaddr;
35 }
36
37 /* safe version of string copy */
38
39 char*
safecpy(to,from,len)40 safecpy(to,from,len)
41 char* to;
42 register char* from;
43 register int len;
44 {
45 register char* dest = to;
46
47 if (from) {
48 while (--len && *from)
49 *dest++ = *from++;
50 }
51 *dest = '\0';
52
53 return to;
54 }
55
56 /* copy a string up to some (non-backslashed) delimiter, if any */
57
58 char*
cpytill(to,from,delim)59 cpytill(to,from,delim)
60 register char* to;
61 register char* from;
62 register int delim;
63 {
64 while (*from) {
65 if (*from == '\\' && from[1] == delim)
66 from++;
67 else if (*from == delim)
68 break;
69 *to++ = *from++;
70 }
71 *to = '\0';
72 return from;
73 }
74
75 /* expand filename via %, ~, and $ interpretation */
76 /* returns pointer to static area */
77 /* Note that there is a 1-deep cache of ~name interpretation */
78
79 char*
filexp(s)80 filexp(s)
81 register char* s;
82 {
83 static char filename[CBUFLEN];
84 char scrbuf[CBUFLEN];
85 register char* d;
86
87 #ifdef DEBUG
88 if (debug & DEB_FILEXP)
89 printf("< %s\n",s) FLUSH;
90 #endif
91 /* interpret any % escapes */
92 dointerp(filename,sizeof filename,s,(char*)NULL,(char*)NULL);
93 #ifdef DEBUG
94 if (debug & DEB_FILEXP)
95 printf("%% %s\n",filename) FLUSH;
96 #endif
97 s = filename;
98 if (*s == '~') { /* does destination start with ~? */
99 if (!*(++s) || *s == '/') {
100 sprintf(scrbuf,"%s%s",homedir,s);
101 /* swap $HOME for it */
102 #ifdef DEBUG
103 if (debug & DEB_FILEXP)
104 printf("~ %s\n",scrbuf) FLUSH;
105 #endif
106 strcpy(filename,scrbuf);
107 }
108 else if (*s == '~' && (!s[1] || s[1] == '/')) {
109 d = getenv("TRNPREFIX");
110 if (!d)
111 d = INSTALLPREFIX;
112 sprintf(scrbuf,"%s%s",d,s+1);
113 #ifdef DEBUG
114 if (debug & DEB_FILEXP)
115 printf("~~ %s\n",scrbuf) FLUSH;
116 #endif
117 }
118 else {
119 #ifdef TILDENAME
120 for (d = scrbuf; isalnum(*s); s++, d++) *d = *s;
121 *d = '\0';
122 if (tildedir && strEQ(tildename,scrbuf)) {
123 strcpy(scrbuf,tildedir);
124 strcat(scrbuf, s);
125 strcpy(filename, scrbuf);
126 #ifdef DEBUG
127 if (debug & DEB_FILEXP)
128 printf("r %s %s\n",tildename,tildedir) FLUSH;
129 #endif
130 }
131 else {
132 if (tildename)
133 free(tildename);
134 if (tildedir)
135 free(tildedir);
136 tildedir = NULL;
137 tildename = savestr(scrbuf);
138 #ifdef HAS_GETPWENT /* getpwnam() is not the paragon of efficiency */
139 {
140 struct passwd* pwd = getpwnam(tildename);
141 if (pwd == NULL) {
142 printf("%s is an unknown user. Using default.\n",tildename) FLUSH;
143 return NULL;
144 }
145 sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
146 tildedir = savestr(pwd->pw_dir);
147 strcpy(filename,scrbuf);
148 endpwent();
149 }
150 #else /* this will run faster, and is less D space */
151 { /* just be sure LOGDIRFIELD is correct */
152 FILE* pfp = fopen(filexp(PASSFILE),"r");
153 char tmpbuf[512];
154 int i;
155
156 if (pfp) {
157 while (fgets(tmpbuf,512,pfp) != NULL) {
158 d = cpytill(scrbuf,tmpbuf,':');
159 #ifdef DEBUG
160 if (debug & DEB_FILEXP)
161 printf("p %s\n",tmpbuf) FLUSH;
162 #endif
163 if (strEQ(scrbuf,tildename)) {
164 for (i=LOGDIRFIELD-2; i; i--) {
165 if (d)
166 d = index(d+1,':');
167 }
168 if (d) {
169 cpytill(scrbuf,d+1,':');
170 tildedir = savestr(scrbuf);
171 strcat(scrbuf,s);
172 strcpy(filename,scrbuf);
173 }
174 break;
175 }
176 }
177 fclose(pfp);
178 }
179 if (!tildedir) {
180 printf("%s is an unknown user. Using default.\n",tildename) FLUSH;
181 return NULL;
182 }
183 }
184 #endif
185 }
186 #else /* !TILDENAME */
187 #ifdef VERBOSE
188 IF(verbose)
189 fputs("~loginname not implemented.\n",stdout) FLUSH;
190 ELSE
191 #endif
192 #ifdef TERSE
193 fputs("~login not impl.\n",stdout) FLUSH;
194 #endif
195 #endif
196 }
197 }
198 else if (*s == '$') { /* starts with some env variable? */
199 d = scrbuf;
200 *d++ = '%';
201 if (s[1] == '{')
202 strcpy(d,s+2);
203 else {
204 *d++ = '{';
205 for (s++; isalnum(*s); s++) *d++ = *s;
206 /* skip over token */
207 *d++ = '}';
208 strcpy(d,s);
209 }
210 #ifdef DEBUG
211 if (debug & DEB_FILEXP)
212 printf("$ %s\n",scrbuf) FLUSH;
213 #endif
214 /* this might do some extra '%'s, but that's how the Mercedes Benz */
215 dointerp(filename,sizeof filename,scrbuf,(char*)NULL,(char*)NULL);
216 }
217 #ifdef DEBUG
218 if (debug & DEB_FILEXP)
219 printf("> %s\n",filename) FLUSH;
220 #endif
221 return filename;
222 }
223
224 /* return ptr to little string in big string, NULL if not found */
225
226 char*
instr(big,little,case_matters)227 instr(big, little, case_matters)
228 char* big;
229 char* little;
230 bool_int case_matters;
231 {
232 register char* t;
233 register char* s;
234 register char* x;
235
236 for (t = big; *t; t++) {
237 for (x=t,s=little; *s; x++,s++) {
238 if (!*x)
239 return NULL;
240 if (case_matters == TRUE) {
241 if (*s != *x)
242 break;
243 } else {
244 register char c,d;
245 if (isupper(*s))
246 c = tolower(*s);
247 else
248 c = *s;
249 if (isupper(*x))
250 d = tolower(*x);
251 else
252 d = *x;
253 if ( c != d )
254 break;
255 }
256 }
257 if (!*s)
258 return t;
259 }
260 return NULL;
261 }
262
263 #ifndef HAS_STRCASECMP
264 static Uchar casemap[256] = {
265 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
266 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
267 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
268 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
269 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
270 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
271 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
272 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
273 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
274 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
275 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
276 0x78,0x79,0x7A,0x7B,0x5C,0x5D,0x5E,0x5F,
277 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
278 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
279 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
280 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
281 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
282 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
283 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
284 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
285 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
286 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
287 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
288 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
289 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
290 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
291 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
292 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
293 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
294 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
295 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
296 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
297 };
298 #endif
299
300 #ifndef HAS_STRCASECMP
301 int
trn_casecmp(s1,s2)302 trn_casecmp(s1, s2)
303 register char* s1;
304 register char* s2;
305 {
306 do {
307 if (casemap[(Uchar)*s1++] != casemap[(Uchar)*s2])
308 return casemap[(Uchar)s1[-1]] - casemap[(Uchar)*s2];
309 } while (*s2++ != '\0');
310 return 0;
311 }
312 #endif
313
314 #ifndef HAS_STRCASECMP
315 int
trn_ncasecmp(s1,s2,len)316 trn_ncasecmp(s1, s2, len)
317 register char* s1;
318 register char* s2;
319 register int len;
320 {
321 while (len--) {
322 if (casemap[(Uchar)*s1++] != casemap[(Uchar)*s2])
323 return casemap[(Uchar)s1[-1]] - casemap[(Uchar)*s2];
324 if (*s2++ == '\0')
325 break;
326 }
327 return 0;
328 }
329 #endif
330
331 #ifdef SUPPORT_NNTP
332 char*
read_auth_file(file,pass_ptr)333 read_auth_file(file, pass_ptr)
334 char* file;
335 char** pass_ptr;
336 {
337 FILE* fp;
338 char* strptr[2];
339 char buf[1024];
340 strptr[0] = strptr[1] = NULL;
341 if ((fp = fopen(file,"r")) != NULL) {
342 int i;
343 for (i = 0; i < 2; i++) {
344 if (fgets(buf, sizeof buf, fp) != NULL) {
345 char* cp = buf + strlen(buf) - 1;
346 if (*cp == '\n')
347 *cp = '\0';
348 strptr[i] = savestr(buf);
349 }
350 }
351 fclose(fp);
352 }
353 *pass_ptr = strptr[1];
354 return strptr[0];
355 }
356 #endif
357
358 #ifdef MSDOS
359 int
ChDir(path)360 ChDir(path)
361 char* path;
362 {
363 if (isalpha(*path) && path[1] == ':') {
364 setdisk(path[0]&0x1f);
365 path += 2;
366 }
367 #undef chdir
368 return chdir(path);
369 }
370 #endif
371
372 #ifdef MSDOS
373 int
getuid()374 getuid()
375 {
376 return 2;
377 }
378 #endif
379