Logo Search packages:      
Sourcecode: dact version File versions  Download package

parse.c

/*
 * Copyright (C) 2001, 2002, and 2003  Roy Keene
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *      email: dact@rkeene.org
 */

/*
      Help, my atoi() is broken.
*/

#include "dact.h"
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <dirent.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include "buffer.h"
#include "parse.h"
#include "crc.h"
#include "ui.h"

uint32_t atoi2(const char *n) {
      uint32_t retval=0;
      int i,m;
      if (n==NULL) return(0);
      m=strcspn(n,".");
      for (i=0;i<m;i++) retval+=(n[i]-48)*pow(10,m-i-1);
      return(retval);
}

/* Parse those stupid netscape-style URLs, icky. 
 * And I know this REALLY crummy looking, but it works
 * (albeit, probably not perfectly) suffciently well.
 *  -- Roy Keene <rkeene@Rkeene.org>
 * `scheme'       will never exceed 5 bytes
 * `username'     will never exceed 128 bytes
 * `password'     will never exceed 128 bytes
 * `host'         will never exceed 512 bytes
 * `file'         will never exceed 1024 bytes
 */
int parse_url(const char *url, char *scheme, char *username, char *password, char *host, int *port, unsigned char *file) {
      char *local_url=NULL, *local_url_s, *fbuf;
      int i;

      if (strstr(url,"://")==NULL) {      /* Make sure we have an URL */
            strncpy(file,url,1023);
            return(1);
      };

      local_url_s=local_url=strdup(url);

      *port=0;
      file[1]=0;

      strncpy(scheme,strsep(&local_url,":"),5);
      local_url+=2;
      strncpy(host,strsep(&local_url,"/"),512);
      if (local_url!=NULL) strncpy(file+1,local_url,1022);
      file[0]='/';

      fbuf=malloc(1024);
      file[0]='/';
      fbuf[0]='\0';
      for (i=0;i<strlen(file);i++) {
            if ((strlen(fbuf)+4)>=1023) break;
            if (file[i]<33 || file[i]>127) {
                  if (file[i]==32) { strcat(fbuf, "+"); } else { sprintf(fbuf, "%s%%%02x", fbuf, file[i]); }
            } else {
                  sprintf(fbuf, "%s%c", fbuf, file[i]);
            }
      }
      strncpy(file, fbuf, 1023);
      file[1023]=0;
      free(fbuf);


      password[0]=0;
      if (strchr(host,'@')!=NULL) {
            local_url=local_url_s; /* Doh!  This was missing. */
            strcpy(local_url,host);
            strncpy(username,strsep(&local_url,"@:"),128);
            if (strchr(local_url,'@')!=NULL)
                  strncpy(password,strsep(&local_url,"@"),128);
            strcpy(host,local_url);
      } else {
            strcpy(username,"");
      }

      if (strchr(host,':')!=NULL) {
            local_url=local_url_s;
            strcpy(local_url,host);
            strcpy(host,strsep(&local_url,":"));
            *port=atoi(local_url);
      } else {
            if (!strcasecmp(scheme,"http")) *port=80;
            if (!strcasecmp(scheme,"ftp")) *port=21;
      }

      free(local_url_s);
      strtolower(scheme);
      return(0);
}


/*
      Replace 
            @@HOME@@    Home directory (getenv("HOME"))
            @@OSNM@@    OS Name (linux, freebsd, sunos, etc)
            @@OSVR@@    OS version (2.2.x, 4.2, 5.8, etc)
            @@OSVS@@    OS version (short) (2.2, 4.2, 5.8, etc)
            @@ARCH@@    Arch (i386, sparc64, sun4u, sun4m, etc)
            @@DIST@@    If OSNM=Linux, distribution of Linux.
            @@FILE@@    Name of compressed file.
            @@DTVR@@    Version of DACT (maj.min.rev)
            @@DTVS@@    Version of DACT (short) (maj.min)
            @@DTID@@    DACT identifier (dact-maj.min.rev-(dev|rel)-(no)modules-(no)debian-(no)network-(no)vercheck)
            @@PASS@@    Prompt for Password
            @@USER@@    Prompt for Username
            @@ATSN@@    Put an `@'
*/
char *parse_url_subst(const char *src, const char *fname) {
      static struct utsname system_info;
      static int sysinfo_init=0;
      uint32_t cmd=0, x, strsz;
      const char *loc=src, *ploc=loc;
      char *ret, *ret_s, found=0, *smbuf;

      if (!strstr((char *) src,"@@")) return(strdup(src));

      ret_s=ret=calloc(1024,1);

      if (!sysinfo_init) {
            uname(&system_info);
            strtolower(system_info.sysname);
            strtolower(system_info.machine);
            sysinfo_init=1;
      }


      while (strstr(loc,"@@")) {
            cmd=elfcrc(0, loc=strstr(loc, "@@")+2, 4);
            loc+=6;

            strsz=(loc-ploc-8);
            memcpy(ret, ploc, strsz);
            ret+=strsz;

            if ((ret-ret_s)>(1024-128)) break;

            switch (cmd) {
                  case 288376: /* ARCH-done */
                        x=strlen(system_info.machine);
                        if (x>127) break;
                        memcpy(ret,system_info.machine,x);
                        ret+=x;
                        break;
                  case 346157: /* OSNM-done */
                        x=strlen(system_info.sysname);
                        if (x>127) break;
                        memcpy(ret,system_info.sysname,x);
                        ret+=x;
                        break;
                  case 346290: /* OSVR-done */
                        if (strlen(system_info.release)>127) break;
                        for (x=0;x<strlen(system_info.release);x++) {
                              if (isdigit((int) system_info.release[x]) || system_info.release[x]=='.') {
                                    ret[0]=system_info.release[x];
                                    ret++;
                              } else {
                                    break;
                              }
                        }
                        break;
                  case 346291: /* OSVS-done */
                        if (strlen(system_info.release)>127) break;
                        for (x=0;x<strlen(system_info.release);x++) {
                              if (system_info.release[x]=='.' && found) break;
                              if (system_info.release[x]=='.') found=1;
                              if (isdigit((int) system_info.release[x]) || found) {
                                    ret[0]=system_info.release[x];
                                    ret++;
                              }
                        }
                        break;
                  case 306693: /* FILE-done */
                        x=strlen(fname);
                        if (x>127) break;
                        memcpy(ret,fname,x);
                        ret+=x;
                        break;
                  case 298628: /* DIST-done */
                        if (!strcmp("linux",system_info.sysname)) {
                              smbuf=parse_url_subst_dist();
                              if (smbuf==NULL) break;
                              x=strlen(smbuf);
                              if (x>127) break;
                              memcpy(ret, smbuf, x);
                              ret+=x;
                        }
                        break;
                  case 301490: /* DTVR-done */
                        smbuf=malloc(128);
                        sprintf(smbuf, "%i.%i.%i", DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION);
                        x=strlen(smbuf);
                        memcpy(ret, smbuf, x);
                        ret+=x;
                        free(smbuf);
                        break;
                  case 301491: /* DTVS-done */
                        smbuf=malloc(128);
                        sprintf(smbuf, "%i.%i", DACT_VER_MAJOR, DACT_VER_MINOR);
                        x=strlen(smbuf);
                        memcpy(ret, smbuf, x);
                        ret+=x;
                        free(smbuf);
                        break;
                  case 345731: /* PASS-done */
                        smbuf=dact_ui_getuserinput("Enter password: ", 128, 1);
                        x=strlen(smbuf);
                        if (x>127) break;
                        memcpy(ret, smbuf, x);
                        ret+=x;
                        free(smbuf);
                        break;
                  case 370594: /* USER-done */
                        smbuf=dact_ui_getuserinput("Enter username: ", 128, 0);
                        x=strlen(smbuf);
                        if (x>127) break;
                        memcpy(ret, smbuf, x);
                        ret+=x;
                        free(smbuf);
                        break;
                  case 289150: /* ATSN-done */
                        ret[0]='@';
                        ret+=1;
                        break;
                  case 316437: /* HOME-done*/
                        if (!(smbuf=getenv("HOME"))) break;
                        x=strlen(smbuf);
                        if (x>127) break;
                        memcpy(ret, smbuf, x);
                        ret+=x;
                        break;
                  case 301268: /* DTID */
                        smbuf=malloc(128);
                        sprintf(smbuf, "dact-%i.%i.%i-%s-%smodules-%sdebian-%snetwork-%svercheck", DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION,
#ifdef DEBUG
                              "dev",
#else
                              "rel",
#endif
#ifdef USE_MODULES
                              "",
#else
                              "no",
#endif
#ifdef DACT_DEBIAN_UPGRADE_PROC
                              "",
#else
                              "no",
#endif
#ifndef NO_NETWORK
                              "",
#else
                              "no",
#endif
#ifdef CHECK_VERSION
                              ""
#else
                              "no"
#endif
                              );
                        x=strlen(smbuf);
                        if (x>127) break;
                        memcpy(ret, smbuf, x);
                        ret+=x;
                        break;
#ifdef DEBUG
                  default:
                        PRINT_LINE; fprintf(stderr, "Unknown cmd (%i) [src=%s].\n",cmd,src);
                        break;
#endif
            }

            ploc=loc;
      }

      memcpy(ret, loc, strlen(loc));

      return(ret_s);
}

char *parse_url_subst_dist(void) {
      DIR *dirfd=NULL;
      struct dirent *info=NULL;
      static char retbuf[128]="unknown";
      char *buf;

/*
      Round 1: check for /etc/DISTRIBUTION-version or /etc/DISTRIBUTION-release
*/
      dirfd=opendir("/etc/.");
      while ((info=readdir(dirfd)) != NULL) {
            if ((buf=strstr(info->d_name,"-version"))!=NULL) {
                  buf[0]=0;
                  strncpy(retbuf, info->d_name, sizeof(retbuf));
                  return(retbuf);
            }
            if ((buf=strstr(info->d_name,"_version"))!=NULL) {
                  buf[0]=0;
                  strncpy(retbuf, info->d_name, sizeof(retbuf));
                  return(retbuf);
            }
            if ((buf=strstr(info->d_name,"-release"))!=NULL) {
                  buf[0]=0;
                  strncpy(retbuf, info->d_name, sizeof(retbuf));
                  return(retbuf);
            }
      }

/*
      Round 2: ??? (distinguish between older versions of Slackware
            and Unknown distributions..)
*/

      return(retbuf);
}


void strtolower(char *str) {
      uint32_t x=0;

      while (str[x]) { str[x]=tolower(str[x]); x++; }
}

char *mime64(unsigned char *str) {
      int x=strlen(str);
      return(mimes64(str,&x));
}


char *mimes64(unsigned char *str, int *size) {
      char *ret;
      char mimeabet[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      int i=0, x=0, m, bit_buf_sze;
      uint32_t bit_buf_sto;

      bit_buf_sze=bit_buffer_size(); /* Save the bit buffer, in case in use */
      bit_buf_sto=bit_buffer_read(bit_buf_sze);

      if ((ret=malloc((int) ((((float)(*size))*1.5)+7)))==NULL) return(NULL);

      while (i<(*size)) {
            while (bit_buffer_size()>=6) ret[x++]=mimeabet[bit_buffer_read(6)];
            if ((bit_buffer_size()+8)<=32) bit_buffer_write(str[i++],8);
      }
      while (bit_buffer_size()>=6) ret[x++]=mimeabet[bit_buffer_read(6)];
      if ((m=bit_buffer_size())) ret[x++]=mimeabet[bit_buffer_read(m)<<(6-m)];
      while (x&3) ret[x++]='=';

      bit_buffer_write(bit_buf_sto, bit_buf_sze); /* Restore it */

      *size=x;

      ret[x]='\0';

      return(ret);
}

char *demime64(unsigned char *str) {
      char *ret;
      char mimeabet[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      int i=0, x=0, m, bit_buf_sze;
      uint32_t bit_buf_sto;

      bit_buf_sze=bit_buffer_size(); /* Save the bit buffer, in case in use */
      bit_buf_sto=bit_buffer_read(bit_buf_sze);

      if ((ret=malloc((int) ((((float)strlen(str))*0.75)+6)))==NULL) return(NULL);

      while (i<strlen(str)) {
            if (str[i]=='=') break;
            while (bit_buffer_size()>=8) ret[x++]=bit_buffer_read(8);
            if ((bit_buffer_size()+6)<=32) bit_buffer_write(strchr(mimeabet,str[i++])-mimeabet,6);
      }
      while (bit_buffer_size()>=8) ret[x++]=bit_buffer_read(8);
      if ((m=bit_buffer_size())) ret[x++]=bit_buffer_read(m)<<(8-m);

      bit_buffer_write(bit_buf_sto, bit_buf_sze); /* Restore it */

      return(ret);
}


int32_t read_f(int fd, void *buf, size_t count) {
      int32_t i=0,x;

      while (i!=count) {
            x=read(fd,(void *) (((char *) buf)+i),count-i);
            if (x==0) break;
/* Damn typos, read_f was broken here because x<0 was typed as x>0 */
            if (x<0) return(x);
            i+=x;
      }

      return(i);
}

uint32_t hash_fourbyte(unsigned char *str, const char term) {
      uint32_t ret=0;
      int i;

      for (i=0;i<4;i++) {
            if (!str[i] || str[i]==term) break;
            ret+=(str[i]<<(i*8));
      }
      return(ret);
}

Generated by  Doxygen 1.6.0   Back to index