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