]> arthur.barton.de Git - netatalk.git/commitdiff
Merge branch 'develop' into ad_set
authorFrank Lahm <franklahm@googlemail.com>
Wed, 11 Apr 2012 08:26:52 +0000 (10:26 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Wed, 11 Apr 2012 08:26:52 +0000 (10:26 +0200)
bin/ad/Makefile.am
bin/ad/ad.c
bin/ad/ad.h
bin/ad/ad_set.c [new file with mode: 0644]

index 7e6fe922b911db850841a15d3e7e72eb6d3cf491..5c3f47b67f918c634dc9247d97d3c70e42896f5c 100644 (file)
@@ -12,7 +12,8 @@ ad_SOURCES = \
        ad_ls.c \
        ad_cp.c \
        ad_mv.c \
-       ad_rm.c
+       ad_rm.c \
+       ad_set.c
 
 ad_CFLAGS = -D_PATH_AD=\"$(bindir)/ad\"
 
index 883378f58f68b2217feccb8c805f6df2883148b1..083bb62ae3905f0562706ea06dc986e92b5e6902 100644 (file)
@@ -35,7 +35,7 @@
 
 static void usage_main(void)
 {
-    printf("Usage: ad ls|cp|rm|mv|find [file|dir, ...]\n");
+    printf("Usage: ad ls|cp|rm|mv|set|find [file|dir, ...]\n");
     printf("       ad -v|--version\n");
 }
 
@@ -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;
 
@@ -69,6 +69,8 @@ int main(int argc, char **argv)
         return ad_rm(argc - 1, argv + 1, &obj);
     else if (STRCMP(argv[1], ==, "mv"))
         return ad_mv(argc, argv, &obj);
+    else if (STRCMP(argv[1], ==, "set"))
+        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 */
diff --git a/bin/ad/ad_set.c b/bin/ad/ad_set.c
new file mode 100644 (file)
index 0000000..d41d522
--- /dev/null
@@ -0,0 +1,331 @@
+/* 
+   Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
+   
+   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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <time.h>
+
+#include <atalk/adouble.h>
+#include <atalk/cnid.h>
+#include "ad.h"
+
+#define ADv2_DIRNAME ".AppleDouble"
+
+#define DIR_DOT_OR_DOTDOT(a)                            \
+    ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
+
+static const char *labels[] = {
+    "none",
+    "grey",
+    "green",
+    "violet",
+    "blue",
+    "yellow",
+    "red",
+    "orange",
+    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 [-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"
+        "       n = No INIT resources (f)\n"
+        "       i = Inited (f/d)\n"
+        "       c = Custom icon (f/d)\n"
+        "       t = Stationery (f)\n"
+        "       s = Name locked (f/d)\n"
+        "       b = Bundle (f/d)\n"
+        "       v = Invisible (f/d)\n"
+        "       a = Alias file (f/d)\n\n"
+        "     AFPAttributes:\n"
+        "       y = System (f/d)\n"
+        "       w = No write (f)\n"
+        "       p = Needs backup (f/d)\n"
+        "       r = No rename (f/d)\n"
+        "       l = No delete (f/d)\n"
+        "       o = No copy (f)\n\n"
+        "     Uppercase letter sets the flag, lowercase removes the flag\n"
+        "     f = valid for files\n"
+        "     d = valid for directories\n"
+
+        );
+}
+
+static void change_type(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_type)
+{
+    char *FinderInfo;
+
+    if ((FinderInfo = ad_entry(ad, ADEID_FINDERI)))
+        memcpy(FinderInfo, new_type, 4);
+}
+
+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);
+
+}
+
+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;
+
+    while (*color) {
+        if (strcasecmp(*color, new_label) == 0) {
+            /* get flags */
+            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++;
+    }
+}
+
+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);
+    AFPattributes = ntohs(AFPattributes);
+
+    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;
+    }
+
+    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;
+    }
+
+    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;
+
+    FinderFlags = ntohs(FinderFlags);
+    memcpy(FinderInfo + 8, &FinderFlags, 2);
+}
+
+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, ":l:t:c:f:a:")) != -1) {
+        switch(c) {
+        case 'l':
+            new_label = strdup(optarg);
+            break;
+        case 't':
+            new_type = strdup(optarg);
+            break;
+        case 'c':
+            new_creator = strdup(optarg);
+            break;
+        case 'f':
+            new_flags = strdup(optarg);
+            break;
+        case 'a':
+            new_attributes = strdup(optarg);
+            break;
+        case ':':
+        case '?':
+            usage_set();
+            return -1;
+            break;
+        }
+
+    }
+
+    if (argc <= optind)
+        exit(1);
+
+    cnid_init();
+
+    openvol(obj, argv[optind], &vol);
+    if (vol.vol->v_path == NULL)
+        exit(1);
+
+    if (stat(argv[optind], &st) != 0) {
+        perror("stat");
+        exit(1);
+    }
+
+    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;
+}