示例#1
0
/*  wrapper around xs_write
 */
static bool
do_write (xs_handle_t *xsh, char *path, char *data)
{
        static struct expanding_buffer ebuf = { 0, };
        unsigned len;

        expanding_buffer_ensure (&ebuf, strlen (data) + 1);
        unsanitise_value (ebuf.buf, &len, data);
        if (!xs_write (xsh, 0, path, ebuf.buf, len)) {
                syslog (LOG_WARNING,
                        "could not write %s to path %s",
                        data,
                        path);
                return false;
        }
        return true;
}
示例#2
0
static int
perform(enum mode mode, int optind, int argc, char **argv, struct xs_handle *xsh,
        xs_transaction_t xth, int prefix, int tidy, int upto, int recurse, int nr_watches)
{
    switch (mode) {
    case MODE_ls:
	if (optind == argc)
	{
	    optind=0;
	    argc=1;
	    argv[0] = "/";
	}
	break;
    default:
	break;
    }

    while (optind < argc) {
        switch (mode) {
        case MODE_unknown:
            /* CANNOT BE REACHED */
            errx(1, "invalid mode %d", mode);
        case MODE_read: {
            static struct expanding_buffer ebuf;
            unsigned len;
            char *val = xs_read(xsh, xth, argv[optind], &len);
            if (val == NULL) {
                warnx("couldn't read path %s", argv[optind]);
                return 1;
            }
            if (prefix)
                output("%s: ", argv[optind]);
            output("%s\n", sanitise_value(&ebuf, val, len));
            free(val);
            optind++;
            break;
        }
        case MODE_write: {
            static struct expanding_buffer ebuf;
            char *val_spec = argv[optind + 1];
            unsigned len;
            expanding_buffer_ensure(&ebuf, strlen(val_spec)+1);
            unsanitise_value(ebuf.buf, &len, val_spec);
            if (!xs_write(xsh, xth, argv[optind], ebuf.buf, len)) {
                warnx("could not write path %s", argv[optind]);
                return 1;
            }
            optind += 2;
        } break;
        case MODE_rm: {
            /* Remove the specified path.  If the tidy flag is set, then also
               remove any containing directories that are both empty and have no
               value attached, and repeat, recursing all the way up to the root if
               necessary.
            */

            char *slash, *path = argv[optind];

            if (tidy) {
                /* Copy path, because we can't modify argv because we will need it
                   again if xs_transaction_end gives us EAGAIN. */
                char *p = malloc(strlen(path) + 1);
                strcpy(p, path);
                path = p;

            again:
                if (do_rm(path, xsh, xth)) {
                    return 1;
                }

                slash = strrchr(p, '/');
                if (slash) {
                    char *val;
                    unsigned len;
                    *slash = '\0';
                    val = xs_read(xsh, xth, p, &len);
                    if (val && len == 0) {
                        unsigned int num;
                        char ** list = xs_directory(xsh, xth, p, &num);

                        if (list) {
                            free(list);
                            if (num == 0)
                                goto again;
                        }
                    }
                }

                free(path);
            }
            else {
                if (do_rm(path, xsh, xth)) {
                    return 1;
                }
            }

            optind++;
            break;
        }
        case MODE_exists: {
            char *val = xs_read(xsh, xth, argv[optind], NULL);
            if (val == NULL) {
                return 1;
            }
            free(val);
            optind++;
            break;
        }
        case MODE_list: {
            unsigned int i, num;
            char **list = xs_directory(xsh, xth, argv[optind], &num);
            if (list == NULL) {
                warnx("could not list path %s", argv[optind]);
                return 1;
            }
            for (i = 0; i < num; i++) {
                if (prefix)
                    output("%s/", argv[optind]);
                output("%s\n", list[i]);
            }
            free(list);
            optind++;
            break;
        }
        case MODE_ls: {
            do_ls(xsh, argv[optind], 0, prefix);
            optind++;
            break;
        }
        case MODE_chmod: {
            /* save path pointer: */
            char *path = argv[optind++];
            int nperms = argc - optind;
            struct xs_permissions perms[nperms];
            int i;
            for (i = 0; argv[optind]; optind++, i++)
            {
                perms[i].id = atoi(argv[optind]+1);

                switch (argv[optind][0])
                {
                case 'n':
                    perms[i].perms = XS_PERM_NONE;
                    break;
                case 'r':
                    perms[i].perms = XS_PERM_READ;
                    break;
                case 'w':
                    perms[i].perms = XS_PERM_WRITE;
                    break;
                case 'b':
                    perms[i].perms = XS_PERM_READ | XS_PERM_WRITE;
                    break;
                default:
                    errx(1, "Invalid permission specification: '%c'",
                         argv[optind][0]);
                }
            }

            do_chmod(path, perms, nperms, upto, recurse, xsh, xth);
            break;
        }
        case MODE_watch: {
            for (; argv[optind]; optind++) {
                const char *w = argv[optind];

                if (!xs_watch(xsh, w, w))
                    errx(1, "Unable to add watch on %s\n", w);
            }
            do_watch(xsh, nr_watches);
        }
        }
    }

    return 0;
}