Line data Source code
1 : #include "../burp.h"
2 : #include "../action.h"
3 : #include "../asfd.h"
4 : #include "../async.h"
5 : #include "../attribs.h"
6 : #include "../cmd.h"
7 : #include "../handy.h"
8 : #include "../log.h"
9 :
10 : /* Note: The chars in this function are not the same as in the CMD_ set.
11 : These are for printing to the screen only. */
12 0 : static char *encode_mode(mode_t mode, char *buf)
13 : {
14 0 : char *cp=buf;
15 0 : *cp++=S_ISDIR(mode)?'d':S_ISBLK(mode)?'b':S_ISCHR(mode)?'c':
16 0 : S_ISLNK(mode)?'l':S_ISFIFO(mode)?'p':S_ISSOCK(mode)?'s':'-';
17 0 : *cp++=mode&S_IRUSR?'r':'-';
18 0 : *cp++=mode&S_IWUSR?'w':'-';
19 0 : *cp++=(mode&S_ISUID?(mode&S_IXUSR?'s':'S'):(mode&S_IXUSR?'x':'-'));
20 0 : *cp++=mode&S_IRGRP?'r':'-';
21 0 : *cp++=mode&S_IWGRP?'w':'-';
22 0 : *cp++=(mode&S_ISGID?(mode&S_IXGRP?'s':'S'):(mode&S_IXGRP?'x':'-'));
23 0 : *cp++=mode&S_IROTH?'r':'-';
24 0 : *cp++=mode&S_IWOTH?'w':'-';
25 0 : *cp++=(mode&S_ISVTX?(mode&S_IXOTH?'t':'T'):(mode&S_IXOTH?'x':'-'));
26 0 : *cp='\0';
27 0 : return cp;
28 : }
29 :
30 0 : void ls_to_buf(char *lsbuf, struct sbuf *sb)
31 : {
32 : int n;
33 : char *p;
34 : time_t time;
35 : const char *f;
36 0 : struct stat *statp=&sb->statp;
37 0 : *lsbuf='\0';
38 :
39 0 : p=encode_mode(statp->st_mode, lsbuf);
40 0 : n=sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
41 0 : p+=n;
42 : n=sprintf(p, "%5d %5d", (uint32_t)statp->st_uid,
43 0 : (uint32_t)statp->st_gid);
44 0 : p+=n;
45 0 : n=sprintf(p, " %7lu ", (unsigned long)statp->st_size);
46 0 : p+=n;
47 0 : if(statp->st_ctime>statp->st_mtime) time=statp->st_ctime;
48 0 : else time=statp->st_mtime;
49 :
50 : // Display most recent time.
51 0 : p=encode_time(time, p);
52 0 : *p++=' ';
53 0 : for(f=sb->path.buf; *f; ) *p++=*f++;
54 0 : *p=0;
55 0 : }
56 :
57 0 : static void ls_long_output(struct sbuf *sb)
58 : {
59 : static char lsbuf[2048];
60 0 : ls_to_buf(lsbuf, sb);
61 : printf("%s", lsbuf);
62 0 : if(sb->link.buf) printf(" -> %s", sb->link.buf);
63 : printf("\n");
64 0 : }
65 :
66 : static void ls_short_output(struct sbuf *sb)
67 : {
68 0 : printf("%s\n", sb->path.buf);
69 : }
70 :
71 0 : static void list_item(enum action act, struct sbuf *sb)
72 : {
73 0 : if(act==ACTION_LIST_LONG)
74 : {
75 0 : ls_long_output(sb);
76 : }
77 : else
78 : {
79 0 : ls_short_output(sb);
80 : }
81 0 : }
82 :
83 0 : int do_list_client(struct asfd *asfd, enum action act, struct conf **confs)
84 : {
85 0 : int ret=-1;
86 0 : char msg[512]="";
87 0 : struct sbuf *sb=NULL;
88 0 : struct iobuf *rbuf=asfd->rbuf;
89 0 : const char *backup=get_string(confs[OPT_BACKUP]);
90 0 : const char *backup2=get_string(confs[OPT_BACKUP2]);
91 0 : const char *browsedir=get_string(confs[OPT_BROWSEDIR]);
92 0 : const char *regex=get_string(confs[OPT_REGEX]);
93 : //logp("in do_list\n");
94 :
95 0 : switch(act)
96 : {
97 : case ACTION_LIST:
98 : case ACTION_LIST_LONG:
99 0 : if(browsedir && regex)
100 : {
101 0 : logp("You cannot specify both a directory and a regular expression when listing.\n");
102 0 : goto end;
103 : }
104 0 : if(browsedir)
105 : snprintf(msg, sizeof(msg), "listb %s:%s",
106 0 : backup?backup:"", browsedir);
107 : else
108 : snprintf(msg, sizeof(msg), "list %s:%s",
109 0 : backup?backup:"", regex?regex:"");
110 : break;
111 : case ACTION_DIFF:
112 : case ACTION_DIFF_LONG:
113 : snprintf(msg, sizeof(msg), "diff %s:%s",
114 0 : backup?backup:"", backup2?backup2:"");
115 : break;
116 : default:
117 0 : logp("unknown action %d\n", act);
118 0 : goto end;
119 : }
120 0 : if(asfd->write_str(asfd, CMD_GEN, msg)
121 0 : || asfd_read_expect(asfd, CMD_GEN, "ok"))
122 : goto end;
123 :
124 0 : if(!(sb=sbuf_alloc(get_protocol(confs)))) goto end;
125 0 : iobuf_init(&sb->path);
126 0 : iobuf_init(&sb->link);
127 0 : iobuf_init(&sb->attr);
128 :
129 : // This should probably should use the sbuf stuff.
130 : while(1)
131 : {
132 0 : sbuf_free_content(sb);
133 :
134 0 : iobuf_free_content(rbuf);
135 0 : if(asfd->read(asfd)) break;
136 0 : if(rbuf->cmd==CMD_MESSAGE)
137 : {
138 0 : printf("%s\n", rbuf->buf);
139 0 : if(!strcmp(rbuf->buf, "no backups"))
140 0 : ret=0;
141 : goto end;
142 : }
143 0 : else if(rbuf->cmd==CMD_TIMESTAMP)
144 : {
145 : // A backup timestamp, just print it.
146 0 : printf("Backup: %s\n", rbuf->buf);
147 0 : if(browsedir)
148 : printf("Listing directory: %s\n",
149 : browsedir);
150 0 : if(regex)
151 : printf("With regex: %s\n",
152 : regex);
153 : continue;
154 : }
155 0 : else if(rbuf->cmd!=CMD_ATTRIBS)
156 : {
157 0 : iobuf_log_unexpected(rbuf, __func__);
158 0 : goto end;
159 : }
160 0 : iobuf_copy(&sb->attr, rbuf);
161 0 : iobuf_init(rbuf);
162 :
163 0 : attribs_decode(sb);
164 :
165 0 : if(asfd->read(asfd))
166 : {
167 0 : logp("got stat without an object\n");
168 0 : goto end;
169 : }
170 0 : iobuf_copy(&sb->path, rbuf);
171 0 : iobuf_init(rbuf);
172 :
173 0 : if(sb->path.cmd==CMD_DIRECTORY
174 0 : || sb->path.cmd==CMD_FILE
175 0 : || sb->path.cmd==CMD_ENC_FILE
176 0 : || sb->path.cmd==CMD_EFS_FILE
177 0 : || sb->path.cmd==CMD_SPECIAL)
178 : {
179 0 : list_item(act, sb);
180 : }
181 0 : else if(cmd_is_link(sb->path.cmd)) // symlink or hardlink
182 : {
183 0 : if(asfd->read(asfd)
184 0 : || rbuf->cmd!=sb->path.cmd)
185 : {
186 : logp("could not get link %c:%s\n",
187 0 : sb->path.cmd, sb->path.buf);
188 0 : goto end;
189 : }
190 0 : iobuf_copy(&sb->link, rbuf);
191 0 : iobuf_init(rbuf);
192 0 : list_item(act, sb);
193 : }
194 : else
195 : {
196 : logp("unlistable %c:%s\n",
197 0 : sb->path.cmd, sb->path.buf?sb->path.buf:"");
198 : }
199 : }
200 :
201 : ret=0;
202 : end:
203 0 : sbuf_free(&sb);
204 0 : if(!ret) logp("List finished ok\n");
205 0 : return ret;
206 : }
|