4556427 [rkeene@sledge /home/rkeene/devel/dact-0.8.37]$ cat -n parse.c
  1 /*
  2  * Copyright (C) 2001, 2002, and 2003  Roy Keene
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU General Public License
  6  * as published by the Free Software Foundation; either version 2
  7  * of the License, or (at your option) any later version.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU General Public License
 15  * along with this program; if not, write to the Free Software
 16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 17  *
 18  *      email: dact@rkeene.org
 19  */
 20 
 21 /*
 22     Help, my atoi() is broken.
 23 */
 24 
 25 #include "dact.h"
 26 #ifdef HAVE_SYS_UTSNAME_H
 27 #include <sys/utsname.h>
 28 #endif
 29 #ifdef HAVE_SYS_TYPES_H
 30 #include <sys/types.h>
 31 #endif
 32 #include <dirent.h>
 33 #ifdef HAVE_STRING_H
 34 #include <string.h>
 35 #endif
 36 #ifdef HAVE_UNISTD_H
 37 #include <unistd.h>
 38 #endif
 39 #ifdef HAVE_STDLIB_H
 40 #include <stdlib.h>
 41 #endif
 42 #include <stdio.h>
 43 #include <ctype.h>
 44 #include <math.h>
 45 #include "buffer.h"
 46 #include "parse.h"
 47 #include "crc.h"
 48 #include "ui.h"
 49 
 50 uint32_t atoi2(const char *n) {
 51     uint32_t retval=0;
 52     int i,m;
 53     if (n==NULL) return(0);
 54     m=strcspn(n,".");
 55     for (i=0;i<m;i++) retval+=(n[i]-48)*pow(10,m-i-1);
 56     return(retval);
 57 }
 58 
 59 /* Parse those stupid netscape-style URLs, icky. 
 60  * And I know this REALLY crummy looking, but it works
 61  * (albeit, probably not perfectly) suffciently well.
 62  *  -- Roy Keene <rkeene@Rkeene.org>
 63  * `scheme'     will never exceed 5 bytes
 64  * `username'   will never exceed 128 bytes
 65  * `password'   will never exceed 128 bytes
 66  * `host'       will never exceed 512 bytes
 67  * `file'       will never exceed 1024 bytes
 68  */
 69 int parse_url(const char *url, char *scheme, char *username, char *password, char *host, int *port, unsigned char *file)
	{
 70     char *local_url=NULL, *local_url_s, *fbuf;
 71     int i;
 72 
 73     if (strstr(url,"://")==NULL) {  /* Make sure we have an URL */
 74         strncpy(file,url,1023);
 75         return(1);
 76     };
 77 
 78     local_url_s=local_url=strdup(url);
 79 
 80     *port=0;
 81     file[1]=0;
 82 
 83     strncpy(scheme,strsep(&local_url,":"),5);
 84     local_url+=2;
 85     strncpy(host,strsep(&local_url,"/"),512);
 86     if (local_url!=NULL) strncpy(file+1,local_url,1022);
 87     file[0]='/';
 88 
 89     fbuf=malloc(1024);
 90     file[0]='/';
 91     fbuf[0]='\0';
 92     for (i=0;i<strlen(file);i++) {
 93         if ((strlen(fbuf)+4)>=1023) break;
 94         if (file[i]<33 || file[i]>127) {
 95             if (file[i]==32) { strcat(fbuf, "+"); } else { sprintf(fbuf, "%s%%%02x", fbuf, file[i]); }
 96         } else {
 97             sprintf(fbuf, "%s%c", fbuf, file[i]);
 98         }
 99     }
100     strncpy(file, fbuf, 1023);
101     file[1023]=0;
102     free(fbuf);
103 
104 
105     password[0]=0;
106     if (strchr(host,'@')!=NULL) {
107         local_url=local_url_s; /* Doh!  This was missing. */
108         strcpy(local_url,host);
109         strncpy(username,strsep(&local_url,"@:"),128);
110         if (strchr(local_url,'@')!=NULL)
111             strncpy(password,strsep(&local_url,"@"),128);
112         strcpy(host,local_url);
113     } else {
114         strcpy(username,"");
115     }
116 
117     if (strchr(host,':')!=NULL) {
118         local_url=local_url_s;
119         strcpy(local_url,host);
120         strcpy(host,strsep(&local_url,":"));
121         *port=atoi(local_url);
122     } else {
123         if (!strcasecmp(scheme,"http")) *port=80;
124         if (!strcasecmp(scheme,"ftp")) *port=21;
125     }
126 
127     free(local_url_s);
128     strtolower(scheme);
129     return(0);
130 }
131 
132 
133 /*
134     Replace 
135         @@HOME@@    Home directory (getenv("HOME"))
136         @@OSNM@@    OS Name (linux, freebsd, sunos, etc)
137         @@OSVR@@    OS version (2.2.x, 4.2, 5.8, etc)
138         @@OSVS@@    OS version (short) (2.2, 4.2, 5.8, etc)
139         @@ARCH@@    Arch (i386, sparc64, sun4u, sun4m, etc)
140         @@DIST@@    If OSNM=Linux, distribution of Linux.
141         @@FILE@@    Name of compressed file.
142         @@DTVR@@    Version of DACT (maj.min.rev)
143         @@DTVS@@    Version of DACT (short) (maj.min)
144         @@DTID@@    DACT identifier (dact-maj.min.rev-(dev|rel)-(no)modules-(no)debian-(no)network-(no)vercheck)
145         @@PASS@@    Prompt for Password
146         @@USER@@    Prompt for Username
147         @@ATSN@@    Put an `@'
148 */
149 char *parse_url_subst(const char *src, const char *fname) {
150     static struct utsname system_info;
151     static int sysinfo_init=0;
152     uint32_t cmd=0, x, strsz;
153     const char *loc=src, *ploc=loc;
154     char *ret, *ret_s, found=0, *smbuf;
155 
156     if (!strstr((char *) src,"@@")) return(strdup(src));
157 
158     ret_s=ret=calloc(1024,1);
159 
160     if (!sysinfo_init) {
161         uname(&system_info);
162         strtolower(system_info.sysname);
163         strtolower(system_info.machine);
164         sysinfo_init=1;
165     }
166 
167 
168     while (strstr(loc,"@@")) {
169         cmd=ELFCRC(0, loc=strstr(loc, "@@")+2, 4);
170         loc+=6;
171 
172         strsz=(loc-ploc-8);
173         memcpy(ret, ploc, strsz);
174         ret+=strsz;
175 
176         if ((ret-ret_s)>(1024-128)) break;
177 
178         switch (cmd) {
179             case 288376: /* ARCH-done */
180                 x=strlen(system_info.machine);
181                 if (x>127) break;
182                 memcpy(ret,system_info.machine,x);
183                 ret+=x;
184                 break;
185             case 346157: /* OSNM-done */
186                 x=strlen(system_info.sysname);
187                 if (x>127) break;
188                 memcpy(ret,system_info.sysname,x);
189                 ret+=x;
190                 break;
191             case 346290: /* OSVR-done */
192                 if (strlen(system_info.release)>127) break;
193                 for (x=0;x<strlen(system_info.release);x++) {
194                     if (isdigit((int) system_info.release[x]) || system_info.release[x]=='.') {
195                         ret[0]=system_info.release[x];
196                         ret++;
197                     } else {
198                         break;
199                     }
200                 }
201                 break;
202             case 346291: /* OSVS-done */
203                 if (strlen(system_info.release)>127) break;
204                 for (x=0;x<strlen(system_info.release);x++) {
205                     if (system_info.release[x]=='.' && found) break;
206                     if (system_info.release[x]=='.') found=1;
207                     if (isdigit((int) system_info.release[x]) || found) {
208                         ret[0]=system_info.release[x];
209                         ret++;
210                     }
211                 }
212                 break;
213             case 306693: /* FILE-done */
214                 x=strlen(fname);
215                 if (x>127) break;
216                 memcpy(ret,fname,x);
217                 ret+=x;
218                 break;
219             case 298628: /* DIST-done */
220                 if (!strcmp("linux",system_info.sysname)) {
221                     smbuf=parse_url_subst_dist();
222                     if (smbuf==NULL) break;
223                     x=strlen(smbuf);
224                     if (x>127) break;
225                     memcpy(ret, smbuf, x);
226                     ret+=x;
227                 }
228                 break;
229             case 301490: /* DTVR-done */
230                 smbuf=malloc(128);
231                 sprintf(smbuf, "%i.%i.%i", DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION);
232                 x=strlen(smbuf);
233                 memcpy(ret, smbuf, x);
234                 ret+=x;
235                 free(smbuf);
236                 break;
237             case 301491: /* DTVS-done */
238                 smbuf=malloc(128);
239                 sprintf(smbuf, "%i.%i", DACT_VER_MAJOR, DACT_VER_MINOR);
240                 x=strlen(smbuf);
241                 memcpy(ret, smbuf, x);
242                 ret+=x;
243                 free(smbuf);
244                 break;
245             case 345731: /* PASS-done */
246                 smbuf=dact_ui_getuserinput("Enter password: ", 128, 1);
247                 x=strlen(smbuf);
248                 if (x>127) break;
249                 memcpy(ret, smbuf, x);
250                 ret+=x;
251                 free(smbuf);
252                 break;
253             case 370594: /* USER-done */
254                 smbuf=dact_ui_getuserinput("Enter username: ", 128, 0);
255                 x=strlen(smbuf);
256                 if (x>127) break;
257                 memcpy(ret, smbuf, x);
258                 ret+=x;
259                 free(smbuf);
260                 break;
261             case 289150: /* ATSN-done */
262                 ret[0]='@';
263                 ret+=1;
264                 break;
265             case 316437: /* HOME-done*/
266                 if (!(smbuf=getenv("HOME"))) break;
267                 x=strlen(smbuf);
268                 if (x>127) break;
269                 memcpy(ret, smbuf, x);
270                 ret+=x;
271                 break;
272             case 301268: /* DTID */
273                 smbuf=malloc(128);
274                 sprintf(smbuf, "dact-%i.%i.%i-%s-%smodules-%sdebian-%snetwork-%svercheck", DACT_VER_MAJOR,
	DACT_VER_MINOR, DACT_VER_REVISION,
275 #ifdef DEBUG
276                     "dev",
277 #else
278                     "rel",
279 #endif
280 #ifdef USE_MODULES
281                     "",
282 #else
283                     "no",
284 #endif
285 #ifdef DACT_DEBIAN_UPGRADE_PROC
286                     "",
287 #else
288                     "no",
289 #endif
290 #ifndef NO_NETWORK
291                     "",
292 #else
293                     "no",
294 #endif
295 #ifdef CHECK_VERSION
296                     ""
297 #else
298                     "no"
299 #endif
300                     );
301                 x=strlen(smbuf);
302                 if (x>127) break;
303                 memcpy(ret, smbuf, x);
304                 ret+=x;
305                 break;
306 #ifdef DEBUG
307             default:
308                 PRINT_LINE; fprintf(stderr, "Unknown cmd (%i) [src=%s].\n",cmd,src);
309                 break;
310 #endif
311         }
312 
313         ploc=loc;
314     }
315 
316     memcpy(ret, loc, strlen(loc));
317 
318     return(ret_s);
319 }
320 
321 char *parse_url_subst_dist(void) {
322     DIR *dirfd=NULL;
323     struct dirent *info=NULL;
324     static char retbuf[128]="unknown";
325     char *buf;
326 
327 /*
328     Round 1: check for /etc/DISTRIBUTION-version or /etc/DISTRIBUTION-release
329 */
330     dirfd=opendir("/etc/.");
331     while ((info=readdir(dirfd)) != NULL) {
332         if ((buf=strstr(info->d_name,"-version"))!=NULL) {
333             buf[0]=0;
334             strncpy(retbuf, info->d_name, sizeof(retbuf));
335             return(retbuf);
336         }
337         if ((buf=strstr(info->d_name,"_version"))!=NULL) {
338             buf[0]=0;
339             strncpy(retbuf, info->d_name, sizeof(retbuf));
340             return(retbuf);
341         }
342         if ((buf=strstr(info->d_name,"-release"))!=NULL) {
343             buf[0]=0;
344             strncpy(retbuf, info->d_name, sizeof(retbuf));
345             return(retbuf);
346         }
347     }
348 
349 /*
350     Round 2: ??? (distinguish between older versions of Slackware
351         and Unknown distributions..)
352 */
353 
354     return(retbuf);
355 }
356 
357 
358 void strtolower(char *str) {
359     uint32_t x=0;
360 
361     while (str[x]) { str[x]=tolower(str[x]); x++; }
362 }
363 
364 char *mime64(unsigned char *str) {
365     int x=strlen(str);
366     return(mimes64(str,&x));
367 }
368 
369 
370 char *mimes64(unsigned char *str, int *size) {
371     char *ret;
372     char mimeabet[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
373     int i=0, x=0, m, bit_buf_sze;
374     uint32_t bit_buf_sto;
375 
376     bit_buf_sze=bit_buffer_size(); /* Save the bit buffer, in case in use */
377     bit_buf_sto=bit_buffer_read(bit_buf_sze);
378 
379     if ((ret=malloc((int) ((((float)(*size))*1.5)+7)))==NULL) return(NULL);
380 
381     while (i<(*size)) {
382         while (bit_buffer_size()>=6) ret[x++]=mimeabet[bit_buffer_read(6)];
383         if ((bit_buffer_size()+8)<=32) bit_buffer_write(str[i++],8);
384     }
385     while (bit_buffer_size()>=6) ret[x++]=mimeabet[bit_buffer_read(6)];
386     if ((m=bit_buffer_size())) ret[x++]=mimeabet[bit_buffer_read(m)<<(6-m)];
387     while (x&3) ret[x++]='=';
388 
389     bit_buffer_write(bit_buf_sto, bit_buf_sze); /* Restore it */
390 
391     *size=x;
392 
393     ret[x]='\0';
394 
395     return(ret);
396 }
397 
398 char *demime64(unsigned char *str) {
399     char *ret;
400     char mimeabet[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
401     int i=0, x=0, m, bit_buf_sze;
402     uint32_t bit_buf_sto;
403 
404     bit_buf_sze=bit_buffer_size(); /* Save the bit buffer, in case in use */
405     bit_buf_sto=bit_buffer_read(bit_buf_sze);
406 
407     if ((ret=malloc((int) ((((float)strlen(str))*0.75)+6)))==NULL) return(NULL);
408 
409     while (i<strlen(str)) {
410         if (str[i]=='=') break;
411         while (bit_buffer_size()>=8) ret[x++]=bit_buffer_read(8);
412         if ((bit_buffer_size()+6)<=32) bit_buffer_write(strchr(mimeabet,str[i++])-mimeabet,6);
413     }
414     while (bit_buffer_size()>=8) ret[x++]=bit_buffer_read(8);
415     if ((m=bit_buffer_size())) ret[x++]=bit_buffer_read(m)<<(8-m);
416 
417     bit_buffer_write(bit_buf_sto, bit_buf_sze); /* Restore it */
418 
419     return(ret);
420 }
421 
422 
423 int32_t read_f(int fd, void *buf, size_t count) {
424     int32_t i=0,x;
425 
426     while (i!=count) {
427         x=read(fd,(void *) (((char *) buf)+i),count-i);
428         if (x==0) break;
429 /* Damn typos, read_f was broken here because x<0 was typed as x>0 */
430         if (x<0) return(x);
431         i+=x;
432     }
433 
434     return(i);
435 }
436 
437 uint32_t hash_fourbyte(unsigned char *str, const char term) {
438     uint32_t ret=0;
439     int i;
440 
441     for (i=0;i<4;i++) {
442         if (!str[i] || str[i]==term) break;
443         ret+=(str[i]<<(i*8));
444     }
445     return(ret);
446 }
4556428 [rkeene@sledge /home/rkeene/devel/dact-0.8.37]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-04-04 07:01:53