mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-20 21:31:32 +03:00
Merge pull request #5575 from urbit/jo/unix-sane
vere/unix: sane(r) path handling
This commit is contained in:
commit
6ed6fdfc6e
@ -350,8 +350,9 @@ intmax_t mdb_get_filesize(HANDLE han_u)
|
||||
|
||||
char *realpath(const char *path, char *resolved_path)
|
||||
{
|
||||
// TODO
|
||||
return strdup(path);
|
||||
// XX MAX_PATH
|
||||
//
|
||||
return _fullpath(resolved_path, path, MAX_PATH);
|
||||
}
|
||||
|
||||
long sysconf(int name)
|
||||
|
@ -10,7 +10,7 @@ _dup_std_handle(HANDLE* new_u, DWORD typ_u)
|
||||
HANDLE han_u = GetStdHandle(typ_u);
|
||||
BOOL con_u = GetConsoleMode(han_u, &dum_u);
|
||||
if ( con_u ) {
|
||||
han_u = (HANDLE)_get_osfhandle(open(c3_dev_null, O_RDWR, 0));
|
||||
han_u = (HANDLE)_get_osfhandle(c3_open(c3_dev_null, O_RDWR, 0));
|
||||
}
|
||||
|
||||
if ( !DuplicateHandle(GetCurrentProcess(), han_u, GetCurrentProcess(), new_u, 0, TRUE, DUPLICATE_SAME_ACCESS) ) {
|
||||
|
@ -55,6 +55,44 @@ _main_presig(c3_c* txt_c)
|
||||
return new_c;
|
||||
}
|
||||
|
||||
/* _main_repath(): canonicalize path, using dirname if needed.
|
||||
*/
|
||||
c3_c*
|
||||
_main_repath(c3_c* pax_c)
|
||||
{
|
||||
c3_c* rel_c;
|
||||
c3_c* fas_c;
|
||||
c3_c* dir_c;
|
||||
c3_w len_w;
|
||||
c3_i wit_i;
|
||||
|
||||
c3_assert(pax_c);
|
||||
if ( 0 != (rel_c = realpath(pax_c, 0)) ) {
|
||||
return rel_c;
|
||||
}
|
||||
fas_c = strrchr(pax_c, '/');
|
||||
if ( !fas_c ) {
|
||||
c3_c rec_c[2048];
|
||||
|
||||
wit_i = snprintf(rec_c, sizeof(rec_c), "./%s", pax_c);
|
||||
c3_assert(sizeof(rec_c) > wit_i);
|
||||
return _main_repath(rec_c);
|
||||
}
|
||||
c3_assert(u3_unix_cane(fas_c + 1));
|
||||
*fas_c = 0;
|
||||
dir_c = realpath(pax_c, 0);
|
||||
*fas_c = '/';
|
||||
if ( 0 == dir_c ) {
|
||||
return 0;
|
||||
}
|
||||
len_w = strlen(dir_c) + strlen(fas_c) + 1;
|
||||
rel_c = c3_malloc(len_w);
|
||||
wit_i = snprintf(rel_c, len_w, "%s%s", dir_c, fas_c);
|
||||
c3_assert(len_w == wit_i + 1);
|
||||
c3_free(dir_c);
|
||||
return rel_c;
|
||||
}
|
||||
|
||||
/* _main_getopt(): extract option map from command line.
|
||||
*/
|
||||
static u3_noun
|
||||
@ -139,7 +177,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'Y': {
|
||||
u3_Host.ops_u.puk_c = strdup(optarg);
|
||||
u3_Host.ops_u.puk_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'Z': {
|
||||
@ -147,11 +185,11 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'J': {
|
||||
u3_Host.ops_u.lit_c = strdup(optarg);
|
||||
u3_Host.ops_u.lit_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'B': {
|
||||
u3_Host.ops_u.pil_c = strdup(optarg);
|
||||
u3_Host.ops_u.pil_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
@ -163,7 +201,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'A': {
|
||||
u3_Host.ops_u.arv_c = strdup(optarg);
|
||||
u3_Host.ops_u.arv_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
@ -171,7 +209,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'I': {
|
||||
u3_Host.ops_u.jin_c = strdup(optarg);
|
||||
u3_Host.ops_u.jin_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'C': {
|
||||
@ -209,7 +247,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'k': {
|
||||
u3_Host.ops_u.key_c = strdup(optarg);
|
||||
u3_Host.ops_u.key_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
@ -231,7 +269,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
u3_Host.ops_u.imp_c = strdup(optarg);
|
||||
u3_Host.ops_u.imp_c = _main_repath(optarg);
|
||||
break;
|
||||
}
|
||||
case 'L': { u3_Host.ops_u.net = c3n; break; }
|
||||
@ -291,7 +329,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
}
|
||||
}
|
||||
|
||||
u3_Host.dir_c = strdup(argv[optind]);
|
||||
u3_Host.dir_c = _main_repath(argv[optind]);
|
||||
}
|
||||
|
||||
// daemon mode (-d) implies disabling terminal assumptions (-t)
|
||||
@ -705,31 +743,7 @@ main(c3_i argc,
|
||||
printf("~\n");
|
||||
// printf("welcome.\n");
|
||||
printf("urbit %s\n", URBIT_VERSION);
|
||||
|
||||
// prints the absolute path of the pier
|
||||
//
|
||||
c3_c* abs_c = realpath(u3_Host.dir_c, 0);
|
||||
|
||||
// if the ship is being booted, we use realpath(). Otherwise, we use getcwd()
|
||||
// with a memory-allocation loop
|
||||
//
|
||||
if (abs_c == NULL) {
|
||||
c3_i mprint_i = 1000;
|
||||
abs_c = c3_malloc(mprint_i);
|
||||
|
||||
// allocates more memory as needed if the path is too large
|
||||
//
|
||||
while ( abs_c != getcwd(abs_c, mprint_i) ) {
|
||||
c3_free(abs_c);
|
||||
mprint_i *= 2;
|
||||
abs_c = c3_malloc(mprint_i);
|
||||
}
|
||||
printf("boot: home is %s/%s\n", abs_c, u3_Host.dir_c);
|
||||
c3_free(abs_c);
|
||||
} else {
|
||||
printf("boot: home is %s\n", abs_c);
|
||||
c3_free(abs_c);
|
||||
}
|
||||
printf("boot: home is %s\n", u3_Host.dir_c);
|
||||
// printf("vere: hostname is %s\n", u3_Host.ops_u.nam_c);
|
||||
|
||||
if ( c3y == u3_Host.ops_u.dem ) {
|
||||
|
@ -122,4 +122,35 @@
|
||||
} \
|
||||
rut;})
|
||||
|
||||
/* Asserting unix fs wrappers.
|
||||
**
|
||||
** these all crash the process if passed a non-canonical
|
||||
** path (i.e., one containing '.', '..', or the empty path
|
||||
** component), so make sure you don't pass them one. if you
|
||||
** find yourself fighting with them, then please delete them
|
||||
** and do a sed search-and-replace to remove the `c3_` from
|
||||
** their call sites; their goal is to decrease maintenance
|
||||
** burden, not increase it.
|
||||
*/
|
||||
// defined in vere/io/unix.c.
|
||||
c3_t u3_unix_cane(const c3_c* pax_c);
|
||||
# define c3_open(a, ...) ({ \
|
||||
c3_assert(u3_unix_cane(a)); \
|
||||
open(a, __VA_ARGS__);})
|
||||
# define c3_opendir(a) ({ \
|
||||
c3_assert(u3_unix_cane(a)); \
|
||||
opendir(a);})
|
||||
# define c3_mkdir(a, b) ({ \
|
||||
c3_assert(u3_unix_cane(a)); \
|
||||
mkdir(a, b);})
|
||||
# define c3_rmdir(a) ({ \
|
||||
c3_assert(u3_unix_cane(a)); \
|
||||
rmdir(a);})
|
||||
# define c3_unlink(a) ({ \
|
||||
c3_assert(u3_unix_cane(a)); \
|
||||
unlink(a);})
|
||||
# define c3_fopen(a, b) ({ \
|
||||
c3_assert(u3_unix_cane(a)); \
|
||||
fopen(a, b);})
|
||||
|
||||
#endif /* ifndef C3_DEFS_H */
|
||||
|
@ -127,12 +127,12 @@
|
||||
|
||||
/* u3i_string(): Produce an LSB-first atom from the C string [a].
|
||||
*/
|
||||
u3_noun
|
||||
u3_atom
|
||||
u3i_string(const c3_c* a_c);
|
||||
|
||||
/* u3i_tape(): from a C string, to a list of bytes.
|
||||
*/
|
||||
u3_atom
|
||||
u3_noun
|
||||
u3i_tape(const c3_c* txt_c);
|
||||
|
||||
/* u3i_list(): list from `u3_none`-terminated varargs.
|
||||
|
@ -328,7 +328,7 @@
|
||||
void (*bot_f)(); // call when chis is up
|
||||
} u3_host; // host == computer == process
|
||||
|
||||
/** New pier system.
|
||||
/** Pier system.
|
||||
**/
|
||||
/* u3_ovum_news: u3_ovum lifecycle events
|
||||
*/
|
||||
@ -755,7 +755,7 @@
|
||||
c3_d
|
||||
u3_time_gap_ms(u3_noun now, u3_noun wen);
|
||||
|
||||
/** ward: common structure lifecycle
|
||||
/** Common structure lifecycle.
|
||||
**/
|
||||
/* u3_dent_init(): initialize file record.
|
||||
*/
|
||||
@ -840,7 +840,7 @@
|
||||
c3_w
|
||||
u3_mcut_host(c3_c* buf_c, c3_w len_w, u3_noun hot);
|
||||
|
||||
/** New vere
|
||||
/** IO drivers.
|
||||
**/
|
||||
/* u3_auto_init(): initialize all drivers.
|
||||
*/
|
||||
@ -1034,41 +1034,14 @@
|
||||
void
|
||||
u3_lord_peek(u3_lord* god_u, u3_pico* pic_u);
|
||||
|
||||
/** Filesystem (new api).
|
||||
**/
|
||||
/* u3_walk_load(): load file or bail.
|
||||
*/
|
||||
u3_noun
|
||||
u3_walk_load(c3_c* pas_c);
|
||||
|
||||
/* u3_walk_safe(): load file or 0.
|
||||
*/
|
||||
u3_noun
|
||||
u3_walk_safe(c3_c* pas_c);
|
||||
|
||||
/* u3_walk_save(): save file or bail.
|
||||
*/
|
||||
void
|
||||
u3_walk_save(c3_c* pas_c, u3_noun tim, u3_atom pad, c3_c* bas_c, u3_noun pax);
|
||||
|
||||
/* u3_walk(): traverse `dir_c` to produce an arch, updating `old`.
|
||||
*/
|
||||
u3_noun
|
||||
u3_walk(const c3_c* dir_c, u3_noun old);
|
||||
|
||||
/* u3_path(): C unix path in computer for file or directory.
|
||||
*/
|
||||
c3_c*
|
||||
u3_path(c3_o fyl, u3_noun pax);
|
||||
|
||||
/** Filesystem (async)
|
||||
/** Filesystem (async).
|
||||
**/
|
||||
/* u3_foil_folder(): load directory, blockingly. create if nonexistent.
|
||||
*/
|
||||
u3_dire*
|
||||
u3_foil_folder(const c3_c* pax_c); // directory object, or 0
|
||||
|
||||
/** Terminal, new style.
|
||||
/** Terminal.
|
||||
**/
|
||||
/* u3_term_start_spinner(): prepare spinner state. RETAIN.
|
||||
*/
|
||||
@ -1166,8 +1139,18 @@
|
||||
u3_save_io_exit(u3_pier *pir_u);
|
||||
|
||||
|
||||
/** Storage, new school.
|
||||
/** Storage.
|
||||
**/
|
||||
/* u3_unix_save(): save file undir .../.urb/put or bail.
|
||||
*/
|
||||
void
|
||||
u3_unix_save(c3_c* pax_c, u3_atom pad);
|
||||
|
||||
/* u3_unix_cane(): true iff (unix) path is canonical.
|
||||
*/
|
||||
c3_t
|
||||
u3_unix_cane(const c3_c* pax_c);
|
||||
|
||||
/* u3_unix_initial_into_card(): create initial filesystem sync card.
|
||||
*/
|
||||
u3_noun
|
||||
@ -1199,14 +1182,14 @@
|
||||
u3_auto*
|
||||
u3_cttp_io_init(u3_pier* pir_u);
|
||||
|
||||
/** fore, first events
|
||||
/** fore, first events.
|
||||
**/
|
||||
/* u3_hind_io_init(): initialize fore
|
||||
*/
|
||||
u3_auto*
|
||||
u3_fore_io_init(u3_pier* pir_u);
|
||||
|
||||
/** hind, defaults
|
||||
/** hind, defaults.
|
||||
**/
|
||||
/* u3_hind_io_init(): initialize hint
|
||||
*/
|
||||
@ -1309,7 +1292,7 @@
|
||||
void
|
||||
u3_pier_info(u3_pier* pir_u);
|
||||
|
||||
/* u3_pier_boot(): start the new pier system.
|
||||
/* u3_pier_boot(): start the pier.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_boot(c3_w wag_w, // config flags
|
||||
@ -1319,7 +1302,7 @@
|
||||
u3_noun pax, // path to pier
|
||||
u3_weak fed); // extra private keys
|
||||
|
||||
/* u3_pier_stay(): restart the new pier system.
|
||||
/* u3_pier_stay(): restart the pier.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_stay(c3_w wag_w, u3_noun pax);
|
||||
|
@ -239,17 +239,17 @@ _ce_image_open(u3e_image* img_u)
|
||||
c3_c ful_c[8193];
|
||||
|
||||
snprintf(ful_c, 8192, "%s", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/%s.bin", u3P.dir_c, img_u->nam_c);
|
||||
if ( -1 == (img_u->fid_i = open(ful_c, mod_i, 0666)) ) {
|
||||
fprintf(stderr, "loom: open %s: %s\r\n", ful_c, strerror(errno));
|
||||
if ( -1 == (img_u->fid_i = c3_open(ful_c, mod_i, 0666)) ) {
|
||||
fprintf(stderr, "loom: c3_open %s: %s\r\n", ful_c, strerror(errno));
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
@ -333,20 +333,20 @@ _ce_patch_create(u3_ce_patch* pat_u)
|
||||
c3_c ful_c[8193];
|
||||
|
||||
snprintf(ful_c, 8192, "%s", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/control.bin", u3P.dir_c);
|
||||
if ( -1 == (pat_u->ctl_i = open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0600)) ) {
|
||||
fprintf(stderr, "loom: patch open control.bin: %s\r\n", strerror(errno));
|
||||
if ( -1 == (pat_u->ctl_i = c3_open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0600)) ) {
|
||||
fprintf(stderr, "loom: patch c3_open control.bin: %s\r\n", strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/memory.bin", u3P.dir_c);
|
||||
if ( -1 == (pat_u->mem_i = open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0600)) ) {
|
||||
fprintf(stderr, "loom: patch open memory.bin: %s\r\n", strerror(errno));
|
||||
if ( -1 == (pat_u->mem_i = c3_open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0600)) ) {
|
||||
fprintf(stderr, "loom: patch c3_open memory.bin: %s\r\n", strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
}
|
||||
@ -359,10 +359,10 @@ _ce_patch_delete(void)
|
||||
c3_c ful_c[8193];
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/control.bin", u3P.dir_c);
|
||||
unlink(ful_c);
|
||||
c3_unlink(ful_c);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/memory.bin", u3P.dir_c);
|
||||
unlink(ful_c);
|
||||
c3_unlink(ful_c);
|
||||
}
|
||||
|
||||
/* _ce_patch_verify(): check patch data mug.
|
||||
@ -431,18 +431,18 @@ _ce_patch_open(void)
|
||||
c3_i ctl_i, mem_i;
|
||||
|
||||
snprintf(ful_c, 8192, "%s", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb", u3P.dir_c);
|
||||
mkdir(ful_c, 0700);
|
||||
c3_mkdir(ful_c, 0700);
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/control.bin", u3P.dir_c);
|
||||
if ( -1 == (ctl_i = open(ful_c, O_RDWR)) ) {
|
||||
if ( -1 == (ctl_i = c3_open(ful_c, O_RDWR)) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/chk/memory.bin", u3P.dir_c);
|
||||
if ( -1 == (mem_i = open(ful_c, O_RDWR)) ) {
|
||||
if ( -1 == (mem_i = c3_open(ful_c, O_RDWR)) ) {
|
||||
close(ctl_i);
|
||||
|
||||
_ce_patch_delete();
|
||||
@ -838,7 +838,7 @@ _ce_backup(void)
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/bhk", u3P.dir_c);
|
||||
|
||||
if ( mkdir(ful_c, 0700) ) {
|
||||
if ( c3_mkdir(ful_c, 0700) ) {
|
||||
if ( EEXIST != errno ) {
|
||||
fprintf(stderr, "loom: image backup: %s\r\n", strerror(errno));
|
||||
}
|
||||
@ -847,15 +847,15 @@ _ce_backup(void)
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/bhk/%s.bin", u3P.dir_c, nop_u.nam_c);
|
||||
|
||||
if ( -1 == (nop_u.fid_i = open(ful_c, mod_i, 0666)) ) {
|
||||
fprintf(stderr, "loom: open %s: %s\r\n", ful_c, strerror(errno));
|
||||
if ( -1 == (nop_u.fid_i = c3_open(ful_c, mod_i, 0666)) ) {
|
||||
fprintf(stderr, "loom: c3_open %s: %s\r\n", ful_c, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(ful_c, 8192, "%s/.urb/bhk/%s.bin", u3P.dir_c, sop_u.nam_c);
|
||||
|
||||
if ( -1 == (sop_u.fid_i = open(ful_c, mod_i, 0666)) ) {
|
||||
fprintf(stderr, "loom: open %s: %s\r\n", ful_c, strerror(errno));
|
||||
if ( -1 == (sop_u.fid_i = c3_open(ful_c, mod_i, 0666)) ) {
|
||||
fprintf(stderr, "loom: c3_open %s: %s\r\n", ful_c, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -863,11 +863,11 @@ _ce_backup(void)
|
||||
|| (c3n == _ce_image_copy(&u3P.sou_u, &sop_u)) )
|
||||
{
|
||||
|
||||
unlink(ful_c);
|
||||
c3_unlink(ful_c);
|
||||
snprintf(ful_c, 8192, "%s/.urb/bhk/%s.bin", u3P.dir_c, nop_u.nam_c);
|
||||
unlink(ful_c);
|
||||
c3_unlink(ful_c);
|
||||
snprintf(ful_c, 8192, "%s/.urb/bhk", u3P.dir_c);
|
||||
rmdir(ful_c);
|
||||
c3_rmdir(ful_c);
|
||||
}
|
||||
|
||||
close(nop_u.fid_i);
|
||||
|
@ -541,7 +541,7 @@ u3i_qual(u3_noun a, u3_noun b, u3_noun c, u3_noun d)
|
||||
|
||||
/* u3i_string(): Produce an LSB-first atom from the C string [a].
|
||||
*/
|
||||
u3_noun
|
||||
u3_atom
|
||||
u3i_string(const c3_c* a_c)
|
||||
{
|
||||
return u3i_bytes(strlen(a_c), (c3_y *)a_c);
|
||||
@ -549,7 +549,7 @@ u3i_string(const c3_c* a_c)
|
||||
|
||||
/* u3i_tape(): from a C string, to a list of bytes.
|
||||
*/
|
||||
u3_atom
|
||||
u3_noun
|
||||
u3i_tape(const c3_c* txt_c)
|
||||
{
|
||||
if ( !*txt_c ) {
|
||||
|
@ -432,7 +432,7 @@ u3_noun
|
||||
u3m_file(c3_c* pas_c)
|
||||
{
|
||||
struct stat buf_b;
|
||||
c3_i fid_i = open(pas_c, O_RDONLY, 0644);
|
||||
c3_i fid_i = c3_open(pas_c, O_RDONLY, 0644);
|
||||
c3_w fln_w, red_w;
|
||||
c3_y* pad_y;
|
||||
|
||||
|
@ -282,13 +282,13 @@ u3t_trace_open(c3_c* dir_c)
|
||||
|
||||
struct stat st;
|
||||
if ( -1 == stat(fil_c, &st) ) {
|
||||
mkdir(fil_c, 0700);
|
||||
c3_mkdir(fil_c, 0700);
|
||||
}
|
||||
|
||||
c3_c lif_c[2056];
|
||||
snprintf(lif_c, 2056, "%s/%d.json", fil_c, u3_Host.tra_u.fun_w);
|
||||
|
||||
u3_Host.tra_u.fil_u = fopen(lif_c, "w");
|
||||
u3_Host.tra_u.fil_u = c3_fopen(lif_c, "w");
|
||||
u3_Host.tra_u.nid_w = (int)getpid();
|
||||
|
||||
fprintf(u3_Host.tra_u.fil_u, "[ ");
|
||||
|
@ -509,7 +509,7 @@ _cu_rock_path_make(c3_c* dir_c, c3_d eve_d, c3_c** out_c)
|
||||
return c3n;
|
||||
}
|
||||
|
||||
if ( mkdir(nam_c, 0700)
|
||||
if ( c3_mkdir(nam_c, 0700)
|
||||
&& (EEXIST != errno) )
|
||||
{
|
||||
fprintf(stderr, "rock: directory create failed (%s, %" PRIu64 "): %s\r\n",
|
||||
@ -552,8 +552,8 @@ _cu_rock_save(c3_c* dir_c, c3_d eve_d, c3_d len_d, c3_y* byt_y)
|
||||
return c3n;
|
||||
}
|
||||
|
||||
if ( -1 == (fid_i = open(nam_c, O_RDWR | O_CREAT | O_TRUNC, 0644)) ) {
|
||||
fprintf(stderr, "rock: open failed (%s, %" PRIu64 "): %s\r\n",
|
||||
if ( -1 == (fid_i = c3_open(nam_c, O_RDWR | O_CREAT | O_TRUNC, 0644)) ) {
|
||||
fprintf(stderr, "rock: c3_open failed (%s, %" PRIu64 "): %s\r\n",
|
||||
dir_c, eve_d, strerror(errno));
|
||||
c3_free(nam_c);
|
||||
return c3n;
|
||||
@ -691,8 +691,8 @@ u3u_mmap_read(c3_c* cap_c, c3_c* pat_c, c3_d* out_d, c3_y** out_y)
|
||||
|
||||
// open file
|
||||
//
|
||||
if ( -1 == (fid_i = open(pat_c, O_RDONLY, 0644)) ) {
|
||||
fprintf(stderr, "%s: open failed (%s): %s\r\n",
|
||||
if ( -1 == (fid_i = c3_open(pat_c, O_RDONLY, 0644)) ) {
|
||||
fprintf(stderr, "%s: c3_open failed (%s): %s\r\n",
|
||||
cap_c, pat_c, strerror(errno));
|
||||
return c3n;
|
||||
}
|
||||
@ -744,8 +744,8 @@ u3u_mmap(c3_c* cap_c, c3_c* pat_c, c3_d len_d, c3_y** out_y)
|
||||
|
||||
// open file
|
||||
//
|
||||
if ( -1 == (fid_i = open(pat_c, O_RDWR | O_CREAT | O_TRUNC, 0644)) ) {
|
||||
fprintf(stderr, "%s: open failed (%s): %s\r\n",
|
||||
if ( -1 == (fid_i = c3_open(pat_c, O_RDWR | O_CREAT | O_TRUNC, 0644)) ) {
|
||||
fprintf(stderr, "%s: c3_open failed (%s): %s\r\n",
|
||||
cap_c, pat_c, strerror(errno));
|
||||
return c3n;
|
||||
}
|
||||
@ -895,7 +895,7 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d)
|
||||
|
||||
// leave rocks on disk
|
||||
//
|
||||
// if ( 0 != unlink(nam_c) ) {
|
||||
// if ( 0 != c3_unlink(nam_c) ) {
|
||||
// fprintf(stderr, "uncram: failed to delete rock (%s, %" PRIu64 "): %s\r\n",
|
||||
// dir_c, eve_d, strerror(errno));
|
||||
// c3_free(nam_c);
|
||||
|
65
pkg/urbit/tests/unix_tests.c
Normal file
65
pkg/urbit/tests/unix_tests.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
/* _setup(): prepare for tests.
|
||||
*/
|
||||
static void
|
||||
_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* _test_safe():
|
||||
*/
|
||||
static c3_i
|
||||
_test_safe()
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
if ( !u3_unix_cane("/") ||
|
||||
!u3_unix_cane("~.") ||
|
||||
!u3_unix_cane("a") ||
|
||||
!u3_unix_cane("a/b") ||
|
||||
!u3_unix_cane("a/b/c/defg/h/ijklmnop") )
|
||||
{
|
||||
fprintf(stderr, "_safe fail 1\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( u3_unix_cane("") ||
|
||||
u3_unix_cane(".") ||
|
||||
u3_unix_cane("..") ||
|
||||
u3_unix_cane("/.") ||
|
||||
u3_unix_cane("a/b/c//") ||
|
||||
u3_unix_cane("a/b/.") ||
|
||||
u3_unix_cane("/././../.") ||
|
||||
u3_unix_cane("/../etc") )
|
||||
{
|
||||
fprintf(stderr, "_safe fail 2\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( !u3_unix_cane(".a") ||
|
||||
!u3_unix_cane("/.a.b.c/..c") )
|
||||
{
|
||||
fprintf(stderr, "_safe fail 3\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
/* main(): run all test cases.
|
||||
*/
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
_setup();
|
||||
|
||||
if ( !_test_safe() ) {
|
||||
fprintf(stderr, "test unix: failed\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stderr, "test unix: ok\r\n");
|
||||
return 0;
|
||||
}
|
@ -462,7 +462,7 @@ _dawn_come(u3_noun stars)
|
||||
c3_c pat_c[64];
|
||||
snprintf(pat_c, 64, "%s.key", who_c + 1);
|
||||
|
||||
FILE* fil_u = fopen(pat_c, "w");
|
||||
FILE* fil_u = c3_fopen(pat_c, "w");
|
||||
fprintf(fil_u, "%s\n", key_c);
|
||||
fclose(fil_u);
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ u3_lmdb_init(const c3_c* pax_c, size_t siz_i)
|
||||
MDB_env* env_u;
|
||||
c3_w ret_w;
|
||||
|
||||
c3_assert(u3_unix_cane(pax_c));
|
||||
|
||||
if ( (ret_w = mdb_env_create(&env_u)) ) {
|
||||
mdb_logerror(stderr, ret_w, "lmdb: init fail");
|
||||
return 0;
|
||||
|
@ -585,6 +585,94 @@ u3_disk_read_meta(u3_disk* log_u,
|
||||
return c3y;
|
||||
}
|
||||
|
||||
/* _disk_lock(): lockfile path.
|
||||
*/
|
||||
static c3_c*
|
||||
_disk_lock(c3_c* pax_c)
|
||||
{
|
||||
c3_w len_w = strlen(pax_c) + sizeof("/.vere.lock");
|
||||
c3_c* paf_c = c3_malloc(len_w);
|
||||
c3_i wit_i;
|
||||
|
||||
wit_i = snprintf(paf_c, len_w, "%s/.vere.lock", pax_c);
|
||||
c3_assert(wit_i + 1 == len_w);
|
||||
return paf_c;
|
||||
}
|
||||
|
||||
/* u3_disk_acquire(): acquire a lockfile, killing anything that holds it.
|
||||
*/
|
||||
static void
|
||||
u3_disk_acquire(c3_c* pax_c)
|
||||
{
|
||||
c3_c* paf_c = _disk_lock(pax_c);
|
||||
c3_w pid_w;
|
||||
FILE* loq_u;
|
||||
|
||||
if ( NULL != (loq_u = c3_fopen(paf_c, "r")) ) {
|
||||
if ( 1 != fscanf(loq_u, "%" SCNu32, &pid_w) ) {
|
||||
u3l_log("lockfile %s is corrupt!\n", paf_c);
|
||||
kill(getpid(), SIGTERM);
|
||||
sleep(1); c3_assert(0);
|
||||
}
|
||||
else if (pid_w != getpid()) {
|
||||
c3_w i_w;
|
||||
|
||||
if ( -1 != kill(pid_w, SIGTERM) ) {
|
||||
u3l_log("disk: stopping process %d, live in %s...\n",
|
||||
pid_w, pax_c);
|
||||
|
||||
for ( i_w = 0; i_w < 16; i_w++ ) {
|
||||
sleep(1);
|
||||
if ( -1 == kill(pid_w, SIGTERM) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( 16 == i_w ) {
|
||||
for ( i_w = 0; i_w < 16; i_w++ ) {
|
||||
if ( -1 == kill(pid_w, SIGKILL) ) {
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
if ( 16 == i_w ) {
|
||||
u3l_log("disk: process %d seems unkillable!\n", pid_w);
|
||||
c3_assert(0);
|
||||
}
|
||||
u3l_log("disk: stopped old process %u\n", pid_w);
|
||||
}
|
||||
}
|
||||
fclose(loq_u);
|
||||
c3_unlink(paf_c);
|
||||
}
|
||||
|
||||
if ( NULL == (loq_u = c3_fopen(paf_c, "w")) ) {
|
||||
u3l_log("disk: unable to open %s\n", paf_c);
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
fprintf(loq_u, "%u\n", getpid());
|
||||
|
||||
{
|
||||
c3_i fid_i = fileno(loq_u);
|
||||
c3_sync(fid_i);
|
||||
}
|
||||
|
||||
fclose(loq_u);
|
||||
c3_free(paf_c);
|
||||
}
|
||||
|
||||
/* u3_disk_release(): release a lockfile.
|
||||
*/
|
||||
static void
|
||||
u3_disk_release(c3_c* pax_c)
|
||||
{
|
||||
c3_c* paf_c = _disk_lock(pax_c);
|
||||
|
||||
c3_unlink(paf_c);
|
||||
c3_free(paf_c);
|
||||
}
|
||||
|
||||
/* u3_disk_exit(): close the log.
|
||||
*/
|
||||
void
|
||||
@ -633,6 +721,8 @@ u3_disk_exit(u3_disk* log_u)
|
||||
}
|
||||
}
|
||||
|
||||
u3_disk_release(log_u->dir_u->pax_c);
|
||||
|
||||
u3_dire_free(log_u->dir_u);
|
||||
u3_dire_free(log_u->urb_u);
|
||||
u3_dire_free(log_u->com_u);
|
||||
@ -697,6 +787,10 @@ u3_disk_init(c3_c* pax_c, u3_disk_cb cb_u)
|
||||
}
|
||||
}
|
||||
|
||||
// acquire lockfile.
|
||||
//
|
||||
u3_disk_acquire(pax_c);
|
||||
|
||||
// create/load $pier/.urb
|
||||
//
|
||||
{
|
||||
@ -721,11 +815,11 @@ u3_disk_init(c3_c* pax_c, u3_disk_cb cb_u)
|
||||
|
||||
strcpy(dir_c, pax_c);
|
||||
strcat(dir_c, "/.urb/put");
|
||||
mkdir(dir_c, 0700);
|
||||
c3_mkdir(dir_c, 0700);
|
||||
|
||||
strcpy(dir_c, pax_c);
|
||||
strcat(dir_c, "/.urb/get");
|
||||
mkdir(dir_c, 0700);
|
||||
c3_mkdir(dir_c, 0700);
|
||||
|
||||
c3_free(dir_c);
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ u3_foil_folder(const c3_c* pax_c)
|
||||
uv_dirent_t den_u;
|
||||
c3_i err_i;
|
||||
|
||||
c3_assert(u3_unix_cane(pax_c));
|
||||
|
||||
/* open directory, synchronously
|
||||
*/
|
||||
{
|
||||
|
@ -1608,7 +1608,7 @@ _http_write_ports_file(u3_httd* htd_u, c3_c *pax_c)
|
||||
c3_c* paf_c = c3_malloc(len_w);
|
||||
snprintf(paf_c, len_w, "%s/%s", pax_c, nam_c);
|
||||
|
||||
c3_i por_i = open(paf_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
c3_i por_i = c3_open(paf_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
c3_free(paf_c);
|
||||
|
||||
u3_http* htp_u = htd_u->htp_u;
|
||||
@ -1639,7 +1639,7 @@ _http_release_ports_file(c3_c *pax_c)
|
||||
c3_c* paf_c = c3_malloc(len_w);
|
||||
snprintf(paf_c, len_w, "%s/%s", pax_c, nam_c);
|
||||
|
||||
unlink(paf_c);
|
||||
c3_unlink(paf_c);
|
||||
c3_free(paf_c);
|
||||
}
|
||||
|
||||
|
@ -549,14 +549,13 @@ _term_it_show_more(u3_utty* uty_u)
|
||||
/* _term_it_path(): path for console file.
|
||||
*/
|
||||
static c3_c*
|
||||
_term_it_path(c3_o fyl, u3_noun pax)
|
||||
_term_it_path(u3_noun pax)
|
||||
{
|
||||
c3_w len_w;
|
||||
c3_w len_w = 0;
|
||||
c3_c *pas_c;
|
||||
|
||||
// measure
|
||||
//
|
||||
len_w = strlen(u3_Host.dir_c);
|
||||
{
|
||||
u3_noun wiz = pax;
|
||||
|
||||
@ -569,7 +568,6 @@ _term_it_path(c3_o fyl, u3_noun pax)
|
||||
// cut
|
||||
//
|
||||
pas_c = c3_malloc(len_w + 1);
|
||||
strncpy(pas_c, u3_Host.dir_c, len_w);
|
||||
pas_c[len_w] = '\0';
|
||||
{
|
||||
u3_noun wiz = pax;
|
||||
@ -578,7 +576,7 @@ _term_it_path(c3_o fyl, u3_noun pax)
|
||||
while ( u3_nul != wiz ) {
|
||||
c3_w tis_w = u3r_met(3, u3h(wiz));
|
||||
|
||||
if ( (c3y == fyl) && (u3_nul == u3t(wiz)) ) {
|
||||
if ( (u3_nul == u3t(wiz)) ) {
|
||||
*waq_c++ = '.';
|
||||
} else *waq_c++ = '/';
|
||||
|
||||
@ -598,27 +596,10 @@ _term_it_path(c3_o fyl, u3_noun pax)
|
||||
static void
|
||||
_term_it_save(u3_noun pax, u3_noun pad)
|
||||
{
|
||||
c3_c* pax_c;
|
||||
c3_c* bas_c = 0;
|
||||
c3_w xap_w = u3kb_lent(u3k(pax));
|
||||
u3_noun xap = u3_nul;
|
||||
u3_noun urb = c3_s4('.','u','r','b');
|
||||
u3_noun put = c3_s3('p','u','t');
|
||||
|
||||
// directory base and relative path
|
||||
if ( 2 < xap_w ) {
|
||||
u3_noun bas = u3nt(urb, put, u3_nul);
|
||||
bas_c = _term_it_path(c3n, bas);
|
||||
xap = u3qb_scag(xap_w - 2, pax);
|
||||
}
|
||||
|
||||
pax = u3nt(urb, put, pax);
|
||||
pax_c = _term_it_path(c3y, pax);
|
||||
|
||||
u3_walk_save(pax_c, 0, pad, bas_c, xap);
|
||||
c3_c* pax_c = _term_it_path(pax);
|
||||
|
||||
u3_unix_save(pax_c, pad);
|
||||
c3_free(pax_c);
|
||||
c3_free(bas_c);
|
||||
}
|
||||
|
||||
/* _term_ovum_plan(): plan term ovums, configuring spinner.
|
||||
|
@ -1,5 +1,36 @@
|
||||
/* vere/unix.c
|
||||
**
|
||||
** this file is responsible for maintaining a bidirectional
|
||||
** mapping between the contents of a clay desk and a directory
|
||||
** in a unix filesystem.
|
||||
**
|
||||
** TODO this driver is crufty and overdue for a rewrite.
|
||||
** aspirationally, the rewrite should do sanity checking and
|
||||
** transformations at the noun level to convert messages from
|
||||
** arvo into sets of fs operations on trusted inputs, and
|
||||
** inverse transformations and checks for fs contents to arvo
|
||||
** messages.
|
||||
**
|
||||
** the two relevant transformations to apply are:
|
||||
**
|
||||
** 1. bidirectionally map file contents to atoms
|
||||
** 2. bidirectionally map arvo $path <-> unix relative paths
|
||||
**
|
||||
** the first transform is trivial. the second poses some
|
||||
** challenges: an arvo $path is a list of $knot, and the $knot
|
||||
** space intersects with invalid unix paths in the three cases
|
||||
** of: %$ (the empty knot), '.', and '..'. we escape these by
|
||||
** prepending a '!' to the filename corresponding to the $knot,
|
||||
** yielding unix files named '!', '!.', and '!..'.
|
||||
**
|
||||
** there is also the case of the empty path. we elide empty
|
||||
** paths from this wrapper, which always uses the last path
|
||||
** component as the file extension/mime-type.
|
||||
**
|
||||
** these transforms are implemented, but they ought to be
|
||||
** implemented in one place, prior to any fs calls; as-is, they
|
||||
** are sprinkled throughout the file updating code.
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include <ftw.h>
|
||||
@ -58,6 +89,7 @@ struct _u3_ufil;
|
||||
c3_c* pax_c; // pier directory
|
||||
c3_o alm; // timer set
|
||||
c3_o dyr; // ready to update
|
||||
u3_noun sat; // (sane %ta) handle
|
||||
#ifdef SYNCLOG
|
||||
c3_w lot_w; // sync-slot
|
||||
struct _u3_sylo {
|
||||
@ -72,6 +104,50 @@ struct _u3_ufil;
|
||||
void
|
||||
u3_unix_ef_look(u3_unix* unx_u, u3_noun mon, u3_noun all);
|
||||
|
||||
/* u3_unix_cane(): true iff (unix) path is canonical.
|
||||
*/
|
||||
c3_t
|
||||
u3_unix_cane(const c3_c* pax_c)
|
||||
{
|
||||
if ( 0 == pax_c ) {
|
||||
return 0;
|
||||
}
|
||||
// allow absolute paths.
|
||||
//
|
||||
if ( '/' == *pax_c ) {
|
||||
pax_c++;
|
||||
// allow root.
|
||||
//
|
||||
if ( 0 == *pax_c ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
do {
|
||||
if ( 0 == *pax_c
|
||||
|| 0 == strcmp(".", pax_c)
|
||||
|| 0 == strcmp("..", pax_c)
|
||||
|| 0 == strncmp("/", pax_c, 1)
|
||||
|| 0 == strncmp("./", pax_c, 2)
|
||||
|| 0 == strncmp("../", pax_c, 3) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pax_c = strchr(pax_c, '/');
|
||||
} while ( 0 != pax_c++ );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _unix_sane_ta(): true iff pat is a valid @ta
|
||||
**
|
||||
** %ta is parsed by:
|
||||
** (star ;~(pose nud low hep dot sig cab))
|
||||
*/
|
||||
static c3_t
|
||||
_unix_sane_ta(u3_unix* unx_u, u3_atom pat)
|
||||
{
|
||||
return _(u3n_slam_on(u3k(unx_u->sat), pat));
|
||||
}
|
||||
|
||||
/* u3_readdir_r():
|
||||
*/
|
||||
c3_w
|
||||
@ -91,6 +167,56 @@ u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* _unix_string_to_knot(): convert c unix path component to $knot
|
||||
*/
|
||||
static u3_atom
|
||||
_unix_string_to_knot(c3_c* pax_c)
|
||||
{
|
||||
c3_assert(pax_c);
|
||||
// XX this can happen if we encounter a file without an extension.
|
||||
//
|
||||
// c3_assert(*pax_c);
|
||||
c3_assert(!strchr(pax_c, '/'));
|
||||
// XX horrible
|
||||
//
|
||||
# ifdef _WIN32
|
||||
c3_assert(!strchr(pax_c, '\\'));
|
||||
# endif
|
||||
if ( '!' == *pax_c ) {
|
||||
pax_c++;
|
||||
}
|
||||
return u3i_string(pax_c);
|
||||
}
|
||||
|
||||
/* _unix_knot_to_string(): convert $knot to c unix path component. RETAIN.
|
||||
*/
|
||||
static c3_c*
|
||||
_unix_knot_to_string(u3_atom pon)
|
||||
{
|
||||
c3_c* ret_c;
|
||||
|
||||
if ( u3_nul != pon
|
||||
&& c3_s1('.') != pon
|
||||
&& c3_s2('.','.') != pon
|
||||
&& '!' != u3r_byte(0, pon) )
|
||||
{
|
||||
ret_c = u3r_string(pon);
|
||||
}
|
||||
else {
|
||||
c3_w met_w = u3r_met(3, pon);
|
||||
|
||||
ret_c = c3_malloc(met_w + 2);
|
||||
*ret_c = '!';
|
||||
u3r_bytes(0, met_w, (c3_y*)ret_c + 1, pon);
|
||||
ret_c[met_w + 1] = 0;
|
||||
}
|
||||
c3_assert(!strchr(ret_c, '/'));
|
||||
# ifdef _WIN32
|
||||
c3_assert(!strchr(ret_c, '\\'));
|
||||
# endif
|
||||
return ret_c;
|
||||
}
|
||||
|
||||
/* _unix_down(): descend path.
|
||||
*/
|
||||
static c3_c*
|
||||
@ -108,29 +234,34 @@ _unix_down(c3_c* pax_c, c3_c* sub_c)
|
||||
return don_c;
|
||||
}
|
||||
|
||||
/* _unix_string_to_path(): convert c string to u3_noun path
|
||||
*
|
||||
* c string must begin with the pier path plus mountpoint
|
||||
/* _unix_string_to_path(): convert c string to u3_noun $path
|
||||
**
|
||||
** c string must begin with the pier path plus mountpoint
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_string_to_path_helper(c3_c* pax_c)
|
||||
{
|
||||
u3_noun not;
|
||||
|
||||
c3_assert(pax_c[-1] == '/');
|
||||
c3_c* end_w = strchr(pax_c, '/');
|
||||
if ( !end_w ) {
|
||||
end_w = strrchr(pax_c, '.');
|
||||
if ( !end_w ) {
|
||||
return u3nc(u3i_string(pax_c), u3_nul);
|
||||
c3_c* end_c = strchr(pax_c, '/');
|
||||
if ( !end_c ) {
|
||||
end_c = strrchr(pax_c, '.');
|
||||
if ( !end_c ) {
|
||||
return u3nc(_unix_string_to_knot(pax_c), u3_nul);
|
||||
}
|
||||
else {
|
||||
return u3nt(u3i_bytes(end_w - pax_c, (c3_y*) pax_c),
|
||||
u3i_string(end_w + 1),
|
||||
u3_nul);
|
||||
*end_c = 0;
|
||||
not = _unix_string_to_knot(pax_c);
|
||||
*end_c = '.';
|
||||
return u3nt(not, _unix_string_to_knot(end_c + 1), u3_nul);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return u3nc(u3i_bytes(end_w - pax_c, (c3_y*) pax_c),
|
||||
_unix_string_to_path_helper(end_w + 1));
|
||||
*end_c = 0;
|
||||
not = _unix_string_to_knot(pax_c);
|
||||
*end_c = '/';
|
||||
return u3nc(not, _unix_string_to_path_helper(end_c + 1));
|
||||
}
|
||||
}
|
||||
static u3_noun
|
||||
@ -144,7 +275,7 @@ _unix_string_to_path(u3_unix* unx_u, c3_c* pax_c)
|
||||
return u3_nul;
|
||||
}
|
||||
else {
|
||||
return u3nc(u3i_string(pox_c + 1), u3_nul);
|
||||
return u3nc(_unix_string_to_knot(pox_c + 1), u3_nul);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -152,6 +283,77 @@ _unix_string_to_path(u3_unix* unx_u, c3_c* pax_c)
|
||||
}
|
||||
}
|
||||
|
||||
/* _unix_mkdirp(): recursive mkdir of dirname of pax_c.
|
||||
*/
|
||||
static void
|
||||
_unix_mkdirp(c3_c* pax_c)
|
||||
{
|
||||
c3_c* fas_c = strchr(pax_c + 1, '/');
|
||||
|
||||
while ( fas_c ) {
|
||||
*fas_c = 0;
|
||||
if ( 0 != mkdir(pax_c, 0777) && EEXIST != errno ) {
|
||||
u3l_log("unix: mkdir %s: %s\n", pax_c, strerror(errno));
|
||||
u3m_bail(c3__fail);
|
||||
}
|
||||
*fas_c++ = '/';
|
||||
fas_c = strchr(fas_c, '/');
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_unix_save(): save file under .../.urb/put or bail.
|
||||
**
|
||||
** XX this is quite bad, and doesn't share much in common with
|
||||
** the rest of unix.c. a refactor would probably share common
|
||||
** logic with _unix_sync_change, perhaps using openat, making
|
||||
** unx_u optional, and/or having a flag to not track the file
|
||||
** for future changes.
|
||||
*/
|
||||
void
|
||||
u3_unix_save(c3_c* pax_c, u3_atom pad)
|
||||
{
|
||||
c3_i fid_i;
|
||||
c3_w lod_w, len_w, fln_w, rit_w;
|
||||
c3_y* pad_y;
|
||||
c3_c* ful_c;
|
||||
|
||||
if ( !u3_unix_cane(pax_c) ) {
|
||||
u3l_log("%s: non-canonical path\n", pax_c);
|
||||
u3z(pad); u3m_bail(c3__fail);
|
||||
}
|
||||
if ( '/' == *pax_c) {
|
||||
pax_c++;
|
||||
}
|
||||
lod_w = strlen(u3_Host.dir_c);
|
||||
len_w = lod_w + sizeof("/.urb/put/") + strlen(pax_c);
|
||||
ful_c = c3_malloc(len_w);
|
||||
rit_w = snprintf(ful_c, len_w, "%s/.urb/put/%s", u3_Host.dir_c, pax_c);
|
||||
c3_assert(len_w == rit_w + 1);
|
||||
|
||||
_unix_mkdirp(ful_c);
|
||||
fid_i = c3_open(ful_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if ( fid_i < 0 ) {
|
||||
u3l_log("%s: %s\n", ful_c, strerror(errno));
|
||||
c3_free(ful_c);
|
||||
u3z(pad); u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
fln_w = u3r_met(3, pad);
|
||||
pad_y = c3_malloc(fln_w);
|
||||
u3r_bytes(0, fln_w, pad_y, pad);
|
||||
u3z(pad);
|
||||
rit_w = write(fid_i, pad_y, fln_w);
|
||||
close(fid_i);
|
||||
c3_free(pad_y);
|
||||
|
||||
if ( rit_w != fln_w ) {
|
||||
u3l_log("%s: %s\n", ful_c, strerror(errno));
|
||||
c3_free(ful_c);
|
||||
u3m_bail(c3__fail);
|
||||
}
|
||||
c3_free(ful_c);
|
||||
}
|
||||
|
||||
/* _unix_rm_r_cb(): callback to delete individual files/directories
|
||||
*/
|
||||
static c3_i
|
||||
@ -165,7 +367,7 @@ _unix_rm_r_cb(const c3_c* pax_c,
|
||||
u3l_log("bad file type in rm_r: %s\r\n", pax_c);
|
||||
break;
|
||||
case FTW_F:
|
||||
if ( 0 != unlink(pax_c) && ENOENT != errno ) {
|
||||
if ( 0 != c3_unlink(pax_c) && ENOENT != errno ) {
|
||||
u3l_log("error unlinking (in rm_r) %s: %s\n",
|
||||
pax_c, strerror(errno));
|
||||
c3_assert(0);
|
||||
@ -181,7 +383,7 @@ _unix_rm_r_cb(const c3_c* pax_c,
|
||||
u3l_log("couldn't stat path: %s\r\n", pax_c);
|
||||
break;
|
||||
case FTW_DP:
|
||||
if ( 0 != rmdir(pax_c) && ENOENT != errno ) {
|
||||
if ( 0 != c3_rmdir(pax_c) && ENOENT != errno ) {
|
||||
u3l_log("error rmdiring %s: %s\n", pax_c, strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
@ -213,7 +415,7 @@ _unix_rm_r(c3_c* pax_c)
|
||||
static void
|
||||
_unix_mkdir(c3_c* pax_c)
|
||||
{
|
||||
if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno) {
|
||||
if ( 0 != c3_mkdir(pax_c, 0755) && EEXIST != errno) {
|
||||
u3l_log("error mkdiring %s: %s\n", pax_c, strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
@ -224,7 +426,7 @@ _unix_mkdir(c3_c* pax_c)
|
||||
static c3_w
|
||||
_unix_write_file_hard(c3_c* pax_c, u3_noun mim)
|
||||
{
|
||||
c3_i fid_i = open(pax_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
c3_i fid_i = c3_open(pax_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
c3_w len_w, rit_w, siz_w, mug_w = 0;
|
||||
c3_y* dat_y;
|
||||
|
||||
@ -267,7 +469,7 @@ static void
|
||||
_unix_write_file_soft(u3_ufil* fil_u, u3_noun mim)
|
||||
{
|
||||
struct stat buf_u;
|
||||
c3_i fid_i = open(fil_u->pax_c, O_RDONLY, 0644);
|
||||
c3_i fid_i = c3_open(fil_u->pax_c, O_RDONLY, 0644);
|
||||
c3_ws len_ws, red_ws;
|
||||
c3_w old_w;
|
||||
c3_y* old_y;
|
||||
@ -339,7 +541,7 @@ _unix_get_mount_point(u3_unix* unx_u, u3_noun mon)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c3_c* nam_c = u3r_string(mon);
|
||||
c3_c* nam_c = _unix_knot_to_string(mon);
|
||||
u3_umon* mon_u;
|
||||
|
||||
for ( mon_u = unx_u->mon_u;
|
||||
@ -374,7 +576,7 @@ _unix_get_mount_point(u3_unix* unx_u, u3_noun mon)
|
||||
static void
|
||||
_unix_scan_mount_point(u3_unix* unx_u, u3_umon* mon_u)
|
||||
{
|
||||
DIR* rid_u = opendir(mon_u->dir_u.pax_c);
|
||||
DIR* rid_u = c3_opendir(mon_u->dir_u.pax_c);
|
||||
if ( !rid_u ) {
|
||||
u3l_log("error opening pier directory: %s: %s\r\n",
|
||||
mon_u->dir_u.pax_c, strerror(errno));
|
||||
@ -425,12 +627,11 @@ _unix_scan_mount_point(u3_unix* unx_u, u3_umon* mon_u)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( '.' != out_u->d_name[len_w]
|
||||
|| '\0' == out_u->d_name[len_w + 1]
|
||||
|| '~' == out_u->d_name[strlen(out_u->d_name) - 1]
|
||||
|| ('#' == out_u->d_name[0] &&
|
||||
'#' == out_u->d_name[strlen(out_u->d_name) - 1])
|
||||
) {
|
||||
if ( '.' != out_u->d_name[len_w]
|
||||
|| '\0' == out_u->d_name[len_w + 1]
|
||||
|| '~' == out_u->d_name[strlen(out_u->d_name) - 1]
|
||||
|| !_unix_sane_ta(unx_u, _unix_string_to_knot(out_u->d_name)) )
|
||||
{
|
||||
c3_free(pax_c);
|
||||
continue;
|
||||
}
|
||||
@ -452,7 +653,7 @@ static u3_noun _unix_free_node(u3_unix* unx_u, u3_unod* nod_u);
|
||||
static void
|
||||
_unix_free_file(u3_ufil *fil_u)
|
||||
{
|
||||
if ( 0 != unlink(fil_u->pax_c) && ENOENT != errno ) {
|
||||
if ( 0 != c3_unlink(fil_u->pax_c) && ENOENT != errno ) {
|
||||
u3l_log("error unlinking %s: %s\n", fil_u->pax_c, strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
@ -482,8 +683,8 @@ _unix_free_dir(u3_udir *dir_u)
|
||||
}
|
||||
|
||||
/* _unix_free_node(): free node, deleting everything within
|
||||
*
|
||||
* also deletes from parent list if in it
|
||||
**
|
||||
** also deletes from parent list if in it
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_free_node(u3_unix* unx_u, u3_unod* nod_u)
|
||||
@ -526,12 +727,12 @@ _unix_free_node(u3_unix* unx_u, u3_unod* nod_u)
|
||||
}
|
||||
|
||||
/* _unix_free_mount_point(): free mount point
|
||||
*
|
||||
* this process needs to happen in a very careful order. in particular,
|
||||
* we must recurse before we get to the callback, so that libuv does all
|
||||
* the child directories before it does us.
|
||||
*
|
||||
* tread carefully
|
||||
**
|
||||
** this process needs to happen in a very careful order. in
|
||||
** particular, we must recurse before we get to the callback, so
|
||||
** that libuv does all the child directories before it does us.
|
||||
**
|
||||
** tread carefully
|
||||
*/
|
||||
static void
|
||||
_unix_free_mount_point(u3_unix* unx_u, u3_umon* mon_u)
|
||||
@ -559,7 +760,7 @@ _unix_delete_mount_point(u3_unix* unx_u, u3_noun mon)
|
||||
return;
|
||||
}
|
||||
|
||||
c3_c* nam_c = u3r_string(mon);
|
||||
c3_c* nam_c = _unix_knot_to_string(mon);
|
||||
u3_umon* mon_u;
|
||||
u3_umon* tem_u;
|
||||
|
||||
@ -651,7 +852,7 @@ _unix_watch_dir(u3_udir* dir_u, u3_udir* par_u, c3_c* pax_c)
|
||||
static void
|
||||
_unix_create_dir(u3_udir* dir_u, u3_udir* par_u, u3_noun nam)
|
||||
{
|
||||
c3_c* nam_c = u3r_string(nam);
|
||||
c3_c* nam_c = _unix_knot_to_string(nam);
|
||||
c3_w nam_w = strlen(nam_c);
|
||||
c3_w pax_w = strlen(par_u->pax_c);
|
||||
c3_c* pax_c = c3_malloc(pax_w + 1 + nam_w + 1);
|
||||
@ -671,12 +872,13 @@ _unix_create_dir(u3_udir* dir_u, u3_udir* par_u, u3_noun nam)
|
||||
static u3_noun _unix_update_node(u3_unix* unx_u, u3_unod* nod_u);
|
||||
|
||||
/* _unix_update_file(): update file, producing list of changes
|
||||
*
|
||||
* when scanning through files, if dry, do nothing. otherwise, mark as
|
||||
* dry, then check if file exists. if not, remove self from node list
|
||||
* and add path plus sig to %into event. otherwise, read the file and
|
||||
* get a mug checksum. if same as gum_w, move on. otherwise, overwrite
|
||||
* add path plus data to %into event.
|
||||
**
|
||||
** when scanning through files, if dry, do nothing. otherwise,
|
||||
** mark as dry, then check if file exists. if not, remove
|
||||
** self from node list and add path plus sig to %into event.
|
||||
** otherwise, read the file and get a mug checksum. if same as
|
||||
** gum_w, move on. otherwise, overwrite add path plus data to
|
||||
** %into event.
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_update_file(u3_unix* unx_u, u3_ufil* fil_u)
|
||||
@ -690,7 +892,7 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u)
|
||||
fil_u->dry = c3n;
|
||||
|
||||
struct stat buf_u;
|
||||
c3_i fid_i = open(fil_u->pax_c, O_RDONLY, 0644);
|
||||
c3_i fid_i = c3_open(fil_u->pax_c, O_RDONLY, 0644);
|
||||
c3_ws len_ws, red_ws;
|
||||
c3_y* dat_y;
|
||||
|
||||
@ -745,9 +947,9 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u)
|
||||
}
|
||||
|
||||
/* _unix_update_dir(): update directory, producing list of changes
|
||||
*
|
||||
* when changing this, consider whether to also change
|
||||
* _unix_initial_update_dir()
|
||||
**
|
||||
** when changing this, consider whether to also change
|
||||
** _unix_initial_update_dir()
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_update_dir(u3_unix* unx_u, u3_udir* dir_u)
|
||||
@ -773,7 +975,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u)
|
||||
}
|
||||
else {
|
||||
if ( c3y == nod_u->dir ) {
|
||||
DIR* red_u = opendir(nod_u->pax_c);
|
||||
DIR* red_u = c3_opendir(nod_u->pax_c);
|
||||
if ( 0 == red_u ) {
|
||||
u3_unod* nex_u = nod_u->nex_u;
|
||||
can = u3kb_weld(_unix_free_node(unx_u, nod_u), can);
|
||||
@ -786,7 +988,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u)
|
||||
}
|
||||
else {
|
||||
struct stat buf_u;
|
||||
c3_i fid_i = open(nod_u->pax_c, O_RDONLY, 0644);
|
||||
c3_i fid_i = c3_open(nod_u->pax_c, O_RDONLY, 0644);
|
||||
|
||||
if ( (fid_i < 0) || (fstat(fid_i, &buf_u) < 0) ) {
|
||||
if ( ENOENT != errno ) {
|
||||
@ -813,7 +1015,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u)
|
||||
|
||||
// Check for new nodes
|
||||
|
||||
DIR* rid_u = opendir(dir_u->pax_c);
|
||||
DIR* rid_u = c3_opendir(dir_u->pax_c);
|
||||
if ( !rid_u ) {
|
||||
u3l_log("error opening directory %s: %s\r\n",
|
||||
dir_u->pax_c, strerror(errno));
|
||||
@ -869,11 +1071,10 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u)
|
||||
|
||||
if ( !nod_u ) {
|
||||
if ( !S_ISDIR(buf_u.st_mode) ) {
|
||||
if ( !strchr(out_u->d_name,'.')
|
||||
|| '~' == out_u->d_name[strlen(out_u->d_name) - 1]
|
||||
|| ('#' == out_u->d_name[0] &&
|
||||
'#' == out_u->d_name[strlen(out_u->d_name) - 1])
|
||||
) {
|
||||
if ( !strchr(out_u->d_name,'.')
|
||||
|| '~' == out_u->d_name[strlen(out_u->d_name) - 1]
|
||||
|| !_unix_sane_ta(unx_u, _unix_string_to_knot(out_u->d_name)) )
|
||||
{
|
||||
c3_free(pax_c);
|
||||
continue;
|
||||
}
|
||||
@ -942,7 +1143,8 @@ _unix_update_mount(u3_unix* unx_u, u3_umon* mon_u, u3_noun all)
|
||||
u3_noun wir = u3nt(c3__sync,
|
||||
u3dc("scot", c3__uv, unx_u->sev_l),
|
||||
u3_nul);
|
||||
u3_noun cad = u3nq(c3__into, u3i_string(mon_u->nam_c), all, can);
|
||||
u3_noun cad = u3nq(c3__into, _unix_string_to_knot(mon_u->nam_c), all,
|
||||
can);
|
||||
|
||||
u3_auto_plan(&unx_u->car_u, u3_ovum_init(0, c3__c, wir, cad));
|
||||
}
|
||||
@ -950,13 +1152,13 @@ _unix_update_mount(u3_unix* unx_u, u3_umon* mon_u, u3_noun all)
|
||||
}
|
||||
|
||||
/* _unix_initial_update_file(): read file, but don't watch
|
||||
** XX deduplicate with _unix_update_file()
|
||||
** XX deduplicate with _unix_update_file()
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_initial_update_file(c3_c* pax_c, c3_c* bas_c)
|
||||
{
|
||||
struct stat buf_u;
|
||||
c3_i fid_i = open(pax_c, O_RDONLY, 0644);
|
||||
c3_i fid_i = c3_open(pax_c, O_RDONLY, 0644);
|
||||
c3_ws len_ws, red_ws;
|
||||
c3_y* dat_y;
|
||||
|
||||
@ -1006,14 +1208,14 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c)
|
||||
}
|
||||
|
||||
/* _unix_initial_update_dir(): read directory, but don't watch
|
||||
** XX deduplicate with _unix_update_dir()
|
||||
** XX deduplicate with _unix_update_dir()
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c)
|
||||
{
|
||||
u3_noun can = u3_nul;
|
||||
|
||||
DIR* rid_u = opendir(pax_c);
|
||||
DIR* rid_u = c3_opendir(pax_c);
|
||||
if ( !rid_u ) {
|
||||
u3l_log("error opening initial directory: %s: %s\r\n",
|
||||
pax_c, strerror(errno));
|
||||
@ -1089,8 +1291,8 @@ _unix_sync_file(u3_unix* unx_u, u3_udir* par_u, u3_noun nam, u3_noun ext, u3_nou
|
||||
|
||||
// form file path
|
||||
|
||||
c3_c* nam_c = u3r_string(nam);
|
||||
c3_c* ext_c = u3r_string(ext);
|
||||
c3_c* nam_c = _unix_knot_to_string(nam);
|
||||
c3_c* ext_c = _unix_knot_to_string(ext);
|
||||
c3_w par_w = strlen(par_u->pax_c);
|
||||
c3_w nam_w = strlen(nam_c);
|
||||
c3_w ext_w = strlen(ext_c);
|
||||
@ -1174,7 +1376,7 @@ _unix_sync_change(u3_unix* unx_u, u3_udir* dir_u, u3_noun pax, u3_noun mim)
|
||||
_unix_sync_file(unx_u, dir_u, u3k(i_pax), u3k(it_pax), mim);
|
||||
}
|
||||
else {
|
||||
c3_c* nam_c = u3r_string(i_pax);
|
||||
c3_c* nam_c = _unix_knot_to_string(i_pax);
|
||||
c3_w pax_w = strlen(dir_u->pax_c);
|
||||
u3_unod* nod_u;
|
||||
|
||||
@ -1207,7 +1409,7 @@ static void
|
||||
_unix_sync_ergo(u3_unix* unx_u, u3_umon* mon_u, u3_noun can)
|
||||
{
|
||||
u3_noun nac = can;
|
||||
u3_noun nam = u3i_string(mon_u->nam_c);
|
||||
u3_noun nam = _unix_string_to_knot(mon_u->nam_c);
|
||||
|
||||
while ( u3_nul != nac) {
|
||||
_unix_sync_change(unx_u, &mon_u->dir_u,
|
||||
@ -1263,98 +1465,24 @@ u3_unix_ef_hill(u3_unix* unx_u, u3_noun hil)
|
||||
u3z(hil);
|
||||
}
|
||||
|
||||
/* u3_unix_acquire(): acquire a lockfile, killing anything that holds it.
|
||||
*/
|
||||
static void
|
||||
u3_unix_acquire(c3_c* pax_c)
|
||||
{
|
||||
c3_c* paf_c = _unix_down(pax_c, ".vere.lock");
|
||||
c3_w pid_w;
|
||||
FILE* loq_u;
|
||||
|
||||
if ( NULL != (loq_u = fopen(paf_c, "r")) ) {
|
||||
if ( 1 != fscanf(loq_u, "%" SCNu32, &pid_w) ) {
|
||||
u3l_log("lockfile %s is corrupt!\n", paf_c);
|
||||
kill(getpid(), SIGTERM);
|
||||
sleep(1); c3_assert(0);
|
||||
}
|
||||
else if (pid_w != getpid()) {
|
||||
c3_w i_w;
|
||||
|
||||
if ( -1 != kill(pid_w, SIGTERM) ) {
|
||||
u3l_log("unix: stopping process %d, live in %s...\n",
|
||||
pid_w, pax_c);
|
||||
|
||||
for ( i_w = 0; i_w < 16; i_w++ ) {
|
||||
sleep(1);
|
||||
if ( -1 == kill(pid_w, SIGTERM) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( 16 == i_w ) {
|
||||
for ( i_w = 0; i_w < 16; i_w++ ) {
|
||||
if ( -1 == kill(pid_w, SIGKILL) ) {
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
if ( 16 == i_w ) {
|
||||
u3l_log("unix: process %d seems unkillable!\n", pid_w);
|
||||
c3_assert(0);
|
||||
}
|
||||
u3l_log("unix: stopped old process %u\n", pid_w);
|
||||
}
|
||||
}
|
||||
fclose(loq_u);
|
||||
unlink(paf_c);
|
||||
}
|
||||
|
||||
if ( NULL == (loq_u = fopen(paf_c, "w")) ) {
|
||||
u3l_log("unix: unable to open %s\n", paf_c);
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
fprintf(loq_u, "%u\n", getpid());
|
||||
|
||||
{
|
||||
c3_i fid_i = fileno(loq_u);
|
||||
c3_sync(fid_i);
|
||||
}
|
||||
|
||||
fclose(loq_u);
|
||||
c3_free(paf_c);
|
||||
}
|
||||
|
||||
/* u3_unix_release(): release a lockfile.
|
||||
*/
|
||||
static void
|
||||
u3_unix_release(c3_c* pax_c)
|
||||
{
|
||||
c3_c* paf_c = _unix_down(pax_c, ".vere.lock");
|
||||
|
||||
unlink(paf_c);
|
||||
c3_free(paf_c);
|
||||
}
|
||||
|
||||
/* u3_unix_ef_look(): update the root of a specific mount point.
|
||||
*/
|
||||
void
|
||||
u3_unix_ef_look(u3_unix* unx_u, u3_noun mon, u3_noun all)
|
||||
{
|
||||
if ( c3y == unx_u->dyr ) {
|
||||
c3_c* nam_c = _unix_knot_to_string(mon);
|
||||
|
||||
unx_u->dyr = c3n;
|
||||
u3_umon* mon_u = unx_u->mon_u;
|
||||
|
||||
while ( mon_u && ( c3n == u3r_sing_c(mon_u->nam_c, mon) ) ) {
|
||||
while ( mon_u && 0 != strcmp(nam_c, mon_u->nam_c) ) {
|
||||
mon_u = mon_u->nex_u;
|
||||
}
|
||||
|
||||
c3_free(nam_c);
|
||||
if ( mon_u ) {
|
||||
_unix_update_mount(unx_u, mon_u, all);
|
||||
}
|
||||
}
|
||||
|
||||
u3z(mon);
|
||||
}
|
||||
|
||||
@ -1431,10 +1559,7 @@ _unix_io_exit(u3_auto* car_u)
|
||||
{
|
||||
u3_unix* unx_u = (u3_unix*)car_u;
|
||||
|
||||
// XX move to disk.c?
|
||||
//
|
||||
u3_unix_release(unx_u->pax_c);
|
||||
|
||||
u3z(unx_u->sat);
|
||||
c3_free(unx_u->pax_c);
|
||||
c3_free(unx_u);
|
||||
}
|
||||
@ -1449,10 +1574,7 @@ u3_unix_io_init(u3_pier* pir_u)
|
||||
unx_u->pax_c = strdup(pir_u->pax_c);
|
||||
unx_u->alm = c3n;
|
||||
unx_u->dyr = c3n;
|
||||
|
||||
// XX move to disk.c?
|
||||
//
|
||||
u3_unix_acquire(unx_u->pax_c);
|
||||
unx_u->sat = u3do("sane", c3__ta);
|
||||
|
||||
u3_auto* car_u = &unx_u->car_u;
|
||||
car_u->nam_m = c3__unix;
|
||||
|
@ -924,13 +924,13 @@ u3_king_grab(void* vod_p)
|
||||
|
||||
struct stat st;
|
||||
if ( -1 == stat(nam_c, &st) ) {
|
||||
mkdir(nam_c, 0700);
|
||||
c3_mkdir(nam_c, 0700);
|
||||
}
|
||||
|
||||
c3_c man_c[2048];
|
||||
snprintf(man_c, 2048, "%s/%s-daemon.txt", nam_c, wen_c);
|
||||
|
||||
fil_u = fopen(man_c, "w");
|
||||
fil_u = c3_fopen(man_c, "w");
|
||||
fprintf(fil_u, "%s\r\n", wen_c);
|
||||
|
||||
c3_free(wen_c);
|
||||
|
@ -526,12 +526,11 @@ _pier_on_scry_done(void* ptr_v, u3_noun nun)
|
||||
// if serialization and export path succeeded, write to disk
|
||||
//
|
||||
if ( (u3_none != out) && (u3_none != pad) ) {
|
||||
c3_c fil_c[2048];
|
||||
snprintf(fil_c, 2048, "%s/.urb/put/%s.%s",
|
||||
pir_u->pax_c, pac_c+1, ext_c);
|
||||
c3_c fil_c[256];
|
||||
snprintf(fil_c, 256, "%s.%s", pac_c + 1, ext_c);
|
||||
|
||||
u3_walk_save(fil_c, 0, out, pir_u->pax_c, pad);
|
||||
u3l_log("pier: scry result in %s\n", fil_c);
|
||||
u3_unix_save(fil_c, pad);
|
||||
u3l_log("pier: scry result in %s/.urb/put/%s\n", u3_Host.dir_c, fil_c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,326 +0,0 @@
|
||||
/* vere/walk.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
/* |%
|
||||
** ++ arch :: fs node
|
||||
** $% [& p=@uvI q=*] :: file, hash/data
|
||||
** [| p=(map ,@ta arch)] :: directory
|
||||
** == ::
|
||||
** --
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static u3_noun
|
||||
_walk_ok(u3_noun nod)
|
||||
{
|
||||
u3_noun don = u3n_mung(u3k(u2A->toy.arch), u3k(nod));
|
||||
|
||||
if ( c3n == u3_sing(nod, don) ) {
|
||||
c3_assert(0);
|
||||
}
|
||||
u3z(don);
|
||||
return nod;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u3_walk_safe(): load file or 0.
|
||||
*/
|
||||
u3_noun
|
||||
u3_walk_safe(c3_c* pas_c)
|
||||
{
|
||||
struct stat buf_b;
|
||||
c3_i fid_i = open(pas_c, O_RDONLY, 0644);
|
||||
c3_w fln_w, red_w;
|
||||
c3_y* pad_y;
|
||||
|
||||
if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
|
||||
// u3l_log("%s: %s\n", pas_c, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
fln_w = buf_b.st_size;
|
||||
pad_y = c3_malloc(buf_b.st_size);
|
||||
|
||||
red_w = read(fid_i, pad_y, fln_w);
|
||||
close(fid_i);
|
||||
|
||||
if ( fln_w != red_w ) {
|
||||
c3_free(pad_y);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
u3_noun pad = u3i_bytes(fln_w, (c3_y *)pad_y);
|
||||
c3_free(pad_y);
|
||||
|
||||
return pad;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_walk_load(): load file or bail.
|
||||
*/
|
||||
u3_noun
|
||||
u3_walk_load(c3_c* pas_c)
|
||||
{
|
||||
struct stat buf_b;
|
||||
c3_i fid_i = open(pas_c, O_RDONLY, 0644);
|
||||
c3_w fln_w, red_w;
|
||||
c3_y* pad_y;
|
||||
|
||||
if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
|
||||
u3l_log("%s: %s\n", pas_c, strerror(errno));
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
fln_w = buf_b.st_size;
|
||||
pad_y = c3_malloc(buf_b.st_size);
|
||||
|
||||
red_w = read(fid_i, pad_y, fln_w);
|
||||
close(fid_i);
|
||||
|
||||
if ( fln_w != red_w ) {
|
||||
c3_free(pad_y);
|
||||
u3l_log("u3_walk_load failed");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
u3_noun pad = u3i_bytes(fln_w, (c3_y *)pad_y);
|
||||
c3_free(pad_y);
|
||||
|
||||
return pad;
|
||||
}
|
||||
}
|
||||
|
||||
/* _walk_mkdirp(): recursively make directories in pax at bas_c (RETAIN)
|
||||
*/
|
||||
static void
|
||||
_walk_mkdirp(c3_c* bas_c, u3_noun pax)
|
||||
{
|
||||
c3_c* pax_c;
|
||||
c3_y* waq_y;
|
||||
c3_w pax_w, fas_w, len_w;
|
||||
|
||||
if ( u3_nul == pax ) {
|
||||
return;
|
||||
}
|
||||
|
||||
pax_w = u3r_met(3, u3h(pax));
|
||||
fas_w = strlen(bas_c);
|
||||
len_w = 1 + fas_w + pax_w;
|
||||
|
||||
pax_c = c3_malloc(1 + len_w);
|
||||
strcpy(pax_c, bas_c);
|
||||
|
||||
pax_c[fas_w] = '/';
|
||||
waq_y = (void*)(1 + pax_c + fas_w);
|
||||
u3r_bytes(0, pax_w, waq_y, u3h(pax));
|
||||
pax_c[len_w] = '\0';
|
||||
|
||||
if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno ) {
|
||||
u3l_log("error mkdiring %s: %s\n", pax_c, strerror(errno));
|
||||
u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
_walk_mkdirp(pax_c, u3t(pax));
|
||||
c3_free(pax_c);
|
||||
}
|
||||
|
||||
/* u3_walk_save(): save file or bail.
|
||||
*/
|
||||
void
|
||||
u3_walk_save(c3_c* pas_c, u3_noun tim, u3_atom pad, c3_c* bas_c, u3_noun pax)
|
||||
{
|
||||
c3_i fid_i = open(pas_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
c3_w fln_w, rit_w;
|
||||
c3_y* pad_y;
|
||||
|
||||
if ( fid_i < 0 ) {
|
||||
if ( ENOENT == errno && u3_nul != pax ) {
|
||||
_walk_mkdirp(bas_c, pax);
|
||||
return u3_walk_save(pas_c, tim, pad, 0, u3_nul);
|
||||
}
|
||||
|
||||
u3l_log("%s: %s\n", pas_c, strerror(errno));
|
||||
u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
fln_w = u3r_met(3, pad);
|
||||
pad_y = c3_malloc(fln_w);
|
||||
u3r_bytes(0, fln_w, pad_y, pad);
|
||||
u3z(pad);
|
||||
u3z(pax);
|
||||
|
||||
rit_w = write(fid_i, pad_y, fln_w);
|
||||
close(fid_i);
|
||||
c3_free(pad_y);
|
||||
|
||||
if ( rit_w != fln_w ) {
|
||||
u3l_log("%s: %s\n", pas_c, strerror(errno));
|
||||
u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
if ( 0 != tim ) {
|
||||
struct timeval tim_tv[2];
|
||||
|
||||
u3_time_out_tv(&tim_tv[0], u3k(tim));
|
||||
u3_time_out_tv(&tim_tv[1], tim);
|
||||
|
||||
utimes(pas_c, tim_tv);
|
||||
}
|
||||
}
|
||||
|
||||
/* _walk_in(): inner loop of _walk(), producing map.
|
||||
*/
|
||||
static u3_noun
|
||||
_walk_in(const c3_c* dir_c, c3_w len_w)
|
||||
{
|
||||
DIR* dir_d = opendir(dir_c);
|
||||
u3_noun map = u3_nul;
|
||||
|
||||
if ( !dir_d ) {
|
||||
return u3_nul;
|
||||
}
|
||||
else while ( 1 ) {
|
||||
struct dirent ent_n;
|
||||
struct dirent* out_n;
|
||||
|
||||
if ( u3_readdir_r(dir_d, &ent_n, &out_n) != 0 ) {
|
||||
u3l_log("%s: %s\n", dir_c, strerror(errno));
|
||||
break;
|
||||
}
|
||||
else if ( !out_n ) {
|
||||
break;
|
||||
}
|
||||
else if ( !strcmp(out_n->d_name, ".") ||
|
||||
!strcmp(out_n->d_name, "..") ||
|
||||
('~' == out_n->d_name[0]) ||
|
||||
('.' == out_n->d_name[0]) ) // XX restricts some spans
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
c3_c* fil_c = out_n->d_name;
|
||||
c3_w lef_w = len_w + 1 + strlen(fil_c);
|
||||
c3_c* pat_c = c3_malloc(lef_w + 1);
|
||||
struct stat buf_b;
|
||||
|
||||
strncpy(pat_c, dir_c, lef_w);
|
||||
pat_c[len_w] = '/';
|
||||
strncpy(pat_c + len_w + 1, fil_c, lef_w);
|
||||
pat_c[lef_w] = '\0';
|
||||
|
||||
if ( 0 != stat(pat_c, &buf_b) ) {
|
||||
c3_free(pat_c);
|
||||
} else {
|
||||
u3_noun tim = c3_stat_mtime(&buf_b);
|
||||
|
||||
if ( !S_ISDIR(buf_b.st_mode) ) {
|
||||
c3_c* dot_c = strrchr(fil_c, '.');
|
||||
c3_c* nam_c = strdup(fil_c);
|
||||
c3_c* ext_c = strdup(dot_c + 1);
|
||||
|
||||
nam_c[dot_c - fil_c] = 0;
|
||||
{
|
||||
u3_noun nam = u3i_string(nam_c);
|
||||
u3_noun ext = u3i_string(ext_c);
|
||||
u3_noun get = u3kdb_get(u3k(map), u3k(nam));
|
||||
u3_noun dat = u3_walk_load(pat_c);
|
||||
u3_noun hax;
|
||||
|
||||
if ( !strcmp("noun", ext_c) ) {
|
||||
dat = u3ke_cue(dat);
|
||||
}
|
||||
hax = u3do("sham", u3k(dat));
|
||||
if ( u3_none == get ) { get = u3_nul; }
|
||||
|
||||
get = u3kdb_put(get, ext, u3nt(c3y, hax, dat));
|
||||
map = u3kdb_put(map, nam, u3nc(c3n, get));
|
||||
}
|
||||
c3_free(nam_c);
|
||||
c3_free(ext_c);
|
||||
}
|
||||
else {
|
||||
u3_noun dir = _walk_in(pat_c, lef_w);
|
||||
|
||||
if ( u3_nul != dir ) {
|
||||
map = u3kdb_put
|
||||
(map, u3i_string(fil_c), u3nc(c3n, dir));
|
||||
}
|
||||
else u3z(tim);
|
||||
}
|
||||
c3_free(pat_c);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir_d);
|
||||
return map;
|
||||
}
|
||||
|
||||
/* u3_walk(): traverse `dir_c` to produce an arch, updating `old`.
|
||||
*/
|
||||
u3_noun
|
||||
u3_walk(const c3_c* dir_c, u3_noun old)
|
||||
{
|
||||
// XX - obviously, cheaper to update old data.
|
||||
u3z(old);
|
||||
{
|
||||
struct stat buf_b;
|
||||
|
||||
if ( 0 != stat(dir_c, &buf_b) ) {
|
||||
u3l_log("can't stat %s\n", dir_c);
|
||||
// return u3m_bail(c3__fail);
|
||||
c3_assert(0);
|
||||
}
|
||||
else {
|
||||
return u3nc(c3n,
|
||||
_walk_in(dir_c, strlen(dir_c)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_path(): C unix path in computer for file or directory.
|
||||
*/
|
||||
c3_c*
|
||||
u3_path(c3_o fyl, u3_noun pax)
|
||||
{
|
||||
c3_w len_w;
|
||||
c3_c *pas_c;
|
||||
|
||||
// measure
|
||||
//
|
||||
len_w = strlen(u3_Local);
|
||||
{
|
||||
u3_noun wiz = pax;
|
||||
|
||||
while ( u3_nul != wiz ) {
|
||||
len_w += (1 + u3r_met(3, u3h(wiz)));
|
||||
wiz = u3t(wiz);
|
||||
}
|
||||
}
|
||||
|
||||
// cut
|
||||
//
|
||||
pas_c = c3_malloc(len_w + 1);
|
||||
strncpy(pas_c, u3_Local, len_w);
|
||||
pas_c[len_w] = '\0';
|
||||
{
|
||||
u3_noun wiz = pax;
|
||||
c3_c* waq_c = (pas_c + strlen(pas_c));
|
||||
|
||||
while ( u3_nul != wiz ) {
|
||||
c3_w tis_w = u3r_met(3, u3h(wiz));
|
||||
|
||||
if ( (c3y == fyl) && (u3_nul == u3t(wiz)) ) {
|
||||
*waq_c++ = '.';
|
||||
} else *waq_c++ = '/';
|
||||
|
||||
u3r_bytes(0, tis_w, (c3_y*)waq_c, u3h(wiz));
|
||||
waq_c += tis_w;
|
||||
|
||||
wiz = u3t(wiz);
|
||||
}
|
||||
*waq_c = 0;
|
||||
}
|
||||
u3z(pax);
|
||||
return pas_c;
|
||||
}
|
@ -131,7 +131,7 @@ _cw_serf_stdio(c3_i* inn_i, c3_i* out_i)
|
||||
// we replace [FD 0] (stdin) with a fd pointing to /dev/null
|
||||
// we replace [FD 1] (stdout) with a dup of [FD 2] (stderr)
|
||||
//
|
||||
c3_i nul_i = open(c3_dev_null, O_RDWR, 0);
|
||||
c3_i nul_i = c3_open(c3_dev_null, O_RDWR, 0);
|
||||
|
||||
*inn_i = dup(0);
|
||||
*out_i = dup(1);
|
||||
|
@ -204,13 +204,13 @@ _serf_grab(u3_noun sac)
|
||||
|
||||
struct stat st;
|
||||
if ( -1 == stat(nam_c, &st) ) {
|
||||
mkdir(nam_c, 0700);
|
||||
c3_mkdir(nam_c, 0700);
|
||||
}
|
||||
|
||||
c3_c man_c[2054];
|
||||
snprintf(man_c, 2053, "%s/%s-serf.txt", nam_c, wen_c);
|
||||
|
||||
fil_u = fopen(man_c, "w");
|
||||
fil_u = c3_fopen(man_c, "w");
|
||||
fprintf(fil_u, "%s\r\n", wen_c);
|
||||
|
||||
c3_free(wen_c);
|
||||
@ -835,13 +835,13 @@ _serf_writ_live_exit(u3_serf* sef_u, c3_w cod_w)
|
||||
|
||||
struct stat st;
|
||||
if ( -1 == stat(nam_c, &st) ) {
|
||||
mkdir(nam_c, 0700);
|
||||
c3_mkdir(nam_c, 0700);
|
||||
}
|
||||
|
||||
c3_c man_c[2054];
|
||||
snprintf(man_c, 2053, "%s/%s.txt", nam_c, wen_c);
|
||||
|
||||
fil_u = fopen(man_c, "w");
|
||||
fil_u = c3_fopen(man_c, "w");
|
||||
|
||||
c3_free(wen_c);
|
||||
u3z(wen);
|
||||
|
Loading…
Reference in New Issue
Block a user