aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xsls.c
blob: 4d3b1aa1af4913c99ec337a6b3e736739cc86389 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <xs.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/ioctl.h>

static int max_width = 80;
static int desired_width = 60;

#define TAG " = \"...\""
#define TAG_LEN strlen(TAG)

#define MIN(a, b) (((a) < (b))? (a) : (b))

void print_dir(struct xs_handle *h, char *path, int cur_depth, int show_perms)
{
    char **e;
    char newpath[512], *val;
    int i;
    unsigned int num, len;

    e = xs_directory(h, XBT_NULL, path, &num);
    if (e == NULL)
        err(1, "xs_directory (%s)", path);

    for (i = 0; i<num; i++) {
        char buf[MAX_STRLEN(unsigned int)+1];
        struct xs_permissions *perms;
        unsigned int nperms;
        int linewid;

        for (linewid=0; linewid<cur_depth; linewid++) putchar(' ');
        linewid += printf("%.*s",
                          (int) (max_width - TAG_LEN - linewid), e[i]);
        sprintf(newpath, "%s%s%s", path, 
                path[strlen(path)-1] == '/' ? "" : "/", 
                e[i]);
        val = xs_read(h, XBT_NULL, newpath, &len);
        if (val == NULL) {
            printf(":\n");
        }
        else {
            if (max_width < (linewid + len + TAG_LEN)) {
                printf(" = \"%.*s...\"",
                       (int)(max_width - TAG_LEN - linewid), val);
            }
            else {
                linewid += printf(" = \"%s\"", val);
                if (show_perms) {
                    putchar(' ');
                    for (linewid++;
                         linewid < MIN(desired_width, max_width);
                         linewid++)
                        putchar((linewid & 1)? '.' : ' ');
                }
            }
        }
        free(val);

        if (show_perms) {
            perms = xs_get_permissions(h, XBT_NULL, newpath, &nperms);
            if (perms == NULL) {
                warn("\ncould not access permissions for %s", e[i]);
            }
            else {
                int i;
                fputs("  (", stdout);
                for (i = 0; i < nperms; i++) {
                    if (i)
                        putchar(',');
                    xs_perm_to_string(perms+i, buf);
                    fputs(buf, stdout);
                }
                putchar(')');
            }
        }

        putchar('\n');
            
        print_dir(h, newpath, cur_depth+1, show_perms); 
    }
    free(e);
}

void usage(int argc, char *argv[])
{
    fprintf(stderr, "Usage: %s [-p] [path]\n", argv[0]);
}

int main(int argc, char *argv[])
{
    struct winsize ws;
    int ret;
    int c;
    int show_perm = 0;

    struct xs_handle *xsh = xs_daemon_open();

    if (xsh == NULL)
        err(1, "xs_daemon_open");

#define PAD 2

    memset(&ws, 0, sizeof(ws));
    ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
    if (!ret)
        max_width = ws.ws_col - PAD;

    while (0 < (c = getopt(argc, argv, "p"))) {
        switch (c) {
        case 'p':
            show_perm = 1;
            max_width -= 16;
            break;
        case ':':
        case '?':
        default:
            usage(argc, argv);
            return 0;
        }
    }

    print_dir(xsh, (argc - optind) == 1 ? argv[optind] : "/", 0, show_perm);

    return 0;
}