Add missing Hush shell code in other files
authorPiotr Dymacz <pepe2k@gmail.com>
Wed, 19 Mar 2014 10:01:45 +0000 (11:01 +0100)
committerPiotr Dymacz <pepe2k@gmail.com>
Wed, 19 Mar 2014 10:01:45 +0000 (11:01 +0100)
u-boot/common/cmd_bootm.c
u-boot/common/command.c
u-boot/common/main.c
u-boot/lib_bootstrap/string.c
u-boot/lib_generic/string.c

index 53634f29cc22786b557fdc3cfd55bd310e68966f..c71d293867d9657087d88767730d4b54fc05dd52 100755 (executable)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CFG_HUSH_PARSER
+#include <hush.h>
+#endif
+
 /* cmd_boot.c */
 extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
@@ -397,6 +401,28 @@ void print_image_hdr(tplink_image_header_t *hdr){
 }
 #endif /* defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || defined(CONFIG_FOR_DLINK_DIR505_A1) || defined(CONFIG_FOR_DRAGINO_V2) */
 
+#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
+int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+       int rcode = 0;
+#ifndef CFG_HUSH_PARSER
+       if(run_command (getenv ("bootcmd"), flag) < 0){
+               rcode = 1;
+       }
+#else
+       if(parse_string_outer(getenv("bootcmd"), FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){
+               rcode = 1;
+       }
+#endif
+       return(rcode);
+}
+
+U_BOOT_CMD(boot, 1, 1, do_bootd, "boot default, i.e., run 'bootcmd'\n", NULL);
+
+/* keep old command name "bootd" for backward compatibility */
+U_BOOT_CMD(bootd, 1, 1, do_bootd, "boot default, i.e., run 'bootcmd'\n", NULL);
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_BOOTD */
+
 #if (CONFIG_COMMANDS & CFG_CMD_IMI)
 int do_iminfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
        ulong addr;
index d96b3a530b493cd2bca80ada0623525bebf9dc70..467865636fad1d5a9f9ecfe97bf53de58a0fec64 100755 (executable)
@@ -67,6 +67,152 @@ int do_echo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
 U_BOOT_CMD(echo, CFG_MAXARGS, 1, do_echo, "echo args to console\n", "[args..]\n" "\t- echo args to console; \\c suppresses newline\n");
 #endif /*  CFG_CMD_ECHO */
 
+
+#ifdef CFG_HUSH_PARSER
+int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+       char **ap;
+       int left, adv, expr, last_expr, neg, last_cmp;
+
+       /* args? */
+       if (argc < 3){
+               return(1);
+       }
+
+#if 0
+       printf("test:");
+       left = 1;
+       while (argv[left]){
+               printf(" %s", argv[left++]);
+       }
+#endif
+
+       last_expr = 0;
+       left = argc - 1; ap = argv + 1;
+
+       if(left > 0 && strcmp(ap[0], "!") == 0){
+               neg = 1;
+               ap++;
+               left--;
+       } else {
+               neg = 0;
+       }
+
+       expr = -1;
+       last_cmp = -1;
+       last_expr = -1;
+
+       while(left > 0){
+
+               if(strcmp(ap[0], "-o") == 0 || strcmp(ap[0], "-a") == 0){
+                       adv = 1;
+               } else if(strcmp(ap[0], "-z") == 0 || strcmp(ap[0], "-n") == 0){
+                       adv = 2;
+               } else {
+                       adv = 3;
+               }
+
+               if(left < adv){
+                       expr = 1;
+                       break;
+               }
+
+               if(adv == 1){
+                       if (strcmp(ap[0], "-o") == 0){
+                               last_expr = expr;
+                               last_cmp = 0;
+                       } else if(strcmp(ap[0], "-a") == 0){
+                               last_expr = expr;
+                               last_cmp = 1;
+                       } else {
+                               expr = 1;
+                               break;
+                       }
+               }
+
+               if(adv == 2){
+                       if (strcmp(ap[0], "-z") == 0){
+                               expr = strlen(ap[1]) == 0 ? 1 : 0;
+                       } else if(strcmp(ap[0], "-n") == 0){
+                               expr = strlen(ap[1]) == 0 ? 0 : 1;
+                       } else {
+                               expr = 1;
+                               break;
+                       }
+
+                       if(last_cmp == 0){
+                               expr = last_expr || expr;
+                       } else if(last_cmp == 1){
+                               expr = last_expr && expr;
+                       }
+                       last_cmp = -1;
+               }
+
+               if(adv == 3){
+                       if(strcmp(ap[1], "=") == 0){
+                               expr = strcmp(ap[0], ap[2]) == 0;
+                       } else if(strcmp(ap[1], "!=") == 0){
+                               expr = strcmp(ap[0], ap[2]) != 0;
+                       } else if(strcmp(ap[1], ">") == 0){
+                               expr = strcmp(ap[0], ap[2]) > 0;
+                       } else if(strcmp(ap[1], "<") == 0){
+                               expr = strcmp(ap[0], ap[2]) < 0;
+                       } else if(strcmp(ap[1], "-eq") == 0){
+                               expr = simple_strtol(ap[0], NULL, 10) == simple_strtol(ap[2], NULL, 10);
+                       } else if(strcmp(ap[1], "-ne") == 0){
+                               expr = simple_strtol(ap[0], NULL, 10) != simple_strtol(ap[2], NULL, 10);
+                       } else if(strcmp(ap[1], "-lt") == 0){
+                               expr = simple_strtol(ap[0], NULL, 10) < simple_strtol(ap[2], NULL, 10);
+                       } else if(strcmp(ap[1], "-le") == 0){
+                               expr = simple_strtol(ap[0], NULL, 10) <= simple_strtol(ap[2], NULL, 10);
+                       } else if(strcmp(ap[1], "-gt") == 0){
+                               expr = simple_strtol(ap[0], NULL, 10) > simple_strtol(ap[2], NULL, 10);
+                       } else if(strcmp(ap[1], "-ge") == 0){
+                               expr = simple_strtol(ap[0], NULL, 10) >= simple_strtol(ap[2], NULL, 10);
+                       } else {
+                               expr = 1;
+                               break;
+                       }
+
+                       if(last_cmp == 0){
+                               expr = last_expr || expr;
+                       } else if(last_cmp == 1){
+                               expr = last_expr && expr;
+                       }
+                       last_cmp = -1;
+               }
+
+               ap += adv; left -= adv;
+       }
+
+       if(neg){
+               expr = !expr;
+       }
+
+       expr = !expr;
+
+#if 0
+       printf(": returns %d\n", expr);
+#endif
+
+       return(expr);
+}
+
+U_BOOT_CMD(test, CFG_MAXARGS, 1, do_test, "minimal test like /bin/sh\n", "[args..]\n"
+"\t- test functionality\n");
+
+int do_exit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+       int r = 0;
+
+       if(argc > 1){
+               r = simple_strtoul(argv[1], NULL, 10);
+       }
+
+       return(-r - 2);
+}
+
+U_BOOT_CMD(exit, 2, 1, do_exit, "exit script\n", "\n\t- exit functionality\n");
+#endif /* CFG_HUSH_PARSER */
+
 /*
  * Use puts() instead of printf() to avoid printf buffer overflow
  * for long help messages
index 65bef06d090e852d160e6a969ed6960f2c8f4a12..d5ff9509184d0c1ca95ba6594a6584ea85f076dc 100755 (executable)
 #include <common.h>
 #include <command.h>
 
+#ifdef CFG_HUSH_PARSER
+#include <hush.h>
+#endif
+
 #ifdef CONFIG_SILENT_CONSOLE
 DECLARE_GLOBAL_DATA_PTR;
 #endif
@@ -116,16 +120,24 @@ static __inline__ int abortboot(int bootdelay){
 /****************************************************************************/
 
 void main_loop(void){
+#ifndef CFG_HUSH_PARSER
        static char lastcommand[CFG_CBSIZE] = { 0, };
        int len;
        int rc = 1;
        int flag;
+#endif
        int counter = 0;
 
 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
        char *s;
        int bootdelay;
+#endif /* defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) */
 
+#ifdef CFG_HUSH_PARSER
+       u_boot_hush_start();
+#endif
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
        // get boot delay (seconds)
        s = getenv("bootdelay");
        bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
@@ -220,7 +232,11 @@ void main_loop(void){
        if(bootdelay >= 0 && s && !abortboot(bootdelay)){
 
                // try to boot
-               run_command(s, 0);
+#ifndef CFG_HUSH_PARSER
+                       run_command(s, 0);
+#else
+                       parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+#endif
 
                // something goes wrong!
                printf("\n## Error: failed to execute 'bootcmd'!\nHTTP server is starting for firmware update...\n\n");
@@ -231,6 +247,11 @@ void main_loop(void){
        /*
         * Main Loop for Monitor Command Processing
         */
+#ifdef CFG_HUSH_PARSER
+       parse_file_outer();
+       /* This point is never reached */
+       for (;;);
+#else
        for(;;){
                len = readline(CFG_PROMPT);
 
@@ -252,6 +273,7 @@ void main_loop(void){
                        lastcommand[0] = 0;
                }
        }
+#endif /* CFG_HUSH_PARSER */
 }
 
 /****************************************************************************/
@@ -654,10 +676,15 @@ int do_run(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
                        printf("## Error: \"%s\" not defined\n", argv[i]);
                        return(1);
                }
-
+#ifndef CFG_HUSH_PARSER
                if(run_command(arg, flag) == -1){
                        return(1);
                }
+#else
+               if (parse_string_outer(arg, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){
+                       return(1);
+               }
+#endif /* CFG_HUSH_PARSER */
        }
 
        return(0);
index 667557163b20367cd6abe60ab8866022c687c738..e0b793abbee5106e5614f51f7876fd1e6be1d5e5 100755 (executable)
 #include <linux/ctype.h>
 #include <malloc.h>
 
+
+#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */
+/**
+ * strnicmp - Case insensitive, length-limited string comparison
+ * @s1: One string
+ * @s2: The other string
+ * @len: the maximum number of characters to compare
+ */
+int strnicmp(const char *s1, const char *s2, size_t len)
+{
+       /* Yes, Virginia, it had better be unsigned */
+       unsigned char c1, c2;
+
+       c1 = 0; c2 = 0;
+       if (len) {
+               do {
+                       c1 = *s1; c2 = *s2;
+                       s1++; s2++;
+                       if (!c1)
+                               break;
+                       if (!c2)
+                               break;
+                       if (c1 == c2)
+                               continue;
+                       c1 = tolower(c1);
+                       c2 = tolower(c2);
+                       if (c1 != c2)
+                               break;
+               } while (--len);
+       }
+       return (int)c1 - (int)c2;
+}
+#endif
+
+char * ___strtok;
+
 #ifndef __HAVE_ARCH_STRCPY
 /**
  * strcpy - Copy a %NUL terminated string
  * @dest: Where to copy the string to
  * @src: Where to copy the string from
  */
-char * strcpy(char * dest,const char *src){
+char * strcpy(char * dest,const char *src)
+{
        char *tmp = dest;
 
        while ((*dest++ = *src++) != '\0')
@@ -46,7 +83,8 @@ char * strcpy(char * dest,const char *src){
  * However, the result is not %NUL-terminated if the source exceeds
  * @count bytes.
  */
-char * strncpy(char * dest,const char *src,size_t count){
+char * strncpy(char * dest,const char *src,size_t count)
+{
        char *tmp = dest;
 
        while (count-- && (*dest++ = *src++) != '\0')
@@ -62,7 +100,8 @@ char * strncpy(char * dest,const char *src,size_t count){
  * @dest: The string to be appended to
  * @src: The string to append to it
  */
-char * strcat(char * dest, const char * src){
+char * strcat(char * dest, const char * src)
+{
        char *tmp = dest;
 
        while (*dest)
@@ -74,13 +113,43 @@ char * strcat(char * dest, const char * src){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRNCAT
+/**
+ * strncat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The maximum numbers of bytes to copy
+ *
+ * Note that in contrast to strncpy, strncat ensures the result is
+ * terminated.
+ */
+char * strncat(char *dest, const char *src, size_t count)
+{
+       char *tmp = dest;
+
+       if (count) {
+               while (*dest)
+                       dest++;
+               while ((*dest++ = *src++)) {
+                       if (--count == 0) {
+                               *dest = '\0';
+                               break;
+                       }
+               }
+       }
+
+       return tmp;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRCMP
 /**
  * strcmp - Compare two strings
  * @cs: One string
  * @ct: Another string
  */
-int strcmp(const char * cs,const char * ct){
+int strcmp(const char * cs,const char * ct)
+{
        register signed char __res;
 
        while (1) {
@@ -99,7 +168,8 @@ int strcmp(const char * cs,const char * ct){
  * @ct: Another string
  * @count: The maximum number of bytes to compare
  */
-int strncmp(const char * cs,const char * ct,size_t count){
+int strncmp(const char * cs,const char * ct,size_t count)
+{
        register signed char __res = 0;
 
        while (count) {
@@ -118,7 +188,8 @@ int strncmp(const char * cs,const char * ct,size_t count){
  * @s: The string to be searched
  * @c: The character to search for
  */
-char * strchr(const char * s, int c){
+char * strchr(const char * s, int c)
+{
        for(; *s != (char) c; ++s)
                if (*s == '\0')
                        return NULL;
@@ -126,12 +197,30 @@ char * strchr(const char * s, int c){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRRCHR
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strrchr(const char * s, int c)
+{
+       const char *p = s + strlen(s);
+       do {
+          if (*p == (char)c)
+              return (char *)p;
+       } while (--p >= s);
+       return NULL;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRLEN
 /**
  * strlen - Find the length of a string
  * @s: The string to be sized
  */
-size_t strlen(const char * s){
+size_t strlen(const char * s)
+{
        const char *sc;
 
        for (sc = s; *sc != '\0'; ++sc)
@@ -146,7 +235,8 @@ size_t strlen(const char * s){
  * @s: The string to be sized
  * @count: The maximum number of bytes to search
  */
-size_t strnlen(const char * s, size_t count){
+size_t strnlen(const char * s, size_t count)
+{
        const char *sc;
 
        for (sc = s; count-- && *sc != '\0'; ++sc)
@@ -155,6 +245,21 @@ size_t strnlen(const char * s, size_t count){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRDUP
+char * strdup(const char *s)
+{
+       char *new;
+
+       if ((s == NULL) ||
+           ((new = malloc (strlen(s) + 1)) == NULL) ) {
+               return NULL;
+       }
+
+       strcpy (new, s);
+       return new;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRSPN
 /**
  * strspn - Calculate the length of the initial substring of @s which only
@@ -162,7 +267,8 @@ size_t strnlen(const char * s, size_t count){
  * @s: The string to be searched
  * @accept: The string to search for
  */
-size_t strspn(const char *s, const char *accept){
+size_t strspn(const char *s, const char *accept)
+{
        const char *p;
        const char *a;
        size_t count = 0;
@@ -187,7 +293,8 @@ size_t strspn(const char *s, const char *accept){
  * @cs: The string to be searched
  * @ct: The characters to search for
  */
-char * strpbrk(const char * cs,const char * ct){
+char * strpbrk(const char * cs,const char * ct)
+{
        const char *sc1,*sc2;
 
        for( sc1 = cs; *sc1 != '\0'; ++sc1) {
@@ -200,6 +307,91 @@ char * strpbrk(const char * cs,const char * ct){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRTOK
+/**
+ * strtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * WARNING: strtok is deprecated, use strsep instead.
+ */
+char * strtok(char * s,const char * ct)
+{
+       char *sbegin, *send;
+
+       sbegin  = s ? s : ___strtok;
+       if (!sbegin) {
+               return NULL;
+       }
+       sbegin += strspn(sbegin,ct);
+       if (*sbegin == '\0') {
+               ___strtok = NULL;
+               return( NULL );
+       }
+       send = strpbrk( sbegin, ct);
+       if (send && *send != '\0')
+               *send++ = '\0';
+       ___strtok = send;
+       return (sbegin);
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSEP
+/**
+ * strsep - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * strsep() updates @s to point after the token, ready for the next call.
+ *
+ * It returns empty tokens, too, behaving exactly like the libc function
+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
+ * Same semantics, slimmer shape. ;)
+ */
+char * strsep(char **s, const char *ct)
+{
+       char *sbegin = *s, *end;
+
+       if (sbegin == NULL)
+               return NULL;
+
+       end = strpbrk(sbegin, ct);
+       if (end)
+               *end++ = '\0';
+       *s = end;
+
+       return sbegin;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSWAB
+/**
+ * strswab - swap adjacent even and odd bytes in %NUL-terminated string
+ * s: address of the string
+ *
+ * returns the address of the swapped string or NULL on error. If
+ * string length is odd, last byte is untouched.
+ */
+char *strswab(const char *s)
+{
+       char *p, *q;
+
+       if ((NULL == s) || ('\0' == *s)) {
+               return (NULL);
+       }
+
+       for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) {
+               char  tmp;
+
+               tmp = *p;
+               *p  = *q;
+               *q  = tmp;
+       }
+
+       return (char *) s;
+}
+#endif
+
 #ifndef __HAVE_ARCH_MEMSET
 /**
  * memset - Fill a region of memory with the given value
@@ -209,7 +401,8 @@ char * strpbrk(const char * cs,const char * ct){
  *
  * Do not use memset() to access IO space, use memset_io() instead.
  */
-void * memset(void * s,int c,size_t count){
+void * memset(void * s,int c,size_t count)
+{
        char *xs = (char *) s;
 
        while (count--)
@@ -219,6 +412,30 @@ void * memset(void * s,int c,size_t count){
 }
 #endif
 
+#ifndef __HAVE_ARCH_BCOPY
+/**
+ * bcopy - Copy one area of memory to another
+ * @src: Where to copy from
+ * @dest: Where to copy to
+ * @count: The size of the area.
+ *
+ * Note that this is the same as memcpy(), with the arguments reversed.
+ * memcpy() is the standard, bcopy() is a legacy BSD function.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+char * bcopy(const char * src, char * dest, int count)
+{
+       char *tmp = dest;
+
+       while (count--)
+               *tmp++ = *src++;
+
+       return dest;
+}
+#endif
+
 #ifndef __HAVE_ARCH_MEMCPY
 /**
  * memcpy - Copy one area of memory to another
@@ -229,7 +446,8 @@ void * memset(void * s,int c,size_t count){
  * You should not use this function to access IO space, use memcpy_toio()
  * or memcpy_fromio() instead.
  */
-void * memcpy(void * dest,const void *src,size_t count){
+void * memcpy(void * dest,const void *src,size_t count)
+{
        char *tmp = (char *) dest, *s = (char *) src;
 
        while (count--)
@@ -248,7 +466,8 @@ void * memcpy(void * dest,const void *src,size_t count){
  *
  * Unlike memcpy(), memmove() copes with overlapping areas.
  */
-void * memmove(void * dest,const void *src,size_t count){
+void * memmove(void * dest,const void *src,size_t count)
+{
        char *tmp, *s;
 
        if (dest <= src) {
@@ -275,7 +494,8 @@ void * memmove(void * dest,const void *src,size_t count){
  * @ct: Another area of memory
  * @count: The size of the area.
  */
-int memcmp(const void * cs,const void * ct,size_t count){
+int memcmp(const void * cs,const void * ct,size_t count)
+{
        const unsigned char *su1, *su2;
        int res = 0;
 
@@ -286,13 +506,38 @@ int memcmp(const void * cs,const void * ct,size_t count){
 }
 #endif
 
+#ifndef __HAVE_ARCH_MEMSCAN
+/**
+ * memscan - Find a character in an area of memory.
+ * @addr: The memory area
+ * @c: The byte to search for
+ * @size: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or 1 byte past
+ * the area if @c is not found
+ */
+void * memscan(void * addr, int c, size_t size)
+{
+       unsigned char * p = (unsigned char *) addr;
+
+       while (size) {
+               if (*p == c)
+                       return (void *) p;
+               p++;
+               size--;
+       }
+       return (void *) p;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRSTR
 /**
  * strstr - Find the first substring in a %NUL terminated string
  * @s1: The string to be searched
  * @s2: The string to search for
  */
-char * strstr(const char * s1,const char * s2){
+char * strstr(const char * s1,const char * s2)
+{
        int l1, l2;
 
        l2 = strlen(s2);
@@ -308,3 +553,26 @@ char * strstr(const char * s1,const char * s2){
        return NULL;
 }
 #endif
+
+#ifndef __HAVE_ARCH_MEMCHR
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+       const unsigned char *p = s;
+       while (n-- != 0) {
+               if ((unsigned char)c == *p++) {
+                       return (void *)(p-1);
+               }
+       }
+       return NULL;
+}
+
+#endif
index 667557163b20367cd6abe60ab8866022c687c738..0e99d1b2b50cc9200da6dc49de3a35a858490a90 100755 (executable)
 #include <linux/ctype.h>
 #include <malloc.h>
 
+
+#ifndef __HAVE_ARCH_STRNICMP
+/**
+ * strnicmp - Case insensitive, length-limited string comparison
+ * @s1: One string
+ * @s2: The other string
+ * @len: the maximum number of characters to compare
+ */
+int strnicmp(const char *s1, const char *s2, size_t len)
+{
+       /* Yes, Virginia, it had better be unsigned */
+       unsigned char c1, c2;
+
+       c1 = 0; c2 = 0;
+       if (len) {
+               do {
+                       c1 = *s1; c2 = *s2;
+                       s1++; s2++;
+                       if (!c1)
+                               break;
+                       if (!c2)
+                               break;
+                       if (c1 == c2)
+                               continue;
+                       c1 = tolower(c1);
+                       c2 = tolower(c2);
+                       if (c1 != c2)
+                               break;
+               } while (--len);
+       }
+       return (int)c1 - (int)c2;
+}
+#endif
+
+char * ___strtok;
+
 #ifndef __HAVE_ARCH_STRCPY
 /**
  * strcpy - Copy a %NUL terminated string
  * @dest: Where to copy the string to
  * @src: Where to copy the string from
  */
-char * strcpy(char * dest,const char *src){
+char * strcpy(char * dest,const char *src)
+{
        char *tmp = dest;
 
        while ((*dest++ = *src++) != '\0')
@@ -46,7 +83,8 @@ char * strcpy(char * dest,const char *src){
  * However, the result is not %NUL-terminated if the source exceeds
  * @count bytes.
  */
-char * strncpy(char * dest,const char *src,size_t count){
+char * strncpy(char * dest,const char *src,size_t count)
+{
        char *tmp = dest;
 
        while (count-- && (*dest++ = *src++) != '\0')
@@ -62,7 +100,8 @@ char * strncpy(char * dest,const char *src,size_t count){
  * @dest: The string to be appended to
  * @src: The string to append to it
  */
-char * strcat(char * dest, const char * src){
+char * strcat(char * dest, const char * src)
+{
        char *tmp = dest;
 
        while (*dest)
@@ -74,13 +113,43 @@ char * strcat(char * dest, const char * src){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRNCAT
+/**
+ * strncat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The maximum numbers of bytes to copy
+ *
+ * Note that in contrast to strncpy, strncat ensures the result is
+ * terminated.
+ */
+char * strncat(char *dest, const char *src, size_t count)
+{
+       char *tmp = dest;
+
+       if (count) {
+               while (*dest)
+                       dest++;
+               while ((*dest++ = *src++)) {
+                       if (--count == 0) {
+                               *dest = '\0';
+                               break;
+                       }
+               }
+       }
+
+       return tmp;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRCMP
 /**
  * strcmp - Compare two strings
  * @cs: One string
  * @ct: Another string
  */
-int strcmp(const char * cs,const char * ct){
+int strcmp(const char * cs,const char * ct)
+{
        register signed char __res;
 
        while (1) {
@@ -99,7 +168,8 @@ int strcmp(const char * cs,const char * ct){
  * @ct: Another string
  * @count: The maximum number of bytes to compare
  */
-int strncmp(const char * cs,const char * ct,size_t count){
+int strncmp(const char * cs,const char * ct,size_t count)
+{
        register signed char __res = 0;
 
        while (count) {
@@ -118,7 +188,8 @@ int strncmp(const char * cs,const char * ct,size_t count){
  * @s: The string to be searched
  * @c: The character to search for
  */
-char * strchr(const char * s, int c){
+char * strchr(const char * s, int c)
+{
        for(; *s != (char) c; ++s)
                if (*s == '\0')
                        return NULL;
@@ -126,12 +197,30 @@ char * strchr(const char * s, int c){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRRCHR
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strrchr(const char * s, int c)
+{
+       const char *p = s + strlen(s);
+       do {
+          if (*p == (char)c)
+              return (char *)p;
+       } while (--p >= s);
+       return NULL;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRLEN
 /**
  * strlen - Find the length of a string
  * @s: The string to be sized
  */
-size_t strlen(const char * s){
+size_t strlen(const char * s)
+{
        const char *sc;
 
        for (sc = s; *sc != '\0'; ++sc)
@@ -146,7 +235,8 @@ size_t strlen(const char * s){
  * @s: The string to be sized
  * @count: The maximum number of bytes to search
  */
-size_t strnlen(const char * s, size_t count){
+size_t strnlen(const char * s, size_t count)
+{
        const char *sc;
 
        for (sc = s; count-- && *sc != '\0'; ++sc)
@@ -155,6 +245,21 @@ size_t strnlen(const char * s, size_t count){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRDUP
+char * strdup(const char *s)
+{
+       char *new;
+
+       if ((s == NULL) ||
+           ((new = malloc (strlen(s) + 1)) == NULL) ) {
+               return NULL;
+       }
+
+       strcpy (new, s);
+       return new;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRSPN
 /**
  * strspn - Calculate the length of the initial substring of @s which only
@@ -162,7 +267,8 @@ size_t strnlen(const char * s, size_t count){
  * @s: The string to be searched
  * @accept: The string to search for
  */
-size_t strspn(const char *s, const char *accept){
+size_t strspn(const char *s, const char *accept)
+{
        const char *p;
        const char *a;
        size_t count = 0;
@@ -187,7 +293,8 @@ size_t strspn(const char *s, const char *accept){
  * @cs: The string to be searched
  * @ct: The characters to search for
  */
-char * strpbrk(const char * cs,const char * ct){
+char * strpbrk(const char * cs,const char * ct)
+{
        const char *sc1,*sc2;
 
        for( sc1 = cs; *sc1 != '\0'; ++sc1) {
@@ -200,6 +307,91 @@ char * strpbrk(const char * cs,const char * ct){
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRTOK
+/**
+ * strtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * WARNING: strtok is deprecated, use strsep instead.
+ */
+char * strtok(char * s,const char * ct)
+{
+       char *sbegin, *send;
+
+       sbegin  = s ? s : ___strtok;
+       if (!sbegin) {
+               return NULL;
+       }
+       sbegin += strspn(sbegin,ct);
+       if (*sbegin == '\0') {
+               ___strtok = NULL;
+               return( NULL );
+       }
+       send = strpbrk( sbegin, ct);
+       if (send && *send != '\0')
+               *send++ = '\0';
+       ___strtok = send;
+       return (sbegin);
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSEP
+/**
+ * strsep - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * strsep() updates @s to point after the token, ready for the next call.
+ *
+ * It returns empty tokens, too, behaving exactly like the libc function
+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
+ * Same semantics, slimmer shape. ;)
+ */
+char * strsep(char **s, const char *ct)
+{
+       char *sbegin = *s, *end;
+
+       if (sbegin == NULL)
+               return NULL;
+
+       end = strpbrk(sbegin, ct);
+       if (end)
+               *end++ = '\0';
+       *s = end;
+
+       return sbegin;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSWAB
+/**
+ * strswab - swap adjacent even and odd bytes in %NUL-terminated string
+ * s: address of the string
+ *
+ * returns the address of the swapped string or NULL on error. If
+ * string length is odd, last byte is untouched.
+ */
+char *strswab(const char *s)
+{
+       char *p, *q;
+
+       if ((NULL == s) || ('\0' == *s)) {
+               return (NULL);
+       }
+
+       for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) {
+               char  tmp;
+
+               tmp = *p;
+               *p  = *q;
+               *q  = tmp;
+       }
+
+       return (char *) s;
+}
+#endif
+
 #ifndef __HAVE_ARCH_MEMSET
 /**
  * memset - Fill a region of memory with the given value
@@ -209,7 +401,8 @@ char * strpbrk(const char * cs,const char * ct){
  *
  * Do not use memset() to access IO space, use memset_io() instead.
  */
-void * memset(void * s,int c,size_t count){
+void * memset(void * s,int c,size_t count)
+{
        char *xs = (char *) s;
 
        while (count--)
@@ -219,6 +412,30 @@ void * memset(void * s,int c,size_t count){
 }
 #endif
 
+#ifndef __HAVE_ARCH_BCOPY
+/**
+ * bcopy - Copy one area of memory to another
+ * @src: Where to copy from
+ * @dest: Where to copy to
+ * @count: The size of the area.
+ *
+ * Note that this is the same as memcpy(), with the arguments reversed.
+ * memcpy() is the standard, bcopy() is a legacy BSD function.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+char * bcopy(const char * src, char * dest, int count)
+{
+       char *tmp = dest;
+
+       while (count--)
+               *tmp++ = *src++;
+
+       return dest;
+}
+#endif
+
 #ifndef __HAVE_ARCH_MEMCPY
 /**
  * memcpy - Copy one area of memory to another
@@ -229,7 +446,8 @@ void * memset(void * s,int c,size_t count){
  * You should not use this function to access IO space, use memcpy_toio()
  * or memcpy_fromio() instead.
  */
-void * memcpy(void * dest,const void *src,size_t count){
+void * memcpy(void * dest,const void *src,size_t count)
+{
        char *tmp = (char *) dest, *s = (char *) src;
 
        while (count--)
@@ -248,7 +466,8 @@ void * memcpy(void * dest,const void *src,size_t count){
  *
  * Unlike memcpy(), memmove() copes with overlapping areas.
  */
-void * memmove(void * dest,const void *src,size_t count){
+void * memmove(void * dest,const void *src,size_t count)
+{
        char *tmp, *s;
 
        if (dest <= src) {
@@ -275,7 +494,8 @@ void * memmove(void * dest,const void *src,size_t count){
  * @ct: Another area of memory
  * @count: The size of the area.
  */
-int memcmp(const void * cs,const void * ct,size_t count){
+int memcmp(const void * cs,const void * ct,size_t count)
+{
        const unsigned char *su1, *su2;
        int res = 0;
 
@@ -286,13 +506,38 @@ int memcmp(const void * cs,const void * ct,size_t count){
 }
 #endif
 
+#ifndef __HAVE_ARCH_MEMSCAN
+/**
+ * memscan - Find a character in an area of memory.
+ * @addr: The memory area
+ * @c: The byte to search for
+ * @size: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or 1 byte past
+ * the area if @c is not found
+ */
+void * memscan(void * addr, int c, size_t size)
+{
+       unsigned char * p = (unsigned char *) addr;
+
+       while (size) {
+               if (*p == c)
+                       return (void *) p;
+               p++;
+               size--;
+       }
+       return (void *) p;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRSTR
 /**
  * strstr - Find the first substring in a %NUL terminated string
  * @s1: The string to be searched
  * @s2: The string to search for
  */
-char * strstr(const char * s1,const char * s2){
+char * strstr(const char * s1,const char * s2)
+{
        int l1, l2;
 
        l2 = strlen(s2);
@@ -308,3 +553,26 @@ char * strstr(const char * s1,const char * s2){
        return NULL;
 }
 #endif
+
+#ifndef __HAVE_ARCH_MEMCHR
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+       const unsigned char *p = s;
+       while (n-- != 0) {
+               if ((unsigned char)c == *p++) {
+                       return (void *)(p-1);
+               }
+       }
+       return NULL;
+}
+
+#endif