View | Details | Raw Unified | Return to bug 1555 | Differences between
and this patch

Collapse All | Expand All

(-)ssh.orig/sftp-common.c (-6 / +151 lines)
Lines 47-58 void Link Here
47
attrib_clear(Attrib *a)
47
attrib_clear(Attrib *a)
48
{
48
{
49
	a->flags = 0;
49
	a->flags = 0;
50
	a->ext_flags = 0;
51
	a->dev = 0;
52
	a->ino = 0;
53
	a->rdev = 0;
50
	a->size = 0;
54
	a->size = 0;
55
	a->blocks = 0;
56
	a->blksize = 0;
51
	a->uid = 0;
57
	a->uid = 0;
52
	a->gid = 0;
58
	a->gid = 0;
53
	a->perm = 0;
59
	a->perm = 0;
60
	a->nlink = 0;
54
	a->atime = 0;
61
	a->atime = 0;
55
	a->mtime = 0;
62
	a->mtime = 0;
63
	a->ctime = 0;
64
	a->atimensec = 0;
65
	a->mtimensec = 0;
66
	a->ctimensec = 0;
56
}
67
}
57
68
58
/* Convert from struct stat to filexfer attribs */
69
/* Convert from struct stat to filexfer attribs */
Lines 61-66 stat_to_attrib(const struct stat *st, At Link Here
61
{
72
{
62
	attrib_clear(a);
73
	attrib_clear(a);
63
	a->flags = 0;
74
	a->flags = 0;
75
	a->ext_flags = 0;
64
	a->flags |= SSH2_FILEXFER_ATTR_SIZE;
76
	a->flags |= SSH2_FILEXFER_ATTR_SIZE;
65
	a->size = st->st_size;
77
	a->size = st->st_size;
66
	a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
78
	a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
Lines 69-76 stat_to_attrib(const struct stat *st, At Link Here
69
	a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
81
	a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
70
	a->perm = st->st_mode;
82
	a->perm = st->st_mode;
71
	a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
83
	a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
84
	a->ext_flags |= SSH2_FXE_EXTATTR_ATIME;
85
	a->ext_flags |= SSH2_FXE_EXTATTR_MTIME;
72
	a->atime = st->st_atime;
86
	a->atime = st->st_atime;
73
	a->mtime = st->st_mtime;
87
	a->mtime = st->st_mtime;
88
	a->ext_flags |= SSH2_FXE_EXTATTR_CTIME;
89
	a->ctime = st->st_ctime;
90
	a->ext_flags |= SSH2_FXE_EXTATTR_ATIMENSEC;
91
	a->atimensec = st->st_atimensec;
92
	a->ext_flags |= SSH2_FXE_EXTATTR_MTIMENSEC;
93
	a->mtimensec = st->st_mtimensec;
94
	a->ext_flags |= SSH2_FXE_EXTATTR_CTIMENSEC;
95
	a->ctimensec = st->st_ctimensec;
96
	a->ext_flags |= SSH2_FXE_EXTATTR_DEV;
97
	a->dev = st->st_dev;
98
	a->ext_flags |= SSH2_FXE_EXTATTR_INO;
99
	a->ino = st->st_ino;
100
	a->ext_flags |= SSH2_FXE_EXTATTR_NLINK;
101
	a->nlink = st->st_nlink;
102
	if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
103
		a->ext_flags |= SSH2_FXE_EXTATTR_RDEV;
104
		a->rdev = st->st_rdev;
105
	}
106
	a->ext_flags |= SSH2_FXE_EXTATTR_BLKSIZE;
107
	a->blksize = st->st_blksize;
108
	a->ext_flags |= SSH2_FXE_EXTATTR_BLOCKS;
109
	a->blocks = st->st_blocks;
74
}
110
}
75
111
76
/* Convert from filexfer attribs to struct stat */
112
/* Convert from filexfer attribs to struct stat */
Lines 87-96 attrib_to_stat(const Attrib *a, struct s Link Here
87
	}
123
	}
88
	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
124
	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
89
		st->st_mode = a->perm;
125
		st->st_mode = a->perm;
90
	if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
126
	if ((a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) ||
127
	    (a->ext_flags & SSH2_FXE_EXTATTR_ATIME))
91
		st->st_atime = a->atime;
128
		st->st_atime = a->atime;
129
	if ((a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) ||
130
	    (a->ext_flags & SSH2_FXE_EXTATTR_MTIME))
92
		st->st_mtime = a->mtime;
131
		st->st_mtime = a->mtime;
93
	}
132
	if (a->ext_flags & SSH2_FXE_EXTATTR_CTIME)
133
		st->st_ctime = a->ctime;
134
	if (a->ext_flags & SSH2_FXE_EXTATTR_ATIMENSEC)
135
		st->st_atimensec = a->atimensec;
136
	if (a->ext_flags & SSH2_FXE_EXTATTR_MTIMENSEC)
137
		st->st_mtimensec = a->mtimensec;
138
	if (a->ext_flags & SSH2_FXE_EXTATTR_CTIMENSEC)
139
		st->st_ctimensec = a->ctimensec;
140
	if (a->ext_flags & SSH2_FXE_EXTATTR_DEV)
141
		st->st_dev = a->dev;
142
	if (a->ext_flags & SSH2_FXE_EXTATTR_INO)
143
		st->st_ino = a->ino;
144
	if (a->ext_flags & SSH2_FXE_EXTATTR_NLINK)
145
		st->st_nlink = a->nlink;
146
	if (a->ext_flags & SSH2_FXE_EXTATTR_RDEV)
147
		st->st_rdev = a->rdev;
148
	if (a->ext_flags & SSH2_FXE_EXTATTR_BLKSIZE)
149
		st->st_blksize = a->blksize;
150
	if (a->ext_flags & SSH2_FXE_EXTATTR_BLOCKS)
151
		st->st_blocks = a->blocks;
152
}
153
154
static void
155
decode_extra_attrib(Buffer *b, Attrib *a)
156
{
157
	a->ext_flags = buffer_get_int(b);
158
	if (a->ext_flags & SSH2_FXE_EXTATTR_DEV)
159
		a->dev = buffer_get_int64(b);
160
	if (a->ext_flags & SSH2_FXE_EXTATTR_INO)
161
		a->ino = buffer_get_int64(b);
162
	if (a->ext_flags & SSH2_FXE_EXTATTR_NLINK)
163
		a->nlink = buffer_get_int(b);
164
	if (a->ext_flags & SSH2_FXE_EXTATTR_RDEV)
165
		a->rdev = buffer_get_int64(b);
166
	if (a->ext_flags & SSH2_FXE_EXTATTR_BLKSIZE)
167
		a->blksize = buffer_get_int(b);
168
	if (a->ext_flags & SSH2_FXE_EXTATTR_BLOCKS)
169
		a->blocks = buffer_get_int64(b);
170
	if (a->ext_flags & SSH2_FXE_EXTATTR_ATIME)
171
		a->atime = buffer_get_int64(b);
172
	if (a->ext_flags & SSH2_FXE_EXTATTR_ATIMENSEC)
173
		a->atimensec = buffer_get_int(b);
174
	if (a->ext_flags & SSH2_FXE_EXTATTR_MTIME)
175
		a->mtime = buffer_get_int64(b);
176
	if (a->ext_flags & SSH2_FXE_EXTATTR_MTIMENSEC)
177
		a->mtimensec = buffer_get_int(b);
178
	if (a->ext_flags & SSH2_FXE_EXTATTR_CTIME)
179
		a->ctime = buffer_get_int64(b);
180
	if (a->ext_flags & SSH2_FXE_EXTATTR_CTIMENSEC)
181
		a->ctimensec = buffer_get_int(b);
94
}
182
}
95
183
96
/* Decode attributes in buffer */
184
/* Decode attributes in buffer */
Lines 115-140 decode_attrib(Buffer *b) Link Here
115
	}
203
	}
116
	/* vendor-specific extensions */
204
	/* vendor-specific extensions */
117
	if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
205
	if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
118
		char *type, *data;
206
		char *type;
207
		void *data;
119
		int i, count;
208
		int i, count;
209
		u_int datalen;
120
210
121
		count = buffer_get_int(b);
211
		count = buffer_get_int(b);
122
		for (i = 0; i < count; i++) {
212
		for (i = 0; i < count; i++) {
123
			type = buffer_get_string(b, NULL);
213
			type = buffer_get_string(b, NULL);
124
			data = buffer_get_string(b, NULL);
214
			data = buffer_get_string_ptr(b, &datalen);
125
			debug3("Got file attribute \"%s\"", type);
215
			debug3("Got file attribute \"%s\"", type);
216
			if (strcmp(type, "extattr@openssh.com") == 0) {
217
				Buffer ext;
218
219
				buffer_init(&ext);
220
				buffer_append(&ext, data, datalen);
221
				decode_extra_attrib(&ext, &a);
222
				buffer_free(&ext);
223
			}
126
			xfree(type);
224
			xfree(type);
127
			xfree(data);
128
		}
225
		}
129
	}
226
	}
130
	return &a;
227
	return &a;
131
}
228
}
132
229
230
static void
231
encode_extra_attrib(Buffer *b, const Attrib *a)
232
{
233
	buffer_put_int(b, a->ext_flags);
234
	if (a->ext_flags & SSH2_FXE_EXTATTR_DEV)
235
		buffer_put_int64(b, a->dev);
236
	if (a->ext_flags & SSH2_FXE_EXTATTR_INO)
237
		buffer_put_int64(b, a->ino);
238
	if (a->ext_flags & SSH2_FXE_EXTATTR_NLINK)
239
		buffer_put_int(b, a->nlink);
240
	if (a->ext_flags & SSH2_FXE_EXTATTR_RDEV)
241
		buffer_put_int64(b, a->rdev);
242
	if (a->ext_flags & SSH2_FXE_EXTATTR_BLKSIZE)
243
		buffer_put_int(b, a->blksize);
244
	if (a->ext_flags & SSH2_FXE_EXTATTR_BLOCKS)
245
		buffer_put_int64(b, a->blocks);
246
	if (a->ext_flags & SSH2_FXE_EXTATTR_ATIME)
247
		buffer_put_int64(b, a->atime);
248
	if (a->ext_flags & SSH2_FXE_EXTATTR_ATIMENSEC)
249
		buffer_put_int(b, a->atimensec);
250
	if (a->ext_flags & SSH2_FXE_EXTATTR_MTIME)
251
		buffer_put_int64(b, a->mtime);
252
	if (a->ext_flags & SSH2_FXE_EXTATTR_MTIMENSEC)
253
		buffer_put_int(b, a->mtimensec);
254
	if (a->ext_flags & SSH2_FXE_EXTATTR_CTIME)
255
		buffer_put_int64(b, a->ctime);
256
	if (a->ext_flags & SSH2_FXE_EXTATTR_CTIMENSEC)
257
		buffer_put_int(b, a->ctimensec);
258
}
259
133
/* Encode attributes to buffer */
260
/* Encode attributes to buffer */
134
void
261
void
135
encode_attrib(Buffer *b, const Attrib *a)
262
encode_attrib(Buffer *b, const Attrib *a)
136
{
263
{
137
	buffer_put_int(b, a->flags);
264
	int flags = a->flags;
265
266
	if (a->ext_flags != 0)
267
		flags |= SSH2_FILEXFER_ATTR_EXTENDED;
268
269
	buffer_put_int(b, flags);
138
	if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
270
	if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
139
		buffer_put_int64(b, a->size);
271
		buffer_put_int64(b, a->size);
140
	if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
272
	if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
Lines 147-152 encode_attrib(Buffer *b, const Attrib *a Link Here
147
		buffer_put_int(b, a->atime);
279
		buffer_put_int(b, a->atime);
148
		buffer_put_int(b, a->mtime);
280
		buffer_put_int(b, a->mtime);
149
	}
281
	}
282
283
	if (flags & SSH2_FILEXFER_ATTR_EXTENDED) {
284
		u_int ext_count = 1;
285
		Buffer ext;
286
287
		buffer_put_int(b, ext_count);
288
		buffer_put_cstring(b, "extattr@openssh.com");
289
290
		buffer_init(&ext);
291
		encode_extra_attrib(&ext, a);
292
		buffer_put_string(b, buffer_ptr(&ext), buffer_len(&ext));
293
		buffer_free(&ext);
294
	}
150
}
295
}
151
296
152
/* Convert from SSH2_FX_ status to text error message */
297
/* Convert from SSH2_FX_ status to text error message */
(-)ssh.orig/sftp-common.h (-2 / +13 lines)
Lines 33-44 typedef struct Attrib Attrib; Link Here
33
/* File attributes */
33
/* File attributes */
34
struct Attrib {
34
struct Attrib {
35
	u_int32_t	flags;
35
	u_int32_t	flags;
36
	u_int32_t	ext_flags;
37
	u_int64_t	dev;
38
	u_int64_t	ino;
39
	u_int64_t	rdev;
36
	u_int64_t	size;
40
	u_int64_t	size;
41
	u_int64_t	blocks;
42
	u_int32_t	blksize;
37
	u_int32_t	uid;
43
	u_int32_t	uid;
38
	u_int32_t	gid;
44
	u_int32_t	gid;
39
	u_int32_t	perm;
45
	u_int32_t	perm;
40
	u_int32_t	atime;
46
	u_int32_t	nlink;
41
	u_int32_t	mtime;
47
	u_int64_t	atime;
48
	u_int64_t	mtime;
49
	u_int64_t	ctime;
50
	u_int32_t	atimensec;
51
	u_int32_t	mtimensec;
52
	u_int32_t	ctimensec;
42
};
53
};
43
54
44
void	 attrib_clear(Attrib *);
55
void	 attrib_clear(Attrib *);
(-)ssh.orig/sftp.h (+14 lines)
Lines 83-88 Link Here
83
#define SSH2_FXE_STATVFS_ST_RDONLY	0x00000001
83
#define SSH2_FXE_STATVFS_ST_RDONLY	0x00000001
84
#define SSH2_FXE_STATVFS_ST_NOSUID	0x00000002
84
#define SSH2_FXE_STATVFS_ST_NOSUID	0x00000002
85
85
86
/* extattr@openssh.com extra attribute flags */
87
#define SSH2_FXE_EXTATTR_DEV		0x00000001
88
#define SSH2_FXE_EXTATTR_INO		0x00000002
89
#define SSH2_FXE_EXTATTR_NLINK		0x00000004
90
#define SSH2_FXE_EXTATTR_RDEV		0x00000008
91
#define SSH2_FXE_EXTATTR_BLKSIZE	0x00000010
92
#define SSH2_FXE_EXTATTR_BLOCKS		0x00000020
93
#define SSH2_FXE_EXTATTR_ATIME		0x00000040
94
#define SSH2_FXE_EXTATTR_ATIMENSEC	0x00000080
95
#define SSH2_FXE_EXTATTR_MTIME		0x00000100
96
#define SSH2_FXE_EXTATTR_MTIMENSEC	0x00000200
97
#define SSH2_FXE_EXTATTR_CTIME		0x00000400
98
#define SSH2_FXE_EXTATTR_CTIMENSEC	0x00000800
99
86
/* status messages */
100
/* status messages */
87
#define SSH2_FX_OK			0
101
#define SSH2_FX_OK			0
88
#define SSH2_FX_EOF			1
102
#define SSH2_FX_EOF			1
(-)ssh.orig/sftp-client.c (+1 lines)
Lines 1201-1206 do_upload(struct sftp_conn *conn, char * Link Here
1201
	}
1201
	}
1202
	stat_to_attrib(&sb, &a);
1202
	stat_to_attrib(&sb, &a);
1203
1203
1204
	a.ext_flags = 0;
1204
	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
1205
	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
1205
	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
1206
	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
1206
	a.perm &= 0777;
1207
	a.perm &= 0777;

Return to bug 1555