4 * This module implements a simple remote control protocol
6 * $DragonFly: src/bin/cpdup/hcproto.c,v 1.1 2006/08/13 20:51:40 dillon Exp $
22 static int hc_decode_stat(struct stat
*, struct HCHead
*);
23 static int rc_encode_stat(struct HostConf
*, struct stat
*);
25 static int rc_hello(struct HostConf
*, struct HCHead
*);
26 static int rc_stat(struct HostConf
*, struct HCHead
*);
27 static int rc_lstat(struct HostConf
*, struct HCHead
*);
28 static int rc_opendir(struct HostConf
*, struct HCHead
*);
29 static int rc_readdir(struct HostConf
*, struct HCHead
*);
30 static int rc_closedir(struct HostConf
*, struct HCHead
*);
31 static int rc_open(struct HostConf
*, struct HCHead
*);
32 static int rc_close(struct HostConf
*, struct HCHead
*);
33 static int rc_read(struct HostConf
*, struct HCHead
*);
34 static int rc_write(struct HostConf
*, struct HCHead
*);
35 static int rc_remove(struct HostConf
*, struct HCHead
*);
36 static int rc_mkdir(struct HostConf
*, struct HCHead
*);
37 static int rc_rmdir(struct HostConf
*, struct HCHead
*);
38 static int rc_chown(struct HostConf
*, struct HCHead
*);
39 static int rc_lchown(struct HostConf
*, struct HCHead
*);
40 static int rc_chmod(struct HostConf
*, struct HCHead
*);
41 static int rc_link(struct HostConf
*, struct HCHead
*);
42 #ifdef _ST_FLAGS_PRESENT_
43 static int rc_chflags(struct HostConf
*, struct HCHead
*);
45 static int rc_readlink(struct HostConf
*, struct HCHead
*);
46 static int rc_umask(struct HostConf
*, struct HCHead
*);
47 static int rc_symlink(struct HostConf
*, struct HCHead
*);
48 static int rc_rename(struct HostConf
*, struct HCHead
*);
49 static int rc_utimes(struct HostConf
*, struct HCHead
*);
51 struct HCDesc HCDispatchTable
[] = {
52 { HC_HELLO
, rc_hello
},
54 { HC_LSTAT
, rc_lstat
},
55 { HC_OPENDIR
, rc_opendir
},
56 { HC_READDIR
, rc_readdir
},
57 { HC_CLOSEDIR
, rc_closedir
},
59 { HC_CLOSE
, rc_close
},
61 { HC_WRITE
, rc_write
},
62 { HC_REMOVE
, rc_remove
},
63 { HC_MKDIR
, rc_mkdir
},
64 { HC_RMDIR
, rc_rmdir
},
65 { HC_CHOWN
, rc_chown
},
66 { HC_LCHOWN
, rc_lchown
},
67 { HC_CHMOD
, rc_chmod
},
69 #ifdef _ST_FLAGS_PRESENT_
70 { HC_CHFLAGS
, rc_chflags
},
72 { HC_READLINK
, rc_readlink
},
73 { HC_UMASK
, rc_umask
},
74 { HC_SYMLINK
, rc_symlink
},
75 { HC_RENAME
, rc_rename
},
76 { HC_UTIMES
, rc_utimes
},
80 hc_connect(struct HostConf
*hc
)
82 if (hcc_connect(hc
) < 0)
88 hc_slave(int fdin
, int fdout
)
90 hcc_slave(fdin
, fdout
, HCDispatchTable
,
91 sizeof(HCDispatchTable
) / sizeof(HCDispatchTable
[0]));
96 * A HELLO RPC is sent on the initial connect.
99 hc_hello(struct HostConf
*hc
)
106 bzero(hostbuf
, sizeof(hostbuf
));
107 if (gethostname(hostbuf
, sizeof(hostbuf
) - 1) < 0)
112 hcc_start_command(hc
, HC_HELLO
);
113 hcc_leaf_string(hc
, LC_HELLOSTR
, hostbuf
);
114 if ((head
= hcc_finish_command(hc
)) == NULL
)
118 fprintf(stderr
, "Connected to %s but remote returned error %d\n",
119 hc
->host
, head
->error
);
124 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
125 switch(item
->leafid
) {
127 fprintf(stderr
, "Handshaked with %s\n", HCC_STRING(item
));
132 fprintf(stderr
, "Handshake failed with %s\n", hc
->host
);
137 rc_hello(struct HostConf
*hc
, struct HCHead
*head __unused
)
141 bzero(hostbuf
, sizeof(hostbuf
));
142 if (gethostname(hostbuf
, sizeof(hostbuf
) - 1) < 0)
147 hcc_leaf_string(hc
, LC_HELLOSTR
, hostbuf
);
155 hc_stat(struct HostConf
*hc
, const char *path
, struct stat
*st
)
159 if (hc
== NULL
|| hc
->host
== NULL
)
160 return(stat(path
, st
));
162 hcc_start_command(hc
, HC_STAT
);
163 hcc_leaf_string(hc
, LC_PATH1
, path
);
164 if ((head
= hcc_finish_command(hc
)) == NULL
)
168 return(hc_decode_stat(st
, head
));
172 hc_lstat(struct HostConf
*hc
, const char *path
, struct stat
*st
)
176 if (hc
== NULL
|| hc
->host
== NULL
)
177 return(lstat(path
, st
));
179 hcc_start_command(hc
, HC_LSTAT
);
180 hcc_leaf_string(hc
, LC_PATH1
, path
);
181 if ((head
= hcc_finish_command(hc
)) == NULL
)
185 return(hc_decode_stat(st
, head
));
189 hc_decode_stat(struct stat
*st
, struct HCHead
*head
)
193 bzero(st
, sizeof(*st
));
194 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
195 switch(item
->leafid
) {
197 st
->st_dev
= HCC_INT32(item
);
200 st
->st_ino
= HCC_INT64(item
);
203 st
->st_mode
= HCC_INT32(item
);
206 st
->st_nlink
= HCC_INT32(item
);
209 st
->st_uid
= HCC_INT32(item
);
212 st
->st_gid
= HCC_INT32(item
);
215 st
->st_rdev
= HCC_INT32(item
);
218 st
->st_atime
= (time_t)HCC_INT64(item
);
221 st
->st_mtime
= (time_t)HCC_INT64(item
);
224 st
->st_ctime
= (time_t)HCC_INT64(item
);
227 st
->st_size
= HCC_INT64(item
);
230 st
->st_blocks
= HCC_INT64(item
);
233 st
->st_blksize
= HCC_INT32(item
);
235 #ifdef _ST_FSMID_PRESENT_
237 st
->st_fsmid
= HCC_INT64(item
);
240 #ifdef _ST_FLAGS_PRESENT_
242 st
->st_flags
= (u_int32_t
)HCC_INT64(item
);
251 rc_stat(struct HostConf
*hc
, struct HCHead
*head
)
255 const char *path
= NULL
;
257 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
258 switch(item
->leafid
) {
260 path
= HCC_STRING(item
);
266 if (stat(path
, &st
) < 0)
268 return (rc_encode_stat(hc
, &st
));
272 rc_lstat(struct HostConf
*hc
, struct HCHead
*head
)
276 const char *path
= NULL
;
278 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
279 switch(item
->leafid
) {
281 path
= HCC_STRING(item
);
287 if (lstat(path
, &st
) < 0)
289 return (rc_encode_stat(hc
, &st
));
293 rc_encode_stat(struct HostConf
*hc
, struct stat
*st
)
295 hcc_leaf_int32(hc
, LC_DEV
, st
->st_dev
);
296 hcc_leaf_int64(hc
, LC_INO
, st
->st_ino
);
297 hcc_leaf_int32(hc
, LC_MODE
, st
->st_mode
);
298 hcc_leaf_int32(hc
, LC_NLINK
, st
->st_nlink
);
299 hcc_leaf_int32(hc
, LC_UID
, st
->st_uid
);
300 hcc_leaf_int32(hc
, LC_GID
, st
->st_gid
);
301 hcc_leaf_int32(hc
, LC_RDEV
, st
->st_rdev
);
302 hcc_leaf_int64(hc
, LC_ATIME
, st
->st_atime
);
303 hcc_leaf_int64(hc
, LC_MTIME
, st
->st_mtime
);
304 hcc_leaf_int64(hc
, LC_CTIME
, st
->st_ctime
);
305 hcc_leaf_int64(hc
, LC_FILESIZE
, st
->st_size
);
306 hcc_leaf_int64(hc
, LC_FILEBLKS
, st
->st_blocks
);
307 hcc_leaf_int32(hc
, LC_BLKSIZE
, st
->st_blksize
);
308 #ifdef _ST_FSMID_PRESENT_
309 hcc_leaf_int64(hc
, LC_FSMID
, st
->st_fsmid
);
311 #ifdef _ST_FLAGS_PRESENT_
312 hcc_leaf_int64(hc
, LC_FILEFLAGS
, st
->st_flags
);
321 hc_opendir(struct HostConf
*hc
, const char *path
)
328 if (hc
== NULL
|| hc
->host
== NULL
)
329 return(opendir(path
));
331 hcc_start_command(hc
, HC_OPENDIR
);
332 hcc_leaf_string(hc
, LC_PATH1
, path
);
333 if ((head
= hcc_finish_command(hc
)) == NULL
)
337 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
338 switch(item
->leafid
) {
340 desc
= HCC_INT32(item
);
344 if (hcc_get_descriptor(hc
, desc
, HC_DESC_DIR
)) {
345 fprintf(stderr
, "hc_opendir: remote reused active descriptor %d\n",
349 den
= malloc(sizeof(*den
));
350 bzero(den
, sizeof(*den
));
351 hcc_set_descriptor(hc
, desc
, den
, HC_DESC_DIR
);
352 return((void *)desc
);
356 rc_opendir(struct HostConf
*hc
, struct HCHead
*head
)
359 const char *path
= NULL
;
363 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
364 switch(item
->leafid
) {
366 path
= HCC_STRING(item
);
372 if ((dir
= opendir(path
)) == NULL
) {
375 desc
= hcc_alloc_descriptor(hc
, dir
, HC_DESC_DIR
);
376 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, desc
);
385 hc_readdir(struct HostConf
*hc
, DIR *dir
)
391 if (hc
== NULL
|| hc
->host
== NULL
)
392 return(readdir(dir
));
394 hcc_start_command(hc
, HC_READDIR
);
395 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, (int)dir
);
396 if ((head
= hcc_finish_command(hc
)) == NULL
)
399 return(NULL
); /* XXX errno */
400 den
= hcc_get_descriptor(hc
, (int)dir
, HC_DESC_DIR
);
402 return(NULL
); /* XXX errno */
405 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
406 switch(item
->leafid
) {
408 snprintf(den
->d_name
, sizeof(den
->d_name
), "%s", HCC_STRING(item
));
411 den
->d_fileno
= HCC_INT64(item
);
414 den
->d_type
= HCC_INT32(item
);
418 if (den
->d_name
[0]) {
419 #ifdef _DIRENT_HAVE_D_NAMLEN
420 den
->d_namlen
= strlen(den
->d_name
);
424 return(NULL
); /* XXX errno */
428 rc_readdir(struct HostConf
*hc
, struct HCHead
*head
)
434 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
435 switch(item
->leafid
) {
437 dir
= hcc_get_descriptor(hc
, HCC_INT32(item
), HC_DESC_DIR
);
443 if ((den
= readdir(dir
)) != NULL
) {
444 hcc_leaf_string(hc
, LC_PATH1
, den
->d_name
);
445 hcc_leaf_int64(hc
, LC_INO
, den
->d_fileno
);
446 hcc_leaf_int32(hc
, LC_TYPE
, den
->d_type
);
454 * XXX cpdup needs to check error code to avoid truncated dirs?
457 hc_closedir(struct HostConf
*hc
, DIR *dir
)
462 if (hc
== NULL
|| hc
->host
== NULL
)
463 return(closedir(dir
));
464 den
= hcc_get_descriptor(hc
, (int)dir
, HC_DESC_DIR
);
467 hcc_set_descriptor(hc
, (int)dir
, NULL
, HC_DESC_DIR
);
469 hcc_start_command(hc
, HC_CLOSEDIR
);
470 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, (int)dir
);
471 if ((head
= hcc_finish_command(hc
)) == NULL
)
474 return(-1); /* XXX errno */
483 rc_closedir(struct HostConf
*hc
, struct HCHead
*head
)
488 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
489 switch(item
->leafid
) {
491 dir
= hcc_get_descriptor(hc
, HCC_INT32(item
), HC_DESC_DIR
);
497 return(closedir(dir
));
504 hc_open(struct HostConf
*hc
, const char *path
, int flags
, mode_t mode
)
512 if (hc
== NULL
|| hc
->host
== NULL
) {
514 flags
|= O_LARGEFILE
;
516 return(open(path
, flags
, mode
));
519 nflags
= flags
& XO_NATIVEMASK
;
527 hcc_start_command(hc
, HC_OPEN
);
528 hcc_leaf_string(hc
, LC_PATH1
, path
);
529 hcc_leaf_int32(hc
, LC_OFLAGS
, nflags
);
530 hcc_leaf_int32(hc
, LC_MODE
, mode
);
532 if ((head
= hcc_finish_command(hc
)) == NULL
)
536 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
537 switch(item
->leafid
) {
539 desc
= HCC_INT32(item
);
543 if (hcc_get_descriptor(hc
, desc
, HC_DESC_FD
)) {
544 fprintf(stderr
, "hc_opendir: remote reused active descriptor %d\n",
548 fdp
= malloc(sizeof(int));
549 *fdp
= desc
; /* really just a dummy */
550 hcc_set_descriptor(hc
, desc
, fdp
, HC_DESC_FD
);
555 rc_open(struct HostConf
*hc
, struct HCHead
*head
)
558 const char *path
= NULL
;
566 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
567 switch(item
->leafid
) {
569 path
= HCC_STRING(item
);
572 nflags
= HCC_INT32(item
);
575 mode
= HCC_INT32(item
);
582 flags
= nflags
& XO_NATIVEMASK
;
583 if (nflags
& XO_CREAT
)
585 if (nflags
& XO_EXCL
)
587 if (nflags
& XO_TRUNC
)
591 flags
|= O_LARGEFILE
;
593 if ((fd
= open(path
, flags
, mode
)) < 0) {
597 fdp
= malloc(sizeof(int));
599 desc
= hcc_alloc_descriptor(hc
, fdp
, HC_DESC_FD
);
600 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, desc
);
608 hc_close(struct HostConf
*hc
, int fd
)
613 if (hc
== NULL
|| hc
->host
== NULL
)
616 fdp
= hcc_get_descriptor(hc
, fd
, HC_DESC_FD
);
619 hcc_set_descriptor(hc
, fd
, NULL
, HC_DESC_FD
);
621 hcc_start_command(hc
, HC_CLOSE
);
622 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, fd
);
623 if ((head
= hcc_finish_command(hc
)) == NULL
)
634 rc_close(struct HostConf
*hc
, struct HCHead
*head
)
641 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
642 switch(item
->leafid
) {
644 desc
= HCC_INT32(item
);
650 if ((fdp
= hcc_get_descriptor(hc
, desc
, HC_DESC_FD
)) == NULL
)
654 hcc_set_descriptor(hc
, desc
, NULL
, HC_DESC_FD
);
662 hc_read(struct HostConf
*hc
, int fd
, void *buf
, size_t bytes
)
669 if (hc
== NULL
|| hc
->host
== NULL
)
670 return(read(fd
, buf
, bytes
));
672 fdp
= hcc_get_descriptor(hc
, fd
, HC_DESC_FD
);
676 int n
= (bytes
> 32768) ? 32768 : bytes
;
679 hcc_start_command(hc
, HC_READ
);
680 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, fd
);
681 hcc_leaf_int32(hc
, LC_BYTES
, n
);
682 if ((head
= hcc_finish_command(hc
)) == NULL
)
686 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
687 switch(item
->leafid
) {
689 x
= item
->bytes
- sizeof(*item
);
692 bcopy(HCC_BINARYDATA(item
), buf
, x
);
693 buf
= (char *)buf
+ x
;
709 rc_read(struct HostConf
*hc
, struct HCHead
*head
)
717 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
718 switch(item
->leafid
) {
720 fdp
= hcc_get_descriptor(hc
, HCC_INT32(item
), HC_DESC_FD
);
723 bytes
= HCC_INT32(item
);
729 if (bytes
< 0 || bytes
> 32768)
731 n
= read(*fdp
, buf
, bytes
);
736 hcc_leaf_data(hc
, LC_DATA
, buf
, n
);
744 hc_write(struct HostConf
*hc
, int fd
, const void *buf
, size_t bytes
)
751 if (hc
== NULL
|| hc
->host
== NULL
)
752 return(write(fd
, buf
, bytes
));
754 fdp
= hcc_get_descriptor(hc
, fd
, HC_DESC_FD
);
758 int n
= (bytes
> 32768) ? 32768 : bytes
;
761 hcc_start_command(hc
, HC_WRITE
);
762 hcc_leaf_int32(hc
, LC_DESCRIPTOR
, fd
);
763 hcc_leaf_data(hc
, LC_DATA
, buf
, n
);
764 if ((head
= hcc_finish_command(hc
)) == NULL
)
768 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
769 switch(item
->leafid
) {
778 buf
= (const char *)buf
+ x
;
790 rc_write(struct HostConf
*hc
, struct HCHead
*head
)
797 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
798 switch(item
->leafid
) {
800 fdp
= hcc_get_descriptor(hc
, HCC_INT32(item
), HC_DESC_FD
);
803 buf
= HCC_BINARYDATA(item
);
804 n
= item
->bytes
- sizeof(*item
);
810 if (n
< 0 || n
> 32768)
812 n
= write(*fdp
, buf
, n
);
816 hcc_leaf_int32(hc
, LC_BYTES
, n
);
825 hc_remove(struct HostConf
*hc
, const char *path
)
829 if (hc
== NULL
|| hc
->host
== NULL
)
830 return(remove(path
));
832 hcc_start_command(hc
, HC_REMOVE
);
833 hcc_leaf_string(hc
, LC_PATH1
, path
);
834 if ((head
= hcc_finish_command(hc
)) == NULL
)
842 rc_remove(struct HostConf
*hc __unused
, struct HCHead
*head
)
845 const char *path
= NULL
;
847 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
848 switch(item
->leafid
) {
850 path
= HCC_STRING(item
);
856 return(remove(path
));
863 hc_mkdir(struct HostConf
*hc __unused
, const char *path
, mode_t mode
)
867 if (hc
== NULL
|| hc
->host
== NULL
)
868 return(mkdir(path
, mode
));
870 hcc_start_command(hc
, HC_MKDIR
);
871 hcc_leaf_string(hc
, LC_PATH1
, path
);
872 hcc_leaf_int32(hc
, LC_MODE
, mode
);
873 if ((head
= hcc_finish_command(hc
)) == NULL
)
881 rc_mkdir(struct HostConf
*hc __unused
, struct HCHead
*head
)
884 const char *path
= NULL
;
887 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
888 switch(item
->leafid
) {
890 path
= HCC_STRING(item
);
893 mode
= HCC_INT32(item
);
899 return(mkdir(path
, mode
));
906 hc_rmdir(struct HostConf
*hc
, const char *path
)
910 if (hc
== NULL
|| hc
->host
== NULL
)
913 hcc_start_command(hc
, HC_RMDIR
);
914 hcc_leaf_string(hc
, LC_PATH1
, path
);
915 if ((head
= hcc_finish_command(hc
)) == NULL
)
923 rc_rmdir(struct HostConf
*hc __unused
, struct HCHead
*head
)
926 const char *path
= NULL
;
928 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
929 switch(item
->leafid
) {
931 path
= HCC_STRING(item
);
944 hc_chown(struct HostConf
*hc
, const char *path
, uid_t owner
, gid_t group
)
948 if (hc
== NULL
|| hc
->host
== NULL
)
949 return(chown(path
, owner
, group
));
951 hcc_start_command(hc
, HC_CHOWN
);
952 hcc_leaf_string(hc
, LC_PATH1
, path
);
953 hcc_leaf_int32(hc
, LC_UID
, owner
);
954 hcc_leaf_int32(hc
, LC_GID
, group
);
955 if ((head
= hcc_finish_command(hc
)) == NULL
)
963 rc_chown(struct HostConf
*hc __unused
, struct HCHead
*head
)
966 const char *path
= NULL
;
967 uid_t uid
= (uid_t
)-1;
968 gid_t gid
= (gid_t
)-1;
970 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
971 switch(item
->leafid
) {
973 path
= HCC_STRING(item
);
976 uid
= HCC_INT32(item
);
979 gid
= HCC_INT32(item
);
985 return(chown(path
, uid
, gid
));
992 hc_lchown(struct HostConf
*hc
, const char *path
, uid_t owner
, gid_t group
)
996 if (hc
== NULL
|| hc
->host
== NULL
)
997 return(lchown(path
, owner
, group
));
999 hcc_start_command(hc
, HC_LCHOWN
);
1000 hcc_leaf_string(hc
, LC_PATH1
, path
);
1001 hcc_leaf_int32(hc
, LC_UID
, owner
);
1002 hcc_leaf_int32(hc
, LC_GID
, group
);
1003 if ((head
= hcc_finish_command(hc
)) == NULL
)
1011 rc_lchown(struct HostConf
*hc __unused
, struct HCHead
*head
)
1013 struct HCLeaf
*item
;
1014 const char *path
= NULL
;
1015 uid_t uid
= (uid_t
)-1;
1016 gid_t gid
= (gid_t
)-1;
1018 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1019 switch(item
->leafid
) {
1021 path
= HCC_STRING(item
);
1024 uid
= HCC_INT32(item
);
1027 gid
= HCC_INT32(item
);
1033 return(lchown(path
, uid
, gid
));
1040 hc_chmod(struct HostConf
*hc
, const char *path
, mode_t mode
)
1042 struct HCHead
*head
;
1044 if (hc
== NULL
|| hc
->host
== NULL
)
1045 return(chmod(path
, mode
));
1047 hcc_start_command(hc
, HC_CHMOD
);
1048 hcc_leaf_string(hc
, LC_PATH1
, path
);
1049 hcc_leaf_int32(hc
, LC_MODE
, mode
);
1050 if ((head
= hcc_finish_command(hc
)) == NULL
)
1058 rc_chmod(struct HostConf
*hc __unused
, struct HCHead
*head
)
1060 struct HCLeaf
*item
;
1061 const char *path
= NULL
;
1064 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1065 switch(item
->leafid
) {
1067 path
= HCC_STRING(item
);
1070 mode
= HCC_INT32(item
);
1076 return(chmod(path
, mode
));
1083 hc_link(struct HostConf
*hc
, const char *name1
, const char *name2
)
1085 struct HCHead
*head
;
1087 if (hc
== NULL
|| hc
->host
== NULL
)
1088 return(link(name1
, name2
));
1090 hcc_start_command(hc
, HC_LINK
);
1091 hcc_leaf_string(hc
, LC_PATH1
, name1
);
1092 hcc_leaf_string(hc
, LC_PATH2
, name2
);
1093 if ((head
= hcc_finish_command(hc
)) == NULL
)
1101 rc_link(struct HostConf
*hc __unused
, struct HCHead
*head
)
1103 struct HCLeaf
*item
;
1104 const char *name1
= NULL
;
1105 const char *name2
= NULL
;
1107 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1108 switch(item
->leafid
) {
1110 name1
= HCC_STRING(item
);
1113 name2
= HCC_STRING(item
);
1117 if (name1
== NULL
|| name2
== NULL
)
1119 return(link(name1
, name2
));
1122 #ifdef _ST_FLAGS_PRESENT_
1127 hc_chflags(struct HostConf
*hc
, const char *path
, u_long flags
)
1129 struct HCHead
*head
;
1131 if (hc
== NULL
|| hc
->host
== NULL
)
1132 return(chflags(path
, flags
));
1134 hcc_start_command(hc
, HC_CHFLAGS
);
1135 hcc_leaf_string(hc
, LC_PATH1
, path
);
1136 hcc_leaf_int64(hc
, LC_FILEFLAGS
, flags
);
1137 if ((head
= hcc_finish_command(hc
)) == NULL
)
1145 rc_chflags(struct HostConf
*hc __unused
, struct HCHead
*head
)
1147 struct HCLeaf
*item
;
1148 const char *path
= NULL
;
1151 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1152 switch(item
->leafid
) {
1154 path
= HCC_STRING(item
);
1157 flags
= (u_long
)HCC_INT64(item
);
1163 return(chflags(path
, flags
));
1172 hc_readlink(struct HostConf
*hc
, const char *path
, char *buf
, int bufsiz
)
1174 struct HCHead
*head
;
1175 struct HCLeaf
*item
;
1178 if (hc
== NULL
|| hc
->host
== NULL
)
1179 return(readlink(path
, buf
, bufsiz
));
1181 hcc_start_command(hc
, HC_READLINK
);
1182 hcc_leaf_string(hc
, LC_PATH1
, path
);
1183 if ((head
= hcc_finish_command(hc
)) == NULL
)
1189 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1190 switch(item
->leafid
) {
1192 r
= item
->bytes
- sizeof(*item
);
1197 bcopy(HCC_BINARYDATA(item
), buf
, r
);
1205 rc_readlink(struct HostConf
*hc
, struct HCHead
*head
)
1207 struct HCLeaf
*item
;
1208 const char *path
= NULL
;
1212 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1213 switch(item
->leafid
) {
1215 path
= HCC_STRING(item
);
1221 r
= readlink(path
, buf
, sizeof(buf
));
1224 hcc_leaf_data(hc
, LC_DATA
, buf
, r
);
1232 hc_umask(struct HostConf
*hc
, mode_t numask
)
1234 struct HCHead
*head
;
1235 struct HCLeaf
*item
;
1237 if (hc
== NULL
|| hc
->host
== NULL
)
1238 return(umask(numask
));
1240 hcc_start_command(hc
, HC_UMASK
);
1241 hcc_leaf_int32(hc
, LC_MODE
, numask
);
1242 if ((head
= hcc_finish_command(hc
)) == NULL
)
1248 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1249 switch(item
->leafid
) {
1251 numask
= HCC_INT32(item
);
1259 rc_umask(struct HostConf
*hc
, struct HCHead
*head
)
1261 struct HCLeaf
*item
;
1262 mode_t numask
= ~0666;
1264 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1265 switch(item
->leafid
) {
1267 numask
= HCC_INT32(item
);
1271 numask
= umask(numask
);
1272 hcc_leaf_int32(hc
, LC_MODE
, numask
);
1280 hc_symlink(struct HostConf
*hc
, const char *name1
, const char *name2
)
1282 struct HCHead
*head
;
1284 if (hc
== NULL
|| hc
->host
== NULL
)
1285 return(symlink(name1
, name2
));
1287 hcc_start_command(hc
, HC_SYMLINK
);
1288 hcc_leaf_string(hc
, LC_PATH1
, name1
);
1289 hcc_leaf_string(hc
, LC_PATH2
, name2
);
1290 if ((head
= hcc_finish_command(hc
)) == NULL
)
1298 rc_symlink(struct HostConf
*hc __unused
, struct HCHead
*head
)
1300 struct HCLeaf
*item
;
1301 const char *name1
= NULL
;
1302 const char *name2
= NULL
;
1304 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1305 switch(item
->leafid
) {
1307 name1
= HCC_STRING(item
);
1310 name2
= HCC_STRING(item
);
1314 if (name1
== NULL
|| name2
== NULL
)
1316 return(symlink(name1
, name2
));
1323 hc_rename(struct HostConf
*hc
, const char *name1
, const char *name2
)
1325 struct HCHead
*head
;
1327 if (hc
== NULL
|| hc
->host
== NULL
)
1328 return(rename(name1
, name2
));
1330 hcc_start_command(hc
, HC_RENAME
);
1331 hcc_leaf_string(hc
, LC_PATH1
, name1
);
1332 hcc_leaf_string(hc
, LC_PATH2
, name2
);
1333 if ((head
= hcc_finish_command(hc
)) == NULL
)
1341 rc_rename(struct HostConf
*hc __unused
, struct HCHead
*head
)
1343 struct HCLeaf
*item
;
1344 const char *name1
= NULL
;
1345 const char *name2
= NULL
;
1347 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1348 switch(item
->leafid
) {
1350 name1
= HCC_STRING(item
);
1353 name2
= HCC_STRING(item
);
1357 if (name1
== NULL
|| name2
== NULL
)
1359 return(rename(name1
, name2
));
1366 hc_utimes(struct HostConf
*hc
, const char *path
, const struct timeval
*times
)
1368 struct HCHead
*head
;
1370 if (hc
== NULL
|| hc
->host
== NULL
)
1371 return(utimes(path
, times
));
1373 hcc_start_command(hc
, HC_UTIMES
);
1374 hcc_leaf_string(hc
, LC_PATH1
, path
);
1375 hcc_leaf_int64(hc
, LC_ATIME
, times
[0].tv_sec
);
1376 hcc_leaf_int64(hc
, LC_MTIME
, times
[1].tv_sec
);
1377 if ((head
= hcc_finish_command(hc
)) == NULL
)
1385 rc_utimes(struct HostConf
*hc __unused
, struct HCHead
*head
)
1387 struct HCLeaf
*item
;
1388 struct timeval times
[2];
1391 bzero(times
, sizeof(times
));
1394 for (item
= hcc_firstitem(head
); item
; item
= hcc_nextitem(head
, item
)) {
1395 switch(item
->leafid
) {
1397 path
= HCC_STRING(item
);
1400 times
[0].tv_sec
= HCC_INT64(item
);
1403 times
[1].tv_sec
= HCC_INT64(item
);
1409 return(utimes(path
, times
));