]> arthur.barton.de Git - netatalk.git/commitdiff
Working ad set
authorFrank Lahm <franklahm@googlemail.com>
Wed, 11 Apr 2012 08:24:49 +0000 (10:24 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Wed, 11 Apr 2012 08:24:49 +0000 (10:24 +0200)
bin/ad/ad.c
bin/ad/ad.h
bin/ad/ad_set.c

index 078989fca081f8ac2a793ee666ecf3b15b75b5c8..3433e1b624c692340ae3f2e81c5cba7093a64a26 100644 (file)
@@ -48,8 +48,6 @@ int main(int argc, char **argv)
 {
     AFPObj obj = { 0 };
 
-    setuplog("default:note", "/dev/tty");
-
     if (argc < 2) {
         usage_main();
         return 1;
@@ -58,6 +56,8 @@ int main(int argc, char **argv)
     if (afp_config_parse(&obj) != 0)
         return 1;
 
+    setuplog("default:note", "/dev/tty");
+
     if (load_volumes(&obj, NULL) != 0)
         return 1;
 
@@ -70,7 +70,7 @@ int main(int argc, char **argv)
     else if (STRCMP(argv[1], ==, "mv"))
         return ad_mv(argc, argv, &obj);
     else if (STRCMP(argv[1], ==, "set"))
-        return ad_set(argc, argv, &obj);
+        return ad_set(argc - 1, argv + 1, &obj);
     else if (STRCMP(argv[1], ==, "find"))
         return ad_find(argc, argv, &obj);
     else if (STRCMP(argv[1], ==, "-v")) {
index c405ef680bb4cdbf17b86dc7fd26785e0401cc5c..3195641f7cb291c78e66d580a4d3a047f9d53997 100644 (file)
@@ -61,9 +61,9 @@ extern void _log(enum logtype lt, char *fmt, ...);
 
 extern int ad_ls(int argc, char **argv, AFPObj *obj);
 extern int ad_cp(int argc, char **argv, AFPObj *obj);
-
 extern int ad_rm(int argc, char **argv, AFPObj *obj);
 extern int ad_mv(int argc, char **argv, AFPObj *obj);
+extern int ad_set(int argc, char **argv, AFPObj *obj);
 extern int ad_find(int argc, char **argv, AFPObj *obj);
 
 /* ad_util.c */
index 1a2cac887c189d76d20624322f6911b2d4d4adbf..d41d5222040d8dce083e9e191d0a8807c71db990 100644 (file)
 
 #define ADv2_DIRNAME ".AppleDouble"
 
-#define DIR_DOT_OR_DOTDOT(a) \
-        ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
-
-static volatile sig_atomic_t alarmed;
-
-/* ls options */
-static int ls_a;
-static int ls_l;
-static int ls_R;
-static int ls_d;
-static int ls_u;
-
-/* Used for pretty printing */
-static int first = 1;
-static int recursion;
-
-static char           *netatalk_dirs[] = {
-    ADv2_DIRNAME,
-    ".AppleDB",
-    ".AppleDesktop",
-    NULL
-};
-
-static char *labels[] = {
-    "---",
-    "gry",
-    "gre",
-    "vio",
-    "blu",
-    "yel",
+#define DIR_DOT_OR_DOTDOT(a)                            \
+    ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
+
+static const char *labels[] = {
+    "none",
+    "grey",
+    "green",
+    "violet",
+    "blue",
+    "yellow",
     "red",
-    "ora"
+    "orange",
+    NULL
 };
 
-/*
-  SIGNAL handling:
-  catch SIGINT and SIGTERM which cause clean exit. Ignore anything else.
-*/
-
-static void sig_handler(int signo)
-{
-    alarmed = 1;
-    return;
-}
-
-static void set_signal(void)
-{
-    struct sigaction sv;
-
-    sv.sa_handler = sig_handler;
-    sv.sa_flags = SA_RESTART;
-    sigemptyset(&sv.sa_mask);
-    if (sigaction(SIGTERM, &sv, NULL) < 0)
-        ERROR("error in sigaction(SIGTERM): %s", strerror(errno));
-
-    if (sigaction(SIGINT, &sv, NULL) < 0)
-        ERROR("error in sigaction(SIGINT): %s", strerror(errno));
-
-    memset(&sv, 0, sizeof(struct sigaction));
-    sv.sa_handler = SIG_IGN;
-    sigemptyset(&sv.sa_mask);
-
-    if (sigaction(SIGABRT, &sv, NULL) < 0)
-        ERROR("error in sigaction(SIGABRT): %s", strerror(errno));
-
-    if (sigaction(SIGHUP, &sv, NULL) < 0)
-        ERROR("error in sigaction(SIGHUP): %s", strerror(errno));
-
-    if (sigaction(SIGQUIT, &sv, NULL) < 0)
-        ERROR("error in sigaction(SIGQUIT): %s", strerror(errno));
-}
-
-/*
-  Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
-  Returns pointer to name or NULL.
-*/
-static const char *check_netatalk_dirs(const char *name)
-{
-    int c;
-
-    for (c=0; netatalk_dirs[c]; c++) {
-        if ((strcmp(name, netatalk_dirs[c])) == 0)
-            return netatalk_dirs[c];
-    }
-    return NULL;
-}
-
+static char *new_label;
+static char *new_type;
+static char *new_creator;
+static char *new_flags;
+static char *new_attributes;
 
 static void usage_set(void)
 {
     printf(
-        "Usage: ad set file|dir [-t TYPE] [-c CREATOR] [-l label] [-f flags]\n\n"
-        "     FinderFlags (valid for (f)ile and/or (d)irectory):\n"
+        "Usage: ad set [-t TYPE] [-c CREATOR] [-l label] [-f flags] [-a attributes] file|dir \n\n"
+        "     Color Label:\n"
+        "       none | grey | green | violet | blue | yellow | red | orange\n\n"
+        "     FinderFlags:\n"
         "       d = On Desktop (f/d)\n"
         "       e = Hidden extension (f/d)\n"
         "       m = Shared (can run multiple times) (f)\n"
@@ -148,270 +83,249 @@ static void usage_set(void)
         "       r = No rename (f/d)\n"
         "       l = No delete (f/d)\n"
         "       o = No copy (f)\n\n"
-        "     Note: any letter appearing in uppercase means the flag is set\n"
-        "           but it's a directory for which the flag is not allowed.\n"
+        "     Uppercase letter sets the flag, lowercase removes the flag\n"
+        "     f = valid for files\n"
+        "     d = valid for directories\n"
+
         );
 }
 
-static void print_flags(char *path, afpvol_t *vol, const struct stat *st)
+static void change_type(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_type)
 {
-    int adflags = 0;
-    struct adouble ad;
     char *FinderInfo;
-    uint16_t FinderFlags;
-    uint16_t AFPattributes;
-    char type[5] = "----";
-    char creator[5] = "----";
-    int i;
-    uint32_t cnid;
 
-    if (S_ISDIR(st->st_mode))
-        adflags = ADFLAGS_DIR;
+    if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
+        memcpy(FinderInfo, new_type, 4);
+}
 
-    if (vol->vol->v_path == NULL)
-        return;
+static void change_creator(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_creator)
+{
+    char *FinderInfo;
+
+    if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
+        memcpy(FinderInfo + 4, new_creator, 4);
 
-    ad_init(&ad, vol->vol);
+}
 
-    if ( ad_metadata(path, adflags, &ad) < 0 )
+static void change_label(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_label)
+{
+    char *FinderInfo;
+    const char **color = &labels[0];
+    uint16_t FinderFlags;
+    unsigned char color_count = 0;
+
+    if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
         return;
 
-    FinderInfo = ad_entry(&ad, ADEID_FINDERI);
+    while (*color) {
+        if (strcasecmp(*color, new_label) == 0) {
+            /* get flags */
+            memcpy(&FinderFlags, FinderInfo + 8, 2);
+            FinderFlags = ntohs(FinderFlags);
 
-    memcpy(&FinderFlags, FinderInfo + 8, 2);
-    FinderFlags = ntohs(FinderFlags);
+            /* change value */
+            FinderFlags &= ~FINDERINFO_COLOR;
+            FinderFlags |= color_count << 1;
+
+            /* copy it back */
+            FinderFlags = ntohs(FinderFlags);
+            memcpy(FinderInfo + 8, &FinderFlags, 2);
+
+            break;
+        }
+        color++;
+        color_count++;
+    }
+}
 
-    memcpy(type, FinderInfo, 4);
-    memcpy(creator, FinderInfo + 4, 4);
+static void change_attributes(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_attributes)
+{
+    char *FinderInfo;
+    uint16_t AFPattributes;
 
-    ad_getattr(&ad, &AFPattributes);
+    ad_getattr(ad, &AFPattributes);
     AFPattributes = ntohs(AFPattributes);
 
-    /*
-      Finder flags. Lowercase means valid, uppercase means invalid because
-      object is a dir and flag is only valid for files.
-    */
-    putchar(' ');
-    if (FinderFlags & FINDERINFO_ISONDESK)
-        putchar('d');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_HIDEEXT)
-        putchar('e');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_ISHARED) {
-        if (adflags & ADFLAGS_DIR)
-            putchar('M');
-        else
-            putchar('m');
-    } else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_HASNOINITS) {
-        if (adflags & ADFLAGS_DIR)
-            putchar('N');
-        else
-            putchar('n');
-    } else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_HASBEENINITED)
-        putchar('i');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_HASCUSTOMICON)
-        putchar('c');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_ISSTATIONNERY) {
-        if (adflags & ADFLAGS_DIR)
-            putchar('T');
-        else
-            putchar('t');
-    } else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_NAMELOCKED)
-        putchar('s');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_HASBUNDLE)
-        putchar('b');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_INVISIBLE)
-        putchar('v');
-    else
-        putchar('-');
-
-    if (FinderFlags & FINDERINFO_ISALIAS)
-        putchar('a');
-    else
-        putchar('-');
-
-    putchar(' ');
-
-    /* AFP attributes */
-    if (AFPattributes & ATTRBIT_SYSTEM)
-        putchar('y');
-    else
-        putchar('-');
-
-    if (AFPattributes & ATTRBIT_NOWRITE) {
-        if (adflags & ADFLAGS_DIR)
-            putchar('W');
-        else
-            putchar('w');
-    } else
-        putchar('-');
-
-    if (AFPattributes & ATTRBIT_BACKUP)
-        putchar('p');
-    else
-        putchar('-');
-
-    if (AFPattributes & ATTRBIT_NORENAME)
-        putchar('r');
-    else
-        putchar('-');
-
-    if (AFPattributes & ATTRBIT_NODELETE)
-        putchar('l');
-    else
-        putchar('-');
-
-    if (AFPattributes & ATTRBIT_NOCOPY) {
-        if (adflags & ADFLAGS_DIR)
-            putchar('O');
-        else
-            putchar('o');                
-    } else
-        putchar('-');
-
-    /* Color */
-    printf(" %s ", labels[(FinderFlags & FINDERINFO_COLOR) >> 1]);
-
-    /* Type & Creator */
-    for(i=0; i<4; i++) {
-        if (isalnum(type[i]))
-            putchar(type[i]);
-        else
-            putchar('-');
+    if (S_ISREG(st->st_mode)) {
+        if (strchr(new_attributes, 'W'))
+            AFPattributes |= ATTRBIT_NOWRITE;
+        if (strchr(new_attributes, 'w'))
+            AFPattributes &= ~ATTRBIT_NOWRITE;
+
+        if (strchr(new_attributes, 'O'))
+            AFPattributes |= ATTRBIT_NOCOPY;
+        if (strchr(new_attributes, 'o'))
+            AFPattributes &= ~ATTRBIT_NOCOPY;
     }
-    putchar(' '); 
-    for(i=0; i<4; i++) {
-        if (isalnum(creator[i]))
-            putchar(creator[i]);
-        else
-            putchar('-');
+
+    if (strchr(new_attributes, 'Y'))
+        AFPattributes |= ATTRBIT_SYSTEM;
+    if (strchr(new_attributes, 'y'))
+        AFPattributes &= ~ATTRBIT_SYSTEM;
+
+    if (strchr(new_attributes, 'P'))
+        AFPattributes |= ATTRBIT_BACKUP;
+    if (strchr(new_attributes, 'p'))
+        AFPattributes &= ~ATTRBIT_BACKUP;
+
+    if (strchr(new_attributes, 'R'))
+        AFPattributes |= ATTRBIT_NORENAME;
+    if (strchr(new_attributes, 'r'))
+        AFPattributes &= ~ATTRBIT_NORENAME;
+
+    if (strchr(new_attributes, 'L'))
+        AFPattributes |= ATTRBIT_NODELETE;
+    if (strchr(new_attributes, 'l'))
+        AFPattributes &= ~ATTRBIT_NODELETE;
+
+    AFPattributes = ntohs(AFPattributes);
+    ad_setattr(ad, AFPattributes);
+}
+
+static void change_flags(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_flags)
+{
+    char *FinderInfo;
+    uint16_t FinderFlags;
+
+    if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)) == NULL)
+        return;
+
+    memcpy(&FinderFlags, FinderInfo + 8, 2);
+    FinderFlags = ntohs(FinderFlags);
+
+    if (S_ISREG(st->st_mode)) {
+        if (strchr(new_flags, 'M'))
+            FinderFlags |= FINDERINFO_ISHARED;
+        if (strchr(new_flags, 'm'))
+            FinderFlags &= ~FINDERINFO_ISHARED;
+
+        if (strchr(new_flags, 'N'))
+            FinderFlags |= FINDERINFO_HASNOINITS;
+        if (strchr(new_flags, 'n'))
+            FinderFlags &= ~FINDERINFO_HASNOINITS;
+
+        if (strchr(new_flags, 'T'))
+            FinderFlags |= FINDERINFO_ISSTATIONNERY;
+        if (strchr(new_flags, 't'))
+            FinderFlags &= ~FINDERINFO_ISSTATIONNERY;
     }
-    putchar(' '); 
 
-    /* CNID */
-    cnid = ad_forcegetid(&ad);
-    if (cnid)
-        printf(" %10u ", ntohl(cnid));
-    else
-        printf(" !ADVOL_CACHE ");
+    if (strchr(new_flags, 'D'))
+        FinderFlags |= FINDERINFO_ISONDESK;
+    if (strchr(new_flags, 'd'))
+        FinderFlags &= ~FINDERINFO_ISONDESK;
+
+    if (strchr(new_flags, 'E'))
+        FinderFlags |= FINDERINFO_HIDEEXT;
+    if (strchr(new_flags, 'e'))
+        FinderFlags &= ~FINDERINFO_HIDEEXT;
+
+    if (strchr(new_flags, 'I'))
+        FinderFlags |= FINDERINFO_HASBEENINITED;
+    if (strchr(new_flags, 'i'))
+        FinderFlags &= ~FINDERINFO_HASBEENINITED;
+
+    if (strchr(new_flags, 'C'))
+        FinderFlags |= FINDERINFO_HASCUSTOMICON;
+    if (strchr(new_flags, 'c'))
+        FinderFlags &= ~FINDERINFO_HASCUSTOMICON;
+
+    if (strchr(new_flags, 'S'))
+        FinderFlags |= FINDERINFO_NAMELOCKED;
+    if (strchr(new_flags, 's'))
+        FinderFlags &= ~FINDERINFO_NAMELOCKED;
+
+    if (strchr(new_flags, 'B'))
+        FinderFlags |= FINDERINFO_HASBUNDLE;
+    if (strchr(new_flags, 'b'))
+        FinderFlags &= ~FINDERINFO_HASBUNDLE;
+
+    if (strchr(new_flags, 'V'))
+        FinderFlags |= FINDERINFO_INVISIBLE;
+    if (strchr(new_flags, 'v'))
+        FinderFlags &= ~FINDERINFO_INVISIBLE;
+
+    if (strchr(new_flags, 'A'))
+        FinderFlags |= FINDERINFO_ISALIAS;
+    if (strchr(new_flags, 'a'))
+        FinderFlags &= ~FINDERINFO_ISALIAS;
 
-    ad_close(&ad, ADFLAGS_HF);
+    FinderFlags = ntohs(FinderFlags);
+    memcpy(FinderInfo + 8, &FinderFlags, 2);
 }
 
-int ad_ls(int argc, char **argv, AFPObj *obj)
+int ad_set(int argc, char **argv, AFPObj *obj)
 {
     int c, firstarg;
     afpvol_t vol;
     struct stat st;
+    int adflags = 0;
+    struct adouble ad;
 
-    while ((c = getopt(argc, argv, ":adlRu")) != -1) {
+    while ((c = getopt(argc, argv, ":l:t:c:f:a:")) != -1) {
         switch(c) {
-        case 'a':
-            ls_a = 1;
+        case 'l':
+            new_label = strdup(optarg);
             break;
-        case 'd':
-            ls_d = 1;
+        case 't':
+            new_type = strdup(optarg);
             break;
-        case 'l':
-            ls_l = 1;
+        case 'c':
+            new_creator = strdup(optarg);
             break;
-        case 'R':
-            ls_R = 1;
+        case 'f':
+            new_flags = strdup(optarg);
             break;
-        case 'u':
-            ls_u = 1;
+        case 'a':
+            new_attributes = strdup(optarg);
             break;
         case ':':
         case '?':
-            usage_ls();
+            usage_set();
             return -1;
             break;
         }
 
     }
 
-    set_signal();
+    if (argc <= optind)
+        exit(1);
+
     cnid_init();
 
-    if ((argc - optind) == 0) {
-        openvol(obj, ".", &vol);
-        ad_ls_r(".", &vol);
-        closevol(&vol);
+    openvol(obj, argv[optind], &vol);
+    if (vol.vol->v_path == NULL)
+        exit(1);
+
+    if (stat(argv[optind], &st) != 0) {
+        perror("stat");
+        exit(1);
     }
-    else {
-        int havefile = 0;
-
-        firstarg = optind;
-
-        /* First run: only print files from argv paths */
-        while(optind < argc) {
-            if (stat(argv[optind], &st) != 0)
-                goto next;
-            if (S_ISDIR(st.st_mode))
-                goto next;
-
-            havefile = 1;
-            first = 1;
-            recursion = 0;
-
-            openvol(obj, argv[optind], &vol);
-            ad_ls_r(argv[optind], &vol);
-            closevol(&vol);
-        next:
-            optind++;
-        }
-        if (havefile && (! ls_l))
-            printf("\n");
-
-        /* Second run: print dirs */
-        optind = firstarg;
-        while(optind < argc) {
-            if (stat(argv[optind], &st) != 0)
-                goto next2;
-            if ( ! S_ISDIR(st.st_mode))
-                goto next2;
-            if ((optind > firstarg) || havefile)
-                printf("\n%s:\n", argv[optind]);
-
-            first = 1;
-            recursion = 0;
-
-            openvol(obj, argv[optind], &vol);
-            ad_ls_r(argv[optind], &vol);
-            closevol(&vol);
-
-        next2:
-            optind++;
-        }
 
+    if (S_ISDIR(st.st_mode))
+        adflags = ADFLAGS_DIR;
 
-    }
+    ad_init(&ad, vol.vol);
+
+    if (ad_open(&ad, argv[optind], adflags | ADFLAGS_HF | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666) < 0)
+        goto exit;
+
+    if (new_label)
+        change_label(argv[optind], &vol, &st, &ad, new_label);
+    if (new_type)
+        change_type(argv[optind], &vol, &st, &ad, new_type);
+    if (new_creator)
+        change_creator(argv[optind], &vol, &st, &ad, new_creator);
+    if (new_flags)
+        change_flags(argv[optind], &vol, &st, &ad, new_flags);
+    if (new_attributes)
+        change_attributes(argv[optind], &vol, &st, &ad, new_attributes);
+
+    ad_flush(&ad);
+    ad_close(&ad, ADFLAGS_HF);
+
+exit:
+    closevol(&vol);
 
     return 0;
 }