Merge branch 'test' into do

This commit is contained in:
Henry Ault 2015-05-06 14:05:58 -07:00
commit 71240536df
16 changed files with 370 additions and 182 deletions

View File

@ -64,7 +64,8 @@ INCLUDE=i
MDEFINES=-DU3_OS_$(OS) -DU3_OS_ENDIAN_$(ENDIAN) -D U3_LIB=\"$(LIB)\"
# NOTFORCHECKIN - restore -O3
CFLAGS= $(COSFLAGS) -O3 -msse3 -ffast-math \
# -DGHETTO
CFLAGS= $(COSFLAGS) -g -msse3 -ffast-math \
-funsigned-char \
-I/usr/local/include \
-I/opt/local/include \

View File

@ -669,6 +669,7 @@
# define c3__met c3_s3('m','e','t')
# define c3__meta c3_s4('m','e','t','a')
# define c3__mill c3_s4('m','i','l','l')
# define c3__mime c3_s4('m','i','m','e')
# define c3__mine c3_s4('m','i','n','e')
# define c3__mint c3_s4('m','i','n','t')
# define c3__mirt c3_s4('m','i','r','t')
@ -1009,6 +1010,7 @@
# define c3__tank c3_s4('t','a','n','k')
# define c3__tap c3_s3('t','a','p')
# define c3__tarn c3_s4('t','a','r','n')
# define c3__tas c3_s3('t','a','s')
# define c3__tash c3_s4('t','a','s','h')
# define c3__teal c3_s4('t','e','a','l')
# define c3__teck c3_s4('t','e','c','k')

View File

@ -297,36 +297,39 @@
struct _u3_udir;
struct _u3_ufil;
/* u3_unod: file or directory.
/* u3_unod: in-file or in-directory.
*/
typedef struct _u3_unod {
uv_fs_event_t was_u; // stat watcher
c3_o dir; // always
c3_o dry; // ie, unmodified
c3_c* pax_c; // absolute path
struct _u3_udir* par_u; // in directory
c3_c* pax_c; // in absolute path
c3_c* pot_c; // out absolute path
struct _u3_udir* par_u; // directory
} u3_unod;
/* u3_ufil: synchronized file.
/* u3_ufil: synchronized in-file.
*/
typedef struct _u3_ufil {
uv_fs_event_t was_u; // stat watcher
c3_o non; // always u3_no
c3_o dry; // ie, unmodified
c3_c* pax_c; // absolute path
struct _u3_udir* par_u; // in directory
c3_c* pax_c; // in absolute path
c3_c* pot_c; // out absolute path
struct _u3_udir* par_u; // directory
c3_c* dot_c; // extension point or 0
c3_w mod_w[4]; // mtime
struct _u3_ufil* nex_u; // internal list
} u3_ufil;
/* u3_udir: synchronized directory.
/* u3_udir: synchronized in-directory.
*/
typedef struct _u3_udir {
uv_fs_event_t was_u; // stat watcher
c3_o yes; // always u3_yes
c3_o dry; // ie, unmodified
c3_c* pax_c; // absolute path
c3_c* pax_c; // in absolute path
c3_c* pot_c; // out absolute path
struct _u3_udir* par_u; // parent directory
struct _u3_udir* dis_u; // subdirectories
struct _u3_ufil* fil_u; // files
@ -336,7 +339,7 @@
/* u3_uhot: synchronized host.
*/
typedef struct _u3_uhot {
u3_udir dir_u; // root directory
u3_udir dir_u; // in directory
c3_w who_w[4]; // owner as words
struct _u3_uhot* nex_u; // internal list
} u3_uhot;
@ -929,7 +932,8 @@
void
u3_unix_ef_ergo(u3_noun who,
u3_noun syd,
u3_noun rel);
u3_noun rel,
u3_noun can);
/* u3_unix_io_init(): initialize storage.
*/

View File

@ -1,5 +1,7 @@
/* j/4/by_int.c
**
** XXX THIS IS DISABLED
** specifically, s/hor/gor/g (already done?)
** and eliminate memory leaks
*/
#include "all.h"
@ -47,7 +49,7 @@
u3qdb_int(u3k(l_a), u3k(l_b)),
u3qdb_int(u3k(r_a), u3k(r_b)));
}
else if ( c3y == u3qc_hor(p_n_b, p_n_a) ) {
else if ( c3y == u3qc_gor(p_n_b, p_n_a) ) {
return u3qdb_uni(
u3qdb_int(
@ -81,7 +83,7 @@
u3qdb_int(u3k(l_b), u3k(l_a)),
u3qdb_int(u3k(r_b), u3k(r_a)));
}
else if ( c3y == u3qc_hor(p_n_a, p_n_b) ) {
else if ( c3y == u3qc_gor(p_n_a, p_n_b) ) {
return u3qdb_uni(
u3qdb_int(

View File

@ -1,5 +1,7 @@
/* j/4/by_uni.c
**
** XXX THIS IS DISABLED
** specifically, s/hor/gor/g (already done?)
** and eliminate memory leaks
*/
#include "all.h"
@ -47,7 +49,7 @@
u3qdb_uni(
u3k(r_a), u3k(r_b)));
}
else if ( c3y == u3qc_hor(p_n_b, p_n_a) ) {
else if ( c3y == u3qc_gor(p_n_b, p_n_a) ) {
return u3qdb_uni(
u3nt(
@ -83,7 +85,7 @@
u3qdb_uni(u3k(r_b), u3k(r_a)),
u3qdb_uni(u3k(l_b), u3k(l_a)));
}
else if ( c3y == u3qc_hor(p_n_a, p_n_b) ) {
else if ( c3y == u3qc_gor(p_n_a, p_n_b) ) {
return u3qdb_uni(
u3k(r_a),

View File

@ -19,7 +19,7 @@
} else {
meg_w = 0;
c3_y byt_y;
c3_y byt_y;
while ( 1 ) {
byt_y = u3r_byte(pos_w + meg_w, lub);
@ -29,8 +29,8 @@
}
if ((byt_y == 0) && ((pos_w + meg_w + 1) < len_w)) {
return u3m_bail(c3__exit);
}
return u3m_bail(c3__exit);
}
{
c3_y* byts_y = alloca(meg_w);

View File

@ -724,7 +724,7 @@
u3nt(c3__tsls,
u3nt(c3__ktts, c3__a,
u3nt(c3__tsgr, u3nc(c3__cnzy, c3__v),
u3nc(c3__bccm, u3k(p_gen)))),
u3k(p_gen))),
u3nt(c3__tsls,
u3nt(c3__ktts, c3__b,
u3nt(c3__tsgr,

View File

@ -70,7 +70,7 @@ static u3j_core _mood__hoon__po_d[] =
static u3j_harm _mood__hoon__by_gas_a[] = {{".2", u3wdb_gas, c3y}, {}};
static u3j_harm _mood__hoon__by_get_a[] = {{".2", u3wdb_get, c3y}, {}};
static u3j_harm _mood__hoon__by_has_a[] = {{".2", u3wdb_has, c3y}, {}};
static u3j_harm _mood__hoon__by_int_a[] = {{".2", u3wdb_int, c3y}, {}};
// static u3j_harm _mood__hoon__by_int_a[] = {{".2", u3wdb_int, c3y}, {}};
static u3j_harm _mood__hoon__by_put_a[] = {{".2", u3wdb_put, c3y}, {}};
static u3j_harm _mood__hoon__by_tap_a[] = {{".2", u3wdb_tap, c3y}, {}};
// static u3j_harm _mood__hoon__by_uni_a[] = {{".2", u3wdb_uni, c3y}, {}};
@ -78,7 +78,7 @@ static u3j_core _mood__hoon__by_d[] =
{ { "gas", _mood__hoon__by_gas_a },
{ "get", _mood__hoon__by_get_a },
{ "has", _mood__hoon__by_has_a },
{ "int", _mood__hoon__by_int_a },
// { "int", _mood__hoon__by_int_a },
{ "put", _mood__hoon__by_put_a },
{ "tap", _mood__hoon__by_tap_a },
// { "uni", _mood__hoon__by_uni_a },
@ -88,7 +88,7 @@ static u3j_core _mood__hoon__by_d[] =
static u3j_harm _mood__hoon__in_gas_a[] = {{".2", u3wdi_gas}, {}};
static u3j_harm _mood__hoon__in_has_a[] = {{".2", u3wdi_has}, {}};
static u3j_harm _mood__hoon__in_mer_a[] = {{".2", u3wdi_mer}, {}};
static u3j_harm _mood__hoon__in_int_a[] = {{".2", u3wdi_int}, {}};
// static u3j_harm _mood__hoon__in_int_a[] = {{".2", u3wdi_int}, {}};
static u3j_harm _mood__hoon__in_put_a[] = {{".2", u3wdi_put}, {}};
static u3j_harm _mood__hoon__in_tap_a[] = {{".2", u3wdi_tap}, {}};
// static u3j_harm _mood__hoon__in_uni_a[] = {{".2", u3wdi_uni}, {}};
@ -96,7 +96,7 @@ static u3j_core _mood__hoon__in_d[] =
{ { "gas", _mood__hoon__in_gas_a },
{ "has", _mood__hoon__in_has_a },
{ "mer", _mood__hoon__in_mer_a },
{ "int", _mood__hoon__in_int_a },
// { "int", _mood__hoon__in_int_a },
{ "put", _mood__hoon__in_put_a },
{ "tap", _mood__hoon__in_tap_a },
// { "uni", _mood__hoon__in_uni_a },

14
n/a.c
View File

@ -543,10 +543,10 @@ u3a_malloc(size_t len_i)
c3_w* out_w = u3a_into(ptr_p + pad_w + 1);
#if 0
if ( u3a_botox(out_w) == (u3a_box*)(void *)0x202320b88) {
static int xuc_i;
if ( u3a_botox(out_w) == (u3a_box*)(void *)0x3bdd1c80) {
static int xuc_i = 0;
printf("xuc_i %d\r\n", xuc_i);
fprintf(stderr,"xuc_i %d\r\n", xuc_i);
// if ( 1 == xuc_i ) { abort(); }
xuc_i++;
}
@ -561,6 +561,9 @@ u3a_malloc(size_t len_i)
c3_w*
u3a_celloc(void)
{
#ifdef U3_MEMORY_DEBUG
return u3a_walloc(c3_wiseof(u3a_cell));
#else
u3p(u3a_fbox) cel_p;
if ( (u3R == &(u3H->rod_u)) || !(cel_p = u3R->all.cel_p) ) {
@ -574,6 +577,7 @@ u3a_celloc(void)
return u3a_boxto(box_u);
}
#endif
}
/* u3a_cfree(): free a cell.
@ -581,6 +585,9 @@ u3a_celloc(void)
void
u3a_cfree(c3_w* cel_w)
{
#ifdef U3_MEMORY_DEBUG
return u3a_wfree(cel_w);
#else
if ( u3R == &(u3H->rod_u) ) {
return u3a_wfree(cel_w);
}
@ -591,6 +598,7 @@ u3a_cfree(c3_w* cel_w)
u3to(u3a_fbox, fre_p)->nex_p = u3R->all.cel_p;
u3R->all.cel_p = fre_p;
}
#endif
}
/* u3a_realloc(): aligned realloc in bytes.

13
n/t.c
View File

@ -1,4 +1,4 @@
/* g/t.c
/* g/t.c -
**
** This file is in the public domain.
*/
@ -44,7 +44,7 @@ void
u3t_slog(u3_noun hod)
{
#ifdef GHETTO
static int old;
static int old;
static struct timeval b4, f2, d0;
c3_w ms_w;
@ -52,15 +52,18 @@ u3t_slog(u3_noun hod)
gettimeofday(&f2, 0);
timersub(&f2, &b4, &d0);
ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
if(ms_w > 10 || 1){
printf("%3d.%02dms ", ms_w, (d0.tv_usec % 1000) / 10);
if (ms_w > 10) {
printf("%6d.%02dms ", ms_w, (int) (d0.tv_usec % 1000) / 10);
gettimeofday(&b4, 0);
}
else {
printf(" ");
}
}
else gettimeofday(&b4, 0);
old = 1;
#endif
#endif
if ( c3y == u3du(hod) ) {
u3_noun pri = u3h(hod);

View File

@ -832,6 +832,7 @@ _http_request_to_noun(u3_hreq* req_u)
default: fprintf(stderr, "strange request\r\n"); return u3_none;
case u3_hmet_put: { med = c3__put; break; }
case u3_hmet_get: { med = c3__get; break; }
case u3_hmet_head: { med = c3__head; break; }
case u3_hmet_post: { med = c3__post; break; }
}
url = u3i_string(req_u->url_c);

View File

@ -461,6 +461,8 @@ u3_lo_shut(c3_o inn)
//
if ( c3y == inn ) {
u3_unix_ef_look();
u3_raft_work();
_lo_time();
}
// u3_lo_grab("lo_shut d", u3_none);

View File

@ -1582,8 +1582,8 @@ _raft_punk(u3_noun ovo)
ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
clr_w = ms_w > 1000 ? 1 : ms_w < 100 ? 2 : 3; // red, green, yellow
if(c3__belt != u3h(u3t(ovo)) || clr_w != 2){
uL(fprintf(uH, "\x1b[3%dm%%punk %s %d.%dms\x1b[0m\n",
clr_w, txt_c, ms_w, (d0.tv_usec % 1000) / 10));
uL(fprintf(uH, "\x1b[3%dm%%punk %s %4d.%02dms\x1b[0m\n",
clr_w, txt_c, ms_w, (int) (d0.tv_usec % 1000) / 10));
}
free(txt_c);
#endif

View File

@ -103,9 +103,12 @@ _reck_kick_term(u3_noun pox, c3_l tid_l, u3_noun fav)
u3A->own = u3nc(u3k(p_fav), u3A->own);
u3_unix_ef_init(u3k(p_fav));
uL(fprintf(uH, "kick: init: %d\n", p_fav));
u3z(pox); u3z(fav); return c3y;
u3_noun hox = u3dc("scot", 'p', u3k(p_fav));
c3_c* nam_c = u3r_string(hox);
uL(fprintf(uH, "kick: init: %s\n", nam_c));
free(nam_c); u3z(pox); u3z(hox); u3z(fav); return c3y;
} break;
}
c3_assert(!"not reached"); return 0;
@ -156,9 +159,10 @@ _reck_kick_sync(u3_noun pox, u3_noun fav)
case c3__ergo: {
u3_noun who = u3k(u3h(u3t(fav)));
u3_noun syd = u3k(u3h(u3t(u3t(fav))));
u3_noun rel = u3k(u3t(u3t(u3t(fav))));
u3_noun rel = u3k(u3h(u3t(u3t(u3t(fav)))));
u3_noun can = u3k(u3t(u3t(u3t(u3t(fav)))));
u3_unix_ef_ergo(who, syd, rel);
u3_unix_ef_ergo(who, syd, rel, can);
u3z(pox); u3z(fav); return c3y;
} break;
}

View File

@ -320,13 +320,28 @@ _sist_home()
// Copy zod files, if we're generating a carrier.
//
if ( u3_Host.ops_u.imp_c ) {
snprintf(ful_c, 2048, "cp -r %s/zod %s/%s",
snprintf(ful_c, 2048, "mkdir %s/%s",
u3_Host.dir_c, u3_Host.ops_u.imp_c+1);
printf("%s\r\n", ful_c);
if ( 0 != system(ful_c) ) {
uL(fprintf(uH, "could not %s\n", ful_c));
u3_lo_bail();
}
snprintf(ful_c, 2048, "cp -r %s/zod %s/%s/in",
U3_LIB, u3_Host.dir_c, u3_Host.ops_u.imp_c+1);
printf("%s\r\n", ful_c);
if ( 0 != system(ful_c) ) {
uL(fprintf(uH, "could not %s\n", ful_c));
u3_lo_bail();
}
// snprintf(ful_c, 2048, "cp -r %s/zod %s/%s/out",
// U3_LIB, u3_Host.dir_c, u3_Host.ops_u.imp_c+1);
// printf("%s\r\n", ful_c);
// if ( 0 != system(ful_c) ) {
// uL(fprintf(uH, "could not %s\n", ful_c));
// u3_lo_bail();
// }
}
#endif
}

426
v/unix.c
View File

@ -16,13 +16,14 @@
#include <termios.h>
#include <term.h>
#include <errno.h>
#include <libgen.h>
#include "all.h"
#include "v/vere.h"
/* _unix_ship_in(): c3_w[4] to ship.
*/
static u3_noun
static u3_noun
_unix_ship_in(c3_w* who_w)
{
return u3i_words(4, who_w);
@ -76,11 +77,47 @@ static void
_unix_mkdir(c3_c* pax_c)
{
if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno) {
uL(fprintf(uH, "%s: %s\n", pax_c, strerror(errno)));
uL(fprintf(uH, "error mkdiring %s: %s\n", pax_c, strerror(errno)));
c3_assert(0);
}
}
/* _unix_mkpath(): mkdir -p, asserting
*
* adapted from
* http://niallohiggins.com/2009/01/08/mkpath-mkdir-p-alike-in-c-for-unix/
*/
static void
_unix_mkpath(const char *s)
{
char *q, *r = NULL, *path = NULL, *up = NULL;
if (strcmp(s, ".") == 0 || strcmp(s, "/") == 0)
return;
if ((path = strdup(s)) == NULL)
c3_assert(0);
if ((q = strdup(s)) == NULL)
c3_assert(0);
if ((r = dirname(q)) == NULL)
goto out;
if ((up = strdup(r)) == NULL)
exit(1);
_unix_mkpath(up);
_unix_mkdir(path);
out:
if (up != NULL)
free(up);
free(q);
free(path);
}
/* _unix_opendir(): opendir, recreating if nonexistent.
*/
static DIR*
@ -105,8 +142,8 @@ _unix_opendir(c3_c* pax_c)
static void
_unix_unlink(c3_c* pax_c)
{
if ( 0 != unlink(pax_c) && ENOENT != errno) {
uL(fprintf(uH, "%s: %s\n", pax_c, strerror(errno)));
if ( 0 != unlink(pax_c) && ENOENT != errno ) {
uL(fprintf(uH, "error unlinking %s: %s\n", pax_c, strerror(errno)));
c3_assert(0);
}
}
@ -213,7 +250,6 @@ _unix_fs_event_cb(uv_fs_event_t* was_u,
c3_i evt_i,
c3_i sas_i)
{
// note that we're doing something tricky and weird here.
//
// * libuv passes around a pointer to a uv_fs_event_t
@ -249,6 +285,7 @@ static void
_unix_file_watch(u3_ufil* fil_u,
u3_udir* dir_u,
c3_c* pax_c,
c3_c* pot_c,
c3_w* mod_w)
{
// (1) build data structure
@ -256,6 +293,7 @@ _unix_file_watch(u3_ufil* fil_u,
fil_u->non = c3n;
fil_u->dry = c3n;
fil_u->pax_c = pax_c;
fil_u->pot_c = pot_c;
{
c3_c* dot_c = strrchr(pax_c, '.');
c3_c* fas_c = strrchr(pax_c, '/');
@ -275,7 +313,7 @@ _unix_file_watch(u3_ufil* fil_u,
// (2) stuff data structure into libuv
//
c3_w ret_w = uv_fs_event_init(u3L, // loop
&fil_u->was_u // uv_fs_event_t
&fil_u->was_u // uv_fs_event_t
);
if (0 != ret_w){
uL(fprintf(uH, "event init: %s\n", strerror(ret_w)));
@ -297,45 +335,46 @@ _unix_file_watch(u3_ufil* fil_u,
/* _unix_file_form(): form a filename path downward.
*/
static c3_c*
_unix_file_form(u3_udir* dir_u,
_unix_file_form(c3_c* pax_c,
u3_noun pre,
u3_noun ket,
u3_noun ext)
{
c3_c* pre_c = u3r_string(pre);
c3_c* ext_c = u3r_string(ext);
c3_w pax_w = strlen(dir_u->pax_c);
c3_w pax_w = strlen(pax_c);
c3_w pre_w = strlen(pre_c);
c3_w ext_w = strlen(ext_c);
c3_w ket_w = (c3y == ket) ? 1 : 0;
c3_c* pax_c = c3_malloc(pax_w + 1 + pre_w + 1 + ket_w + ext_w + 1);
c3_c* pox_c = c3_malloc(pax_w + 1 + pre_w + 1 + ket_w + ext_w + 1);
strncpy(pax_c, dir_u->pax_c, pax_w);
pax_c[pax_w] = '/';
strncpy(pax_c + pax_w + 1, pre_c, pre_w);
pax_c[pax_w + 1 + pre_w] = '.';
strncpy(pox_c, pax_c, pax_w);
pox_c[pax_w] = '/';
strncpy(pox_c + pax_w + 1, pre_c, pre_w);
pox_c[pax_w + 1 + pre_w] = '.';
if ( c3y == ket ) {
pax_c[pax_w + 1 + pre_w + 1] = '^';
pox_c[pax_w + 1 + pre_w + 1] = '^';
}
strncpy(pax_c + pax_w + 1 + pre_w + 1 + ket_w, ext_c, ext_w);
pax_c[pax_w + 1 + pre_w + 1 + ket_w + ext_w] = '\0';
strncpy(pox_c + pax_w + 1 + pre_w + 1 + ket_w, ext_c, ext_w);
pox_c[pax_w + 1 + pre_w + 1 + ket_w + ext_w] = '\0';
free(pre_c); free(ext_c);
u3z(pre); u3z(ext);
return pax_c;
return pox_c;
}
/* _unix_dir_watch(): instantiate directory tracker.
*/
static void
_unix_dir_watch(u3_udir* dir_u, u3_udir* par_u, c3_c* pax_c)
_unix_dir_watch(u3_udir* dir_u, u3_udir* par_u, c3_c* pax_c, c3_c* pot_c)
{
// (1) build data structure
//
dir_u->yes = c3y;
dir_u->dry = c3n;
dir_u->pax_c = pax_c;
dir_u->pot_c = pot_c;
dir_u->par_u = par_u;
dir_u->dis_u = 0;
dir_u->fil_u = 0;
@ -372,17 +411,24 @@ _unix_dir_forge(u3_udir* dir_u, u3_udir* par_u, u3_noun tet)
c3_w pax_w = strlen(par_u->pax_c);
c3_w tet_w = strlen(tet_c);
c3_c* pax_c = c3_malloc(pax_w + 1 + tet_w + 1);
c3_c* pot_c = c3_malloc(pax_w + 1 + 1 + tet_w + 1);
strncpy(pax_c, par_u->pax_c, pax_w + 1);
pax_c[pax_w] = '/';
strncpy(pax_c + pax_w + 1, tet_c, tet_w + 1);
pax_c[pax_w + tet_w + 1] = '\0';
strncpy(pot_c, par_u->pot_c, pax_w + 1 + 1);
pot_c[pax_w + 1] = '/';
strncpy(pot_c + pax_w + 1 + 1, tet_c, tet_w + 1);
pot_c[pax_w + 1 + tet_w + 1] = '\0';
free(tet_c);
u3z(tet);
_unix_mkdir(pax_c);
_unix_dir_watch(dir_u, par_u, pax_c);
_unix_mkdir(pot_c);
_unix_dir_watch(dir_u, par_u, pax_c, pot_c);
}
/* _unix_file_done(): finish freeing file.
@ -544,11 +590,13 @@ _unix_dir_update(u3_udir* dir_u, DIR* rid_u)
}
else {
c3_c* pax_c = _unix_down(dir_u->pax_c, out_u->d_name);
c3_c* pot_c = _unix_down(dir_u->pot_c, out_u->d_name);
struct stat buf_u;
// uL(fprintf(uH, " in %s\n", pax_c));
if ( 0 != stat(pax_c, &buf_u) ) {
free(pax_c);
free(pot_c);
continue;
}
else {
@ -559,12 +607,14 @@ _unix_dir_update(u3_udir* dir_u, DIR* rid_u)
if ( ( NULL == strrchr(out_u->d_name, '.')) ||
( '~' == out_u->d_name[strlen(out_u->d_name) - 1] )
) {
free(pax_c);
free(pot_c);
continue;
}
{
u3_noun mod = c3_stat_mtime(&buf_u);
u3r_words(0, 4, mod_w, mod);
u3z(mod);
}
@ -577,7 +627,7 @@ _unix_dir_update(u3_udir* dir_u, DIR* rid_u)
fil_u = c3_malloc(sizeof(u3_ufil));
// uL(fprintf(uH, "found file %s\n", pax_c));
_unix_file_watch(fil_u, dir_u, pax_c, mod_w);
_unix_file_watch(fil_u, dir_u, pax_c, pot_c, mod_w);
fil_u->nex_u = dir_u->fil_u;
dir_u->fil_u = fil_u;
@ -596,7 +646,7 @@ _unix_dir_update(u3_udir* dir_u, DIR* rid_u)
dis_u = c3_malloc(sizeof(u3_udir));
// uL(fprintf(uH, "found directory %s\n", pax_c));
_unix_dir_watch(dis_u, dir_u, pax_c);
_unix_dir_watch(dis_u, dir_u, pax_c, pot_c);
_unix_dir_update(dis_u, red_u);
dis_u->nex_u = dir_u->dis_u;
@ -605,6 +655,7 @@ _unix_dir_update(u3_udir* dir_u, DIR* rid_u)
closedir(red_u);
} else {
free(pax_c);
free(pot_c);
}
}
}
@ -613,25 +664,30 @@ _unix_dir_update(u3_udir* dir_u, DIR* rid_u)
}
}
/* unix_load(): load a file.
/* unix_load(): load a file as a cage
*
* return value of c3__none means delete, u3_nul means no change
*/
static u3_noun
_unix_load(c3_c* pax_c)
_unix_load(u3_ufil* fil_u)
{
struct stat buf_u;
c3_i fid_i = open(pax_c, O_RDONLY, 0644);
c3_i fid_i = open(fil_u->pax_c, O_RDONLY, 0644);
c3_w fln_w, red_w;
c3_y* pad_y;
c3_i fit_i = open(fil_u->pot_c, O_RDONLY, 0644);
c3_w flt_w, ret_w;
c3_y* pat_y;
if ( (fid_i < 0) || (fstat(fid_i, &buf_u) < 0) ) {
// ignore if the file disappeared between getting the sync event and now
if ( ENOENT != errno ) {
uL(fprintf(uH, "%s: %s\n", pax_c, strerror(errno)));
uL(fprintf(uH, "error loading %s: %s\n", fil_u->pax_c, strerror(errno)));
}
return 0;
return c3__none;
}
fln_w = buf_u.st_size;
pad_y = c3_malloc(buf_u.st_size);
pad_y = c3_malloc(fln_w);
red_w = read(fid_i, pad_y, fln_w);
close(fid_i);
@ -642,10 +698,46 @@ _unix_load(c3_c* pax_c)
return 0;
}
else {
u3_noun pad = u3i_bytes(fln_w, (c3_y *)pad_y);
if ( !(fit_i < 0 || fstat(fit_i, &buf_u) < 0) ) {
flt_w = buf_u.st_size;
pat_y = c3_malloc(flt_w);
ret_w = read(fit_i, pat_y, flt_w);
close(fit_i);
if ( flt_w != ret_w ) {
free(pad_y);
c3_assert(0);
return 0;
}
if ( fln_w == flt_w && 0 == memcmp(pad_y, pat_y, fln_w) ) {
free(pad_y);
free(pat_y);
return u3_nul;
}
free(pat_y);
}
// -:!>(*[[@tas @tas ~] @ud @])
u3_noun typ = u3nt(c3__cell,
u3nt(c3__cell,
u3nc(c3__atom, c3__tas),
u3nt(c3__cell,
u3nc(c3__atom, c3__tas),
u3nt(c3__cube,
u3_nul,
u3nc(c3__atom, 'n')))),
u3nt(c3__cell,
u3nc(c3__atom, c3__ud),
u3nc(c3__atom, u3_nul)));
u3_noun nam = u3nt(c3__text, u3i_string("plain"), u3_nul);
u3_noun pad = u3nt(nam, fln_w, u3i_bytes(fln_w, (c3_y *)pad_y));
u3_noun cay = u3nt(c3__mime, typ, pad);
free(pad_y);
return pad;
return cay;
}
}
@ -654,23 +746,30 @@ _unix_load(c3_c* pax_c)
static void
_unix_save(c3_c* pax_c, u3_atom oat)
{
c3_c* dir = strdup(pax_c);
_unix_mkpath(dirname(dir));
free(dir);
c3_i fid_i = open(pax_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
c3_w fln_w, rit_w;
c3_w fln_w, rit_w, siz_w;
c3_y* oat_y;
if ( fid_i < 0 ) {
uL(fprintf(uH, "%s: %s\n", pax_c, strerror(errno)));
uL(fprintf(uH, "error opening %s: %s\n", pax_c, strerror(errno)));
u3m_bail(c3__fail);
}
fln_w = u3r_met(3, oat);
oat_y = c3_malloc(fln_w);
u3r_bytes(0, fln_w, oat_y, oat);
siz_w = u3h(u3t(oat));
fln_w = u3r_met(3, u3t(u3t(oat)));
oat_y = c3_malloc(siz_w);
memset(oat_y, 0, siz_w);
u3r_bytes(0, fln_w, oat_y, u3t(u3t(oat)));
u3z(oat);
rit_w = write(fid_i, oat_y, fln_w);
if ( rit_w != fln_w ) {
uL(fprintf(uH, "%s: %s\n", pax_c, strerror(errno)));
rit_w = write(fid_i, oat_y, siz_w);
if ( rit_w != siz_w ) {
uL(fprintf(uH, "error writing %s: %s\n", pax_c, strerror(errno)));
c3_assert(0);
}
@ -683,15 +782,9 @@ _unix_save(c3_c* pax_c, u3_atom oat)
static u3_noun
_unix_file_load(u3_ufil* fil_u)
{
u3_noun raw = _unix_load(fil_u->pax_c);
if ( (0 == raw) || ('^' != fil_u->dot_c[1]) ) {
return raw;
}
else return u3ke_cue(raw);
return _unix_load(fil_u);
}
/* _unix_dir_name(): directory name.
*/
static u3_noun
@ -745,21 +838,21 @@ _unix_file_name(u3_ufil* fil_u)
}
}
/* _unix_dir_ankh_file(): process a file for ankh.
/* _unix_dir_khan_file(): process a file for khan.
*/
static u3_noun
_unix_dir_ankh_file(u3_noun pam, u3_noun wib, u3_noun baw, u3_noun woz)
_unix_dir_khan_file(u3_noun pam, u3_noun wib, u3_noun woz)
{
u3_weak ole;
if ( c3n == u3du(wib) ) {
ole = u3kdb_get(u3k(pam), u3k(wib));
if ( u3_none == ole ) {
ole = u3do("cosh", u3nt(0, woz, u3_nul));
ole = u3nc(woz, u3_nul);
} else {
u3_noun elo;
elo = u3do("cosh", u3nt(0, woz, u3k(u3t(u3t(ole)))));
elo = u3nc(woz, u3k(u3t(ole)));
u3z(ole);
ole = elo;
@ -773,29 +866,28 @@ _unix_dir_ankh_file(u3_noun pam, u3_noun wib, u3_noun baw, u3_noun woz)
ole = u3kdb_get(u3k(pam), u3k(fid));
if ( u3_none == ole ) {
ole = u3nt
(0, u3_nul, u3kdb_put(u3_nul,
u3k(har),
u3do("cosh", u3nt(0, woz, u3_nul))));
ole = u3do("cosh", ole);
ole = u3nc(u3_nul,
u3kdb_put(u3_nul,
u3k(har),
u3nc(woz, u3_nul)));
}
else {
u3_noun roo = u3t(u3t(ole));
u3_noun roo = u3t(ole);
u3_weak tup = u3kdb_get(u3k(roo), u3k(har));
u3_noun oor, elo;
if ( u3_none == tup ) {
tup = u3do("cosh", u3nt(0, woz, u3_nul));
tup = u3nc(woz, u3_nul);
} else {
u3_noun upt;
upt = u3do("cosh", u3nt(0, woz, u3k(u3t(u3t(tup)))));
upt = u3nc(woz, u3k(u3t(tup)));
u3z(tup);
tup = upt;
}
oor = u3kdb_put(u3k(roo), u3k(har), tup);
elo = u3do("cosh", u3nt(0, u3k(u3h(u3t(ole))), oor));
elo = u3nc(u3k(u3h(ole)), oor);
u3z(ole); ole = elo;
}
@ -805,10 +897,10 @@ _unix_dir_ankh_file(u3_noun pam, u3_noun wib, u3_noun baw, u3_noun woz)
return pam;
}
/* _unix_dir_ankh(): resolve directory to new style ankh.
/* _unix_dir_khan(): resolve directory to khan.
*/
static u3_noun
_unix_dir_ankh(u3_udir* dir_u)
_unix_dir_khan(u3_udir* dir_u)
{
u3_udir* dis_u;
u3_ufil* fil_u;
@ -816,15 +908,14 @@ _unix_dir_ankh(u3_udir* dir_u)
for ( dis_u = dir_u->dis_u; dis_u; dis_u = dis_u->nex_u ) {
u3_noun pre = _unix_dir_name(dis_u);
u3_noun ank = _unix_dir_ankh(dis_u);
u3_noun kan = _unix_dir_khan(dis_u);
// uL(fprintf(uH, "dir %s\n", u3r_string(pre)));
if ( 0 != u3h(ank) ) {
pam = u3kdb_put(pam, pre, ank);
if ( u3_nul != u3h(kan) || u3_nul != u3t(kan) ) {
pam = u3kdb_put(pam, pre, kan);
}
else
{
u3z(ank);
else {
u3z(kan); u3z(pre);
}
}
@ -835,13 +926,12 @@ _unix_dir_ankh(u3_udir* dir_u)
if ( u3_none == wib ) continue;
u3_noun dur = _unix_dir_name(dir_u);
if ( c3n == u3r_sing(dur, u3h(wib)) ) { // wrong desk
u3z(wib); u3z(dur);
u3z(dur); u3z(wib);
continue;
}
u3_noun baw = _unix_file_load(fil_u);
u3_noun woz = u3nt(u3_nul, u3do("sham", u3k(baw)), baw);
u3_noun woz = u3nt(u3_nul, u3_nul, _unix_file_load(fil_u));
pam = _unix_dir_khan_file(pam, u3k(u3t(wib)), woz);
u3z(dur);
pam = _unix_dir_ankh_file(pam, u3k(u3t(wib)), baw, woz);
u3z(wib);
}
}
@ -849,10 +939,12 @@ _unix_dir_ankh(u3_udir* dir_u)
for ( fil_u = dir_u->fil_u; fil_u; fil_u = fil_u->nex_u ) {
u3_noun wib = _unix_file_name(fil_u);
u3_noun baw = _unix_file_load(fil_u);
u3_noun woz = u3nt(u3_nul, u3do("sham", u3k(baw)), baw);
pam = _unix_dir_ankh_file(pam, wib, baw, woz);
u3_noun wol = (c3__none == baw ? u3nc(u3_nul, u3_nul) :
u3_nul == baw ? u3_nul :
u3nt(u3_nul, u3_nul, baw));
pam = _unix_dir_khan_file(pam, wib, wol);
}
return u3do("cosh", u3nt(0, u3_nul, pam));
return u3nc(u3_nul, pam);
}
/* _find_mug(): find a noun with a given mug. retain. DELETEME
@ -878,6 +970,7 @@ _find_mug(u3_noun som, c3_l mug_l)
}
#endif
#if 0
/* _unix_desk_peek(): peek for ankh.
*/
static u3_noun
@ -900,6 +993,7 @@ _unix_desk_peek(u3_noun hox,
u3z(cay); return ank;
}
}
#endif
#if 0
/* _unix_ankh_sing_map(): compare ankh maps for u3_ankh_sing().
@ -983,23 +1077,16 @@ _unix_desk_sync_into(u3_noun who,
u3_noun syd,
u3_udir* dir_u)
{
u3_noun xun, bur, doz, fav, pax;
u3_noun xun, fav, pax;
xun = _unix_dir_ankh(dir_u);
bur = _unix_desk_peek(hox, u3k(syd), u3k(u3A->wen));
xun = _unix_dir_khan(dir_u);
if ( (c3n == u3r_sing(u3h(xun), u3h(bur))))
{
doz = u3dc("cost", xun, bur);
pax = u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul);
fav = u3nq(c3__into, who, syd, xun);
pax = u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul);
fav = u3nq(c3__into, who, syd, u3nc(c3y, doz));
u3v_plan(pax, fav);
u3v_plan(pax, fav);
}
else {
u3z(who); u3z(syd); u3z(xun); u3z(bur);
}
u3z(hox);
}
/* _unix_ship_update(): update top level ship.
@ -1031,6 +1118,9 @@ _unix_ship_update(u3_uhot* hot_u)
}
/* _unix_hot_gain(): gain ship.
*
* I feel like there's some freeing here I missed
* particularly pin_c and/or pot_c
*/
static void
_unix_hot_gain(u3_noun who, u3_noun mek)
@ -1038,8 +1128,22 @@ _unix_hot_gain(u3_noun who, u3_noun mek)
u3_noun hox = u3dc("scot", 'p', u3k(who));
c3_c* hox_c = u3r_string(hox);
c3_c* pax_c = _unix_down(u3_Host.dir_c, hox_c + 1);
c3_c* pin_c = _unix_down(pax_c, "in");
c3_c* pot_c = _unix_down(pax_c, "out");
// DIR* rox_u = opendir(hox_c);
DIR* rid_u = opendir(pax_c);
DIR* rin_u = opendir(pin_c);
DIR* rot_u = opendir(pot_c);
// if ( !rox_u ) {
// if ( c3y == mek ) {
// _unix_mkdir(hox_c);
// } else {
// u3z(who);
// u3z(hox);
// return;
// }
// } else closedir(rox_u);
if ( !rid_u ) {
if ( c3y == mek ) {
_unix_mkdir(pax_c);
@ -1049,17 +1153,37 @@ _unix_hot_gain(u3_noun who, u3_noun mek)
return;
}
} else closedir(rid_u);
if ( !rin_u ) {
if ( c3y == mek ) {
_unix_mkdir(pin_c);
} else {
u3z(who);
u3z(hox);
return;
}
} else closedir(rin_u);
if ( !rot_u ) {
if ( c3y == mek ) {
_unix_mkdir(pot_c);
} else {
u3z(who);
u3z(hox);
return;
}
} else closedir(rot_u);
// uL(fprintf(uH, "GAIN %s\n", pax_c));
free(pax_c);
free(hox_c);
u3z(hox);
u3_unix_acquire(pax_c);
u3_unix_acquire(pin_c);
{
u3_uhot* hot_u = c3_malloc(sizeof(u3_uhot));
_unix_dir_watch(&hot_u->dir_u, 0, pax_c);
_unix_dir_watch(&hot_u->dir_u, 0, pin_c, pot_c);
_unix_ship_out(who, hot_u->who_w);
u3z(who);
@ -1086,6 +1210,8 @@ _unix_pdir(u3_udir* par_u, u3_noun tet)
c3_w pax_w = strlen(par_u->pax_c);
u3_udir** dir_u;
u3z(tet);
dir_u = &(par_u->dis_u);
while ( 1 ) {
if ( !*dir_u || !strcmp(((*dir_u)->pax_c + pax_w + 1), tet_c) ) {
@ -1114,6 +1240,7 @@ _unix_home(u3_noun who)
return hot_u;
}
#if 0
/* _unix_desk_sync_udon(): apply udon to existing value.
*/
static u3_noun
@ -1121,6 +1248,7 @@ _unix_desk_sync_udon(u3_noun don, u3_noun old)
{
return u3dc("lump", don, old);
}
#endif
/* _unix_desk_sync_tofu(): sync out file install.
*/
@ -1128,10 +1256,12 @@ static void
_unix_desk_sync_tofu(u3_udir* dir_u,
u3_noun pre,
u3_noun ext,
u3_noun mis)
u3_noun mim)
{
c3_c* pox_c = _unix_file_form(dir_u, u3k(pre), c3n, u3k(ext));
c3_c* pux_c = _unix_file_form(dir_u, u3k(pre), c3y, u3k(ext));
c3_c* pox_c = _unix_file_form(dir_u->pax_c, u3k(pre), c3n, u3k(ext));
c3_c* pot_c = _unix_file_form(dir_u->pot_c, u3k(pre), c3n, u3k(ext));
c3_c* pux_c = _unix_file_form(dir_u->pax_c, u3k(pre), c3y, u3k(ext));
c3_c* put_c = _unix_file_form(dir_u->pot_c, u3k(pre), c3y, u3k(ext));
u3_ufil** fil_u;
// uL(fprintf(uH, "tofu pox_c %s op %s\n", pox_c, u3r_string(u3h(mis))));
@ -1145,15 +1275,16 @@ _unix_desk_sync_tofu(u3_udir* dir_u,
fil_u = &(dir_u->fil_u);
while ( 1 ) { // XX crude!
if ( !*fil_u ||
!strcmp((*fil_u)->pax_c, pox_c) ||
!strcmp((*fil_u)->pax_c, pux_c) )
!strcmp((*fil_u)->pax_c, pox_c) /* ||
!strcmp((*fil_u)->pax_c, pux_c) */ )
{
break;
}
else fil_u = &((*fil_u)->nex_u);
}
if ( *fil_u && (c3__del == u3h(mis)) ) {
if ( *fil_u && u3_nul == mim ) {
uL(fprintf(uH, "file goning: %s\n", pox_c));
u3_ufil* ded_u = *fil_u;
#ifdef SYNCLOG
@ -1165,35 +1296,45 @@ _unix_desk_sync_tofu(u3_udir* dir_u,
*fil_u = ded_u->nex_u;
_unix_unlink(ded_u->pax_c);
_unix_unlink(ded_u->pot_c);
_unix_file_free(ded_u);
free(ded_u->pot_c);
free(pox_c);
free(pot_c);
free(pux_c);
free(put_c);
}
else if (u3_nul == mim) {
uL(fprintf(uH, "file already gone: %s\n", pox_c)); // fires too often
free(pox_c);
free(pot_c);
free(pux_c);
free(put_c);
}
else {
u3_noun god, oat;
c3_c* pax_c;
c3_c* pat_c;
if ( *fil_u ) {
u3_noun old = _unix_file_load(*fil_u);
c3_assert(c3__mut == u3h(mis));
god = _unix_desk_sync_udon(u3k(u3t(mis)), old);
_unix_unlink((*fil_u)->pax_c);
free((*fil_u)->pax_c);
}
else {
c3_assert(c3__ins == u3h(mis));
god = u3k(u3t(mis));
_unix_unlink((*fil_u)->pot_c);
free((*fil_u)->pot_c);
}
#if 0
if ( c3y == u3du(god) ) {
oat = u3ke_jam(god);
pax_c = pux_c; free(pox_c);
pat_c = put_c; free(pot_c);
} else {
oat = god;
#endif
pax_c = pox_c; free(pux_c);
pat_c = pot_c; free(put_c);
#if 0
}
#endif
#ifdef SYNCLOG
u3_Host.unx_u.sylo[slot].unx = c3n;
@ -1202,11 +1343,13 @@ _unix_desk_sync_tofu(u3_udir* dir_u,
u3_Host.unx_u.sylo[slot].pax_c = strdup(pax_c);
#endif
_unix_save(pax_c, oat);
_unix_save(pax_c, u3k(u3t(mim)));
_unix_save(pat_c, u3k(u3t(mim)));
if ( *fil_u ) {
(*fil_u)->dot_c = (pax_c + ((*fil_u)->dot_c - (*fil_u)->pax_c));
(*fil_u)->pax_c = pax_c;
(*fil_u)->pot_c = pat_c;
u3r_words(0, 4, (*fil_u)->mod_w, u3A->now);
}
@ -1216,28 +1359,29 @@ _unix_desk_sync_tofu(u3_udir* dir_u,
u3r_words(0, 4, mod_w, u3A->now);
*fil_u = c3_malloc(sizeof(u3_ufil));
_unix_file_watch(*fil_u, dir_u, pax_c, mod_w);
_unix_file_watch(*fil_u, dir_u, pax_c, pat_c, mod_w);
}
}
u3z(pre); u3z(ext); u3z(mis);
u3z(pre); u3z(ext); u3z(mim);
}
/* _unix_desk_sync_tako(): sync out change.
*/
static void
_unix_desk_sync_tako(u3_udir* dir_u, u3_noun pax, u3_noun mis)
_unix_desk_sync_tako(u3_udir* dir_u, u3_noun pax, u3_noun mim)
{
if ( (c3n == u3du(pax)) ) {
c3_assert(!"tack");
}
else if ( c3n == u3du(u3t(pax)) ) { // at toplevel
else if ( c3n == u3du(u3t(pax)) ) { // at toplevel
u3_noun i_pax = u3h(pax);
u3_noun t_pax = u3t(pax);
c3_c* par_u = strrchr(dir_u->pax_c, '/') + 1;
u3_noun pem = u3i_string(par_u);
c3_assert( u3_nul == t_pax ); // XX ugly, wrong
c3_assert( u3_nul == t_pax ); // XX ugly, wrong
_unix_desk_sync_tofu(dir_u->par_u, pem, u3k(i_pax), mis);
_unix_desk_sync_tofu(dir_u->par_u, pem, u3k(i_pax), mim);
}
else {
u3_noun i_pax = u3h(pax);
@ -1246,7 +1390,7 @@ _unix_desk_sync_tako(u3_udir* dir_u, u3_noun pax, u3_noun mis)
u3_noun tt_pax = u3t(t_pax);
if ( u3_nul == tt_pax ) {
_unix_desk_sync_tofu(dir_u, u3k(i_pax), u3k(it_pax), mis);
_unix_desk_sync_tofu(dir_u, u3k(i_pax), u3k(it_pax), mim);
}
else {
u3_udir** dis_u = _unix_pdir(dir_u, u3k(i_pax));
@ -1256,24 +1400,25 @@ _unix_desk_sync_tako(u3_udir* dir_u, u3_noun pax, u3_noun mis)
_unix_dir_forge(*dis_u, dir_u, u3k(i_pax));
}
_unix_desk_sync_tako(*dis_u, u3k(t_pax), mis);
_unix_desk_sync_tako(*dis_u, u3k(t_pax), mim);
}
}
u3z(pax);
}
/* _unix_desk_sync_soba(): sync computed changes.
/* _unix_desk_sync_list(): sync computed changes.
*/
static void
_unix_desk_sync_soba(u3_udir* dir_u, u3_noun doz)
_unix_desk_sync_list(u3_udir* dir_u, u3_noun can)
{
u3_noun zod = u3t(doz);
u3_noun nac = can;
while ( u3_nul != zod ) {
_unix_desk_sync_tako(dir_u, u3k(u3h(u3h(zod))), u3k(u3t(u3h(zod))));
zod = u3t(zod);
while ( u3_nul != nac ) {
_unix_desk_sync_tako(dir_u, u3k(u3h(u3h(nac))), u3k(u3t(u3h(nac))));
nac = u3t(nac);
}
u3z(doz);
u3z(can);
}
/* _unix_desk_sync_ergo(): sync desk changes to unix.
@ -1282,10 +1427,14 @@ static void
_unix_desk_sync_ergo(u3_noun hox,
u3_noun syd,
u3_noun lok,
u3_noun can,
u3_uhot* hot_u)
{
#if 0
u3z(hox); u3z(syd); u3z(lok); u3z(can);
#else
u3_udir** dir_u = _unix_pdir(&(hot_u->dir_u), syd);
u3_noun xun;
#if 0
uL(fprintf(uH, "ergo %s %s %s\n", u3r_string(hox),
@ -1296,24 +1445,13 @@ _unix_desk_sync_ergo(u3_noun hox,
if ( !*dir_u ) {
*dir_u = c3_malloc(sizeof(u3_udir));
xun = u3nt(0, u3_nul, u3_nul);
_unix_dir_forge(*dir_u, &(hot_u->dir_u), u3k(syd));
} else {
xun = _unix_dir_ankh(*dir_u);
}
{
u3_noun bur = _unix_desk_peek(hox, syd, lok);
_unix_desk_sync_list(*dir_u, can);
u3z(lok); u3z(syd); u3z(hox);
if ( c3n == u3r_sing(xun, bur) ) {
u3_noun doz = u3dc("cost", bur, xun);
_unix_desk_sync_soba(*dir_u, doz);
}
else {
u3z(xun); u3z(bur);
}
}
#endif
}
/* u3_unix_ef_init(): update filesystem for new acquisition.
@ -1326,7 +1464,7 @@ u3_unix_ef_init(u3_noun who)
u3v_plan(u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul),
u3nq(c3__into, who,
u3_blip,
u3nt(c3y, u3nc(0, 0), u3_nul)));
u3nc(u3_nul, u3_nul)));
}
/* u3_unix_ef_ergo(): update filesystem, outbound.
@ -1334,16 +1472,22 @@ u3_unix_ef_init(u3_noun who)
void
u3_unix_ef_ergo(u3_noun who,
u3_noun syd,
u3_noun rel)
u3_noun rel,
u3_noun can)
{
u3_noun hox = u3dc("scot", 'p', u3k(who));
u3_noun lok = u3dc("scot", c3__ud, rel);
u3_noun hox = u3dc("scot", 'p', u3k(who)); // XXX unnecessary?
u3_noun lok = u3dc("scot", c3__ud, rel); // XXX unnecessary?
u3_uhot* hot_u;
hot_u = _unix_home(who);
u3z(who);
if ( 0 != hot_u ) {
_unix_desk_sync_ergo(hox, syd, lok, hot_u);
_unix_desk_sync_ergo(hox, syd, lok, can, hot_u);
}
else
{
u3z(syd); u3z(syd); u3z(rel); u3z(can);
}
}