5747686 [rkeene@sledge /home/rkeene/devel/libopennet-0.8.1]$ cat -n parse.c
  1 /*
  2     Help, my atoi() is broken.
  3 */
  4 
  5 #include <sys/utsname.h>
  6 #include <sys/types.h>
  7 #include <dirent.h>
  8 #include <string.h>
  9 #include <unistd.h>
 10 #include <stdlib.h>
 11 #include <stdio.h>
 12 #include <ctype.h>
 13 #include <math.h>
 14 #include "conf.h"
 15 #include "buffer.h"
 16 #include "parse.h"
 17 #include "crc.h"
 18 
 19 uint32_t atoi2(const char *n) {
 20     uint32_t retval=0;
 21     int i,m;
 22     if (n==NULL) return(0);
 23     m=strcspn(n,".");
 24     for (i=0;i<m;i++) retval+=(n[i]-48)*pow(10,m-i-1);
 25     return(retval);
 26 }
 27 
 28 /* Parse those stupid netscape-style URLs, icky. 
 29  * And I know this REALLY crummy looking, but it works
 30  * (albeit, probably not perfectly) suffciently well.
 31  *  -- Roy Keene <rkeene@Rkeene.org>
 32  * `scheme'     will never exceed 5 bytes
 33  * `username'   will never exceed 128 bytes
 34  * `password'   will never exceed 128 bytes
 35  * `host'       will never exceed 512 bytes
 36  * `file'       will never exceed 1024 bytes
 37  */
 38 int parse_url(const char *url, char *scheme, char *username, char *password, char *host, int *port, char *file) {
 39     char *local_url=NULL, *local_url_s;
 40 
 41     if (strstr(url,"://")==NULL) {  /* Make sure we have an URL */
 42         strncpy(file,url,1023);
 43         return(1);
 44     };
 45 
 46     local_url_s=local_url=parse_url_subst(url);
 47 
 48     *port=0;
 49     file[1]=0;
 50 
 51     strncpy(scheme,strsep(&local_url,":"),5);
 52     local_url+=2;
 53     strncpy(host,strsep(&local_url,"/"),512);
 54     if (local_url!=NULL) strncpy(file+1,local_url,1022);
 55     file[0]='/';
 56 
 57     password[0]=0;
 58     if (strchr(host,'@')!=NULL) {
 59         local_url=local_url_s; /* Doh!  This was missing. */
 60         strcpy(local_url,host);
 61         strncpy(username,strsep(&local_url,"@:"),128);
 62         if (strchr(local_url,'@')!=NULL)
 63             strncpy(password,strsep(&local_url,"@"),128);
 64         strcpy(host,local_url);
 65     } else {
 66         strcpy(username,"");
 67     }
 68 
 69     if (strchr(host,':')!=NULL) {
 70         local_url=local_url_s;
 71         strcpy(local_url,host);
 72         strcpy(host,strsep(&local_url,":"));
 73         *port=atoi(local_url);
 74     } else {
 75         if (!strcasecmp(scheme,"http")) *port=80;
 76         if (!strcasecmp(scheme,"ftp")) *port=21;
 77     }
 78 
 79     free(local_url_s);
 80     strtolower(scheme);
 81     return(0);
 82 }
 83 
 84 
 85 /*
 86     Replace 
 87         @@OSNM@@    OS Name (linux, freebsd, sunos, etc)
 88         @@OSVR@@    OS version (2.2.x, 4.2, 5.8, etc)
 89         @@OSVS@@    OS version (short) (2.2, 4.2, 5.8, etc)
 90         @@ARCH@@    Arch (i386, sparc64, sun4u, sun4m, etc)
 91         @@DIST@@    If OSNM=Linux, distribution of Linux.
 92         @@ATSN@@    Put an `@'
 93 */
 94 char *parse_url_subst(const char *src) {
 95     struct utsname system_info;
 96     uint32_t cmd=0, x, strsz;
 97     const char *loc=src, *ploc=loc;
 98     char *ret, *ret_s, found=0, *smbuf;
 99 
100     if (!strstr((char *) src,"@@")) return(strdup(src));
101 
102     ret_s=ret=calloc(1024,1);
103 
104     uname(&system_info);
105 
106     strtolower(system_info.sysname);
107     strtolower(system_info.machine);
108 
109     while (strstr(loc,"@@")) {
110         cmd=ELFCRC(0, loc=strstr(loc, "@@")+2, 4);
111         loc+=6;
112 
113         strsz=(loc-ploc-8);
114         memcpy(ret, ploc, strsz);
115         ret+=strsz;
116 
117         if ((ret-ret_s)>(1024-128)) break;
118 
119         switch (cmd) {
120             case 288376: /* ARCH-done */
121                 x=strlen(system_info.machine);
122                 if (x>127) break;
123                 memcpy(ret,system_info.machine,x);
124                 ret+=x;
125                 break;
126             case 346157: /* OSNM-done */
127                 x=strlen(system_info.sysname);
128                 if (x>127) break;
129                 memcpy(ret,system_info.sysname,x);
130                 ret+=x;
131                 break;
132             case 346290: /* OSVR-done */
133                 if (strlen(system_info.release)>127) break;
134                 for (x=0;x<strlen(system_info.release);x++) {
135                     if (isdigit(system_info.release[x]) || system_info.release[x]=='.') {
136                         ret[0]=system_info.release[x];
137                         ret++;
138                     } else {
139                         break;
140                     }
141                 }
142                 break;
143             case 346291: /* OSVS-done */
144                 if (strlen(system_info.release)>127) break;
145                 for (x=0;x<strlen(system_info.release);x++) {
146                     if (system_info.release[x]=='.' && found) break;
147                     if (system_info.release[x]=='.') found=1;
148                     if (isdigit(system_info.release[x]) || found) {
149                         ret[0]=system_info.release[x];
150                         ret++;
151                     }
152                 }
153                 break;
154             case 298628: /* DIST-done */
155                 if (!strcmp("linux",system_info.sysname)) {
156                     smbuf=parse_url_subst_dist();
157                     if (smbuf==NULL) break;
158                     x=strlen(smbuf);
159                     if (x>127) break;
160                     memcpy(ret, smbuf, x);
161                     ret+=x;
162                 }
163                 break;
164             case 289150: /* ATSN-done */
165                 ret[0]='@';
166                 ret+=1;
167                 break;
168             default:
169                 break;
170         }
171 
172         ploc=loc;
173     }
174 
175     memcpy(ret, loc, strlen(loc));
176 
177     return(ret_s);
178 }
179 
180 char *parse_url_subst_dist(void) {
181     DIR *dirfd=NULL;
182     struct dirent *info=NULL;
183     static char retbuf[128]="unknown";
184     char *buf;
185 
186 /*
187     Round 1: check for /etc/DISTRIBUTION-version or /etc/DISTRIBUTION-release
188 */
189     dirfd=opendir("/etc/.");
190     while ((info=readdir(dirfd)) != NULL) {
191         if ((buf=strstr(info->d_name,"-version"))!=NULL) {
192             buf[0]=0;
193             strncpy(retbuf, info->d_name, sizeof(retbuf));
194             return(retbuf);
195         }
196         if ((buf=strstr(info->d_name,"_version"))!=NULL) {
197             buf[0]=0;
198             strncpy(retbuf, info->d_name, sizeof(retbuf));
199             return(retbuf);
200         }
201         if ((buf=strstr(info->d_name,"-release"))!=NULL) {
202             buf[0]=0;
203             strncpy(retbuf, info->d_name, sizeof(retbuf));
204             return(retbuf);
205         }
206     }
207 
208 /*
209     Round 2: ??? (distinguish between older versions of Slackware
210         and Unknown distributions..)
211 */
212 
213     return(retbuf);
214 }
215 
216 
217 void strtolower(char *str) {
218     uint32_t x=0;
219 
220     while (str[x]) { str[x]=tolower(str[x]); x++; }
221 }
222 
223 char *mime64(char *str) {
224     char *ret;
225     char mimeabet[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
226     int i=0, x=0, m, bit_buf_sze;
227     uint32_t bit_buf_sto;
228 
229     bit_buf_sze=bit_buffer_size(); /* Save the bit buffer, in case in use */
230     bit_buf_sto=bit_buffer_read(bit_buf_sze);
231 
232     if ((ret=malloc((int) ((((float)strlen(str))*1.5)+6)))==NULL) return(NULL);
233 
234     while (i<strlen(str)) {
235         while (bit_buffer_size()>=6) ret[x++]=mimeabet[bit_buffer_read(6)];
236         if ((bit_buffer_size()+8)<=32) bit_buffer_write(str[i++],8);
237     }
238     while (bit_buffer_size()>=6) ret[x++]=mimeabet[bit_buffer_read(6)];
239     if ((m=bit_buffer_size())) ret[x++]=mimeabet[bit_buffer_read(m)<<(6-m)];
240     while (x&3) ret[x++]='=';
241 
242     bit_buffer_write(bit_buf_sto, bit_buf_sze); /* Restore it */
243 
244     return(ret);
245 }
246 
247 
248 ssize_t read_net(int fd, void *buf, size_t count) {
249     ssize_t i=0,x;
250 
251     while (i!=count) {
252         x=read(fd,(void *) ((buf)+i),count-i);
253         if (x==0) break;
254         if (x==-1) return(-1);
255         i+=x;
256     }
257 
258     return(i);
259 }
5747687 [rkeene@sledge /home/rkeene/devel/libopennet-0.8.1]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2001-08-24 11:36:58