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 } |