On Sat, Jul 29, 2006, Keith Bennett wrote:
> There is one method of doing this which might be a possible compromise.
> When it comes to swapping characters you only need to escape one set:
> either the originals or the replacements. For example, if you are replacing
> the ' ' character with '_' then you are fine until you come across a
> pathname that already contains the '_' character. Then you need some way
> of telling the original instances of '_' from the ones that have just been
> introduced. There are two ways of dealing with this - either escape the
> originals or escape the replacements. I chose to escape the replacements
> but you could just as easily escape the originals instead.
> 
> Here are two examples of replacing ' ' with '_'. The first is the current
> method. The second escapes the originals instead.
> 
>   'A long pathname using_spaces_and_undercores'
>    1 => 'A\_long\_pathname\_using_spaces_and_underscores'
>    2 => 'A_long_pathname_using\_spaces\_and\_underscores'
> 
> If you prefer method two then let me know and I'll revise the patch.
> Or if you would rather have the potentially dangerous tr-editing back
> then I'll hard-code the '/' character translation. I think that this
> is the only character that absolutely has to be changed?

Here is a patch implementing method 2.

Keith.
diff -Nur lkarmafs-0.1.7.orig/lkarmafs.c lkarmafs-0.1.7/lkarmafs.c
--- lkarmafs-0.1.7.orig/lkarmafs.c      2006-06-25 20:07:30.000000000 +0100
+++ lkarmafs-0.1.7/lkarmafs.c   2006-07-29 13:00:51.000000000 +0100
@@ -41,11 +41,7 @@
 #include <mcheck.h>     /* for mtrace related functions */
 // #include <attr/xattr.h>
 
-#include "karma.h"
-#include "ssdp.h"
-#include "properties.h"
-#include "util.h"
-#include "errors.h"
+#include <lkarma.h>
 #include "utf8.h"
 #include "pathedit.h"
 
@@ -57,6 +53,8 @@
 #define R_PERM 0
 
 #define UNK_NAME "-UnKnown-"
+#define TR_FRM "/ "
+#define TR_TO  "# "
 
 #define CHECK(x) (x)?"failed":"ok"
 
@@ -87,7 +85,7 @@
 /* -------------------------------------------------------------------------- 
*/
 inline int setPropTRCS(uint32_t fid, char *key, char *value) {
   int ret; char *aux;
-  if(value) tr(value, editPathStr2, editPathStr1, "", 0);
+  if(value) unescape(value, editPathStr1, editPathStr2);
   aux = utf8_from_codeset(value);
   ret = lk_properties_set_property(fid, key, aux);
   free(aux); return ret; 
@@ -120,7 +118,7 @@
   if(data) {
     if(strcmp(data, UnkName)) {
       aux = strdup(data);
-      tr(aux, editPathStr2, editPathStr1, "", 0);
+      unescape(aux, editPathStr1, editPathStr2);
       aux = utf8_from_codeset(aux);
     }
   }
@@ -223,7 +221,7 @@
       if(G&&genre) {*(genre)  = '\0'; genre++;     artist = strchr(genre, 
'/');}
       if(artist)   {*(artist) = '\0'; artist++;    source = 
strchr(artist,'/');}
       if(source)   {*(source) = '\0'; source++;     title = 
strchr(source,'/');}
-      if(title)    {*(title)  = '\0'; title++;      codec = strchr(title, '.');
+      if(title)    {*(title)  = '\0'; title++;      codec = strrchr(title, 
'.');
         if(codec)  {*(codec)  = '\0'; codec++;}
       }
       if(codec && strcmp(codec,"ogg")==0) {
@@ -596,14 +594,21 @@
     }
     if(vc) {
       for(j=0; (fid=vc[j])!=0; j++) {
-       aux = getPropCS(fid, key);  
-       name = (aux && strlen(aux))?strdup(aux):strdup(UnkName);
+        aux = getPropCS(fid, key);  
+        if (aux && strlen(aux)) {
+          lname = strlen(aux);
+          name = malloc(2*lname+6);
+          memcpy(name, aux, lname+1);
+        } else {
+          lname = strlen(UnkName);
+          name = malloc(2*lname+6);
+          memcpy(name, UnkName, lname+16);
+        }
 ///    if(aux) name = strlen(aux)?strdup(aux):strdup(UnkName);
 ///    else    name = NULL;
         free(aux);
 /*      fprintf(stderr, "-1-> %d %d %s %s\n", j, fid, key, name); */
        if(name) {
-         lname = strlen(name); name = realloc(name, lname + 16);
          aux = malloc(lname + 9); aux[0] = '\0';
          strcat(aux, "\n"); strcat(aux, name); 
          if(codec) strcat(aux, codec);  strcat(aux, "\n");
@@ -611,7 +616,7 @@
            if(strlen(rep) < 16200) {strcat(rep, name); strcat(rep,"\n");}
            else fprintf(stderr, "*Warning: too many repeated names\n");
            if(strcmp(type, "taxi") && strcmp(type, "playlist"))
-             tr(name, editPathStr1, editPathStr2, "", 0);
+             escape(name, editPathStr1, editPathStr2);
            if (source) {
              if(codec) free(codec); codec = getPropCS(fid, "codec");
              if (codec) {
@@ -619,10 +624,6 @@
                strncat(name, strcmp(codec, "vorbis")?codec:"ogg", 15);
              }
            }
-           if(strchr(name, '/')) {
-             fprintf(stderr, "*Warning: invalid char in \'%s\' \n", name);
-             tr(name, "", "", "/", 0);
-           }
 /*          fprintf(stderr, "-2-> %d %d %s\n", j, fid, name); */
            if (filler(buf, name, NULL, 0)) break;
          }
@@ -1123,11 +1124,12 @@
   char *host=NULL;
   char *psw=NULL;                                         /* Rio Karma paswrd 
*/
   char *usercodeset=NULL;
+  char *ptr;
 /*char *usercodeset="ISO8859-15"; */
 /*mtrace();  */
 
-  editPathStr1 = malloc(1); editPathStr1[0] = '\0';
-  editPathStr2 = malloc(1); editPathStr2[0] = '\0';
+  editPathStr1 = TR_FRM;
+  editPathStr2 = TR_TO;
 
   myArgv = malloc(argc*(sizeof(char*)));
   for (i=0;i<argc;i++) {
@@ -1152,8 +1154,22 @@
       else if ((strcmp(argv[i], "-C") == 0) && (i++<argc-1))
        {if(usercodeset) free(usercodeset); usercodeset = strdup(argv[i]);}
       else if ((strcmp(argv[i], "-E") == 0) && (i<argc-2)) {
-       i++; free(editPathStr1); editPathStr1 = strdup(argv[i]);
-       i++; free(editPathStr2); editPathStr2 = strdup(argv[i]);
+       i++; editPathStr1 = strdup(argv[i]);
+       i++; editPathStr2 = strdup(argv[i]);
+        for (ptr = editPathStr1; *ptr != '\0'; ptr++)
+          if (*ptr == '/')
+            goto cont;
+        fprintf(stderr, "ERROR: 1st edit string does not contain "
+                        "a \'/\' character\n");
+        return -1;
+cont:
+        for (ptr = editPathStr2; *ptr != '\0'; ptr++) {
+          if (*ptr == '/') {
+            fprintf(stderr, "ERROR: 2nd edit string contains "
+                            "a \'/\' character\n");
+            return -1;
+          }
+        }
       }
       else myArgv[myArgc++] = strdup(argv[i]);
   }
diff -Nur lkarmafs-0.1.7.orig/lktools/pathedit.c 
lkarmafs-0.1.7/lktools/pathedit.c
--- lkarmafs-0.1.7.orig/lktools/pathedit.c      2006-01-03 15:25:43.000000000 
+0000
+++ lkarmafs-0.1.7/lktools/pathedit.c   2006-07-29 13:05:06.000000000 +0100
@@ -3,176 +3,129 @@
  *
  * Pathname editing
  *
- * Copyright (c) Enrique Vidal 2005, adapted from "tr.c", 
- * Copyright (c) [EMAIL PROTECTED] (Abhijit Menon-Sen) 1998.
+ * Copyright (c) Keith Bennett <[EMAIL PROTECTED]> 2006
  *
  * You may distribute and modify this program under the terms of 
  * the GNU GPL, version 2 or later.
  */
 
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 
-#define ins(p, c) *p++ = c
-#define next(p) *p++
+#define ESC '\\'
 
-int isodigit (char d);
-char esc(char c);
-char *expand(char *str);
-void tr(char *str, char *orig, char *sub, char *del, int squeezeRep);
-
-int isodigit (char d)
+void unescape(char *str, char *escapefrom, char *escapeto)
 {
-    if ('0' <= d && d <= '7') { return 1; }
-    return 0;
-}
+    char *sptr, *ptr, *frm, *to;
 
-char esc(char c)
-{
-    switch (c) {
-    case 'a': c = '\a'; break;
-    case 'b': c = '\b'; break;
-    case 'f': c = '\f'; break;
-    case 'n': c = '\n'; break;
-    case 'r': c = '\r'; break;
-    case 't': c = '\t'; break;
-    case 'v': c = '\v'; break;
-    default:  break;
+    ptr = sptr = str;
+    /* un-hidden files get re-hidden */
+    if (*sptr == '_' && *(sptr+1) == '.') {
+        *ptr++ = '.';
+        sptr += 2;
+    }
+    for (; *sptr != '\0'; sptr++) {
+        if (*sptr == ESC) {
+            sptr++;
+            /* deal with special characters */
+            switch (*sptr) {
+                case ESC: *ptr++ = *sptr; continue;
+                case 'a': *ptr++ = '\a'; continue;
+                case 'b': *ptr++ = '\b'; continue;
+                case 'f': *ptr++ = '\f'; continue;
+                case 'n': *ptr++ = '\n'; continue;
+                case 'r': *ptr++ = '\r'; continue;
+                case 't': *ptr++ = '\t'; continue;
+                case 'v': *ptr++ = '\v'; continue;
+            }
+            *ptr++ = *sptr;
+        } else {
+            *ptr = *sptr;
+            for (frm = escapefrom, to = escapeto; *frm != '\0'; frm++, to++) {
+                if (*sptr == *to) {
+                    *ptr = *frm;
+                    break;
+                }
+            }
+            ptr++;
+        }
+        
     }
-    return (c);
+    *ptr = '\0';
 }
 
-char *expand(char *str)
+void escape(char *str, char *escapefrom, char *escapeto)
 {
-    static char buf[512], num[8];
-    char i, j=0, k, *o = buf, *p = num;
-    int a, class = 0;
-
-    while ((i = next(str))) {
-        switch (i) {
-        case '\\': if (!(k = next(str))) {
-                       fprintf(stderr, "hanging '\\'.\n");
-                       exit(1);
-                   }
-                   else if (tolower(k) == 'x') {
-                       p = num;
-                       if ((k = next(str)) == 0 || !isxdigit(k)) {
-                           fprintf(stderr, "parse error in \\x.\n");
-                           exit(1);
-                       }
-                       *p++ = k; *p = 0; a = strtol(num, NULL, 16);
-                       if ((k = next(str)) == 0 || !isxdigit(k)) {
-                           ins(o, (char)a); str--;
-                       }
-                       else {
-                           *p++ = k; *p = 0; a = strtol(num, NULL, 16);
-                           ins(o, (char)a);
-                       }
-                   }
-                   else if (isodigit(k)) {
-                       p = num;
-                       *p++ = k; *p = 0; a = strtol(num, NULL, 8);
-                       if ((k = next(str)) == 0 || !isodigit(k)) {
-                           ins(o, (char)a); str--;
-                       }
-                       else {
-                           *p++ = k; *p = 0; a = strtol(num, NULL, 8);
-                           if ((k = next(str)) == 0 || !isodigit(k)) {
-                               ins(o, (char)a); str--;
-                           }
-                           else {
-                               *p++ = k; *p = 0; a = strtol(num, NULL, 8);
-                               ins(o, (char)a);
-                           }
-                       }
-                   }
-                   else { ins(o, esc(k)); }
-                   break;
-        case '[':  if (++class > 1) {
-                       fprintf(stderr, "* Literal [ inside character 
class.\n");
-                       exit(1);
-                   }
-                   break;
-        case '.':  if (!class) { ins(o, '.'); }
-                   else {
-                       for (a = 0x20; a < 0x7f; ++a) { ins(o, (char)a); }
-                   }
-                   break;
-        case '-':  if (!class || (k = next(str)) == ']') {
-                       ins(o, '-');
-                       if (class) { class--; }
-                   }
-                   else {
-                       if (j < k) {
-                           for (i = j+1; i <= k; ++i) { ins(o, i); }
-                       }
-                       else if (k < j) {
-                           for (i = j-1; i >= k; --i) { ins(o, i); }
-                       }
-                   }
-                   break;
-        case ']':  if (--class) {
-                       fprintf(stderr,"* literal ] outside character 
class.\n");
-                       exit(1);
-                   }
-                   break;
-        default:   ins(o, i);
+    int num = 0, edit = 0;
+    char *ptr, *nptr, *frm, *to;
+
+    /* hidden files get un-hidden */
+    if (*str == '.')
+        num++;
+
+    /* count the number of characters to be escaped */
+    for (ptr = str; *ptr != '\0'; ptr++) {
+        /* deal with special characters */
+        switch (*ptr) {
+            case  ESC:
+            case '\a':
+            case '\b':
+            case '\f':
+            case '\n':
+            case '\r':
+            case '\t':
+            case '\v':
+                edit = 1;
+                num++;
+                continue;
+        }
+        for (to = escapeto, frm = escapefrom; *to != '\0'; to++, frm++) {
+            if (*ptr == *to) {
+                edit = 1;
+                num++;
+                break;
+            } else if (*ptr == *frm) {
+                edit = 1;
+                break;
+            }
         }
-        j = i;
     }
-    ins(o, 0);
-    return (buf);
-}
 
-void tr(char *str, char *orig, char *sub, char *del, int squeezeRep)
-{
-    char c, a[1024], b[1024], d[1024];
-    int tab[256], i, cc, s1, s2;
-    char *q, *p=str;
+    if (edit == 0)
+        return;
 
-    for (i = 0; i < 256; ++i) {
-        tab[i] = i;
-    }
-    strcpy(a, expand(orig));
-    strcpy(b, expand(sub));
-    strcpy(d, expand(del));
-    s1 = strlen(a);
-    s2 = strlen(b);
-
-    for (i = 0; i < s1; ++i) {
-        cc=(int)a[i]; cc = (cc<0)?cc+256:cc;
-        tab[cc] = i < s2 ? b[i] : b[s2 - 1];
-/*      tab[(int)a[i]] = i < s2 ? b[i] : b[s2 - 1]; */
-    }
-    while ((c = *str)) {
-        cc = (c<0)?c+256:c;
-        *str++ = tab[cc];
-    }
-/*  /////////////// Moved AFTER delete
-    if (squeezeRep) {
-      q=str=p;
-      while ((c = *str)) {
-      *str++;
-      if ((c != *str) || (strchr(b, c)==NULL)) {*q++; *q=*str;}
-      }
-    }
-*/
-    if(del && (strlen(del)>0)) {
-      q=str=p;
-      while ((c = *str)) {
-       if ((strchr(d, c)==NULL)) *q++=*str;
-       *str++;
-      }
-      *q='\0';
-    }
-    if (squeezeRep) {
-      q=str=p;
-      while ((c = *str)) {
-       *str++;
-       if ((c != *str) || (strchr(b, c)==NULL)) {*q++; *q=*str;}
-      }
+    /* overwrite the string, starting from the end and working backwards */
+    nptr = str+strlen(str)+num+1;
+    *nptr-- = '\0';
+    for (ptr = str+strlen(str); ptr >= str; ptr--) {
+        /* deal with special characters */
+        switch (*ptr) {
+            case  ESC: *nptr-- = ESC; *nptr-- = ESC; continue;
+            case '\a': *nptr-- = 'a'; *nptr-- = ESC; continue;
+            case '\b': *nptr-- = 'b'; *nptr-- = ESC; continue;
+            case '\f': *nptr-- = 'f'; *nptr-- = ESC; continue;
+            case '\n': *nptr-- = 'n'; *nptr-- = ESC; continue;
+            case '\r': *nptr-- = 'r'; *nptr-- = ESC; continue;
+            case '\t': *nptr-- = 't'; *nptr-- = ESC; continue;
+            case '\v': *nptr-- = 'v'; *nptr-- = ESC; continue;
+        }
+        for (frm = escapefrom, to = escapeto; *frm != '\0'; frm++, to++) {
+            if (*ptr == *frm) {
+                *nptr-- = *to;
+                goto next;
+            } else if (*ptr == *to) {
+                *nptr-- = *to;
+                *nptr-- = ESC;
+                goto next;
+            }
+        }
+        *nptr-- = *ptr;
+next:
+        continue;
     }
+
+    /* hidden files get un-hidden */
+    if (*str == '.')
+        *str = '_';
+
+    return;
 }
-/* -------------------------- End pathname editing -------------------------- 
*/
diff -Nur lkarmafs-0.1.7.orig/lktools/pathedit.h 
lkarmafs-0.1.7/lktools/pathedit.h
--- lkarmafs-0.1.7.orig/lktools/pathedit.h      2006-01-03 15:25:43.000000000 
+0000
+++ lkarmafs-0.1.7/lktools/pathedit.h   2006-07-18 01:09:51.000000000 +0100
@@ -3,8 +3,7 @@
  *
  * Pathname editing
  *
- * Copyright (c) Enrique Vidal 2005, adapted from "tr.c", 
- * Copyright (c) [EMAIL PROTECTED] (Abhijit Menon-Sen) 1998.
+ * Copyright (c) Keith Bennett <[EMAIL PROTECTED]> 2006
  *
  * You may distribute and modify this program under the terms of 
  * the GNU GPL, version 2 or later.
@@ -12,6 +11,7 @@
 #ifndef _PATHEDIT_H
 #define _PATHEDIT_H
 
-void tr(char *str, char *orig, char *sub, char *del, int squeezeRep);
+void   escape(char *str, char *escapefrom, char *escapeto);
+void unescape(char *str, char *escapefrom, char *escapeto);
 
 #endif
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-karma-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-karma-devel

Reply via email to