Beispiel #1
0
/* _unix_hot_gain(): gain ship.
*/
static void
_unix_hot_gain(u2_noun who, u2_bean mek)
{
  u2_noun hox = u2_dc("scot", 'p', who);
  c3_c*   hox_c = u2_cr_string(hox);
  c3_c*   pax_c = _unix_down(u2_Host.ops_u.hom_c, hox_c + 1);
  DIR*    rid_u = opendir(pax_c);

  if ( !rid_u ) {
    if ( u2_yes == mek ) {
      _unix_mkdir(pax_c);
    } else return;
  } else closedir(rid_u);

  // uL(fprintf(uH, "GAIN %s\n", pax_c));
  free(hox_c);
  u2z(hox);
  u2_unix_acquire(pax_c);

  {
    u2_uhot* hot_u = malloc(sizeof(u2_uhot));

    _unix_dir_watch(&hot_u->dir_u, 0, pax_c);

    u2_cr_mp(hot_u->who_mp, who);
    hot_u->nex_u = u2_Host.unx_u.hot_u;
    u2_Host.unx_u.hot_u = hot_u;
  }
}
Beispiel #2
0
/* _unix_home(): find home directory from identity.
*/
static u2_uhot*
_unix_home(u2_noun who)
{
  u2_unix* unx_u = &u2_Host.unx_u;
  u2_uhot* hot_u;
  mpz_t    who_mp;

  u2_cr_mp(who_mp, who);
  for ( hot_u = unx_u->hot_u; 
        hot_u && (0 != mpz_cmp(who_mp, hot_u->who_mp));
        hot_u = hot_u->nex_u ) 
  {
    // uL(fprintf(uH, "uh: %p, %s\n", hot_u, hot_u->dir_u.pax_c));
  }
  mpz_clear(who_mp);
  return hot_u;
}
Beispiel #3
0
/* _unix_desk_sync_tofu(): sync out file install.
*/
static void
_unix_desk_sync_tofu(u2_udir* dir_u,
                     u2_noun  pre,
                     u2_noun  ext,
                     u2_noun  mis)
{
  c3_c*     pox_c = _unix_file_form(dir_u, u2k(pre), u2_no, u2k(ext));
  c3_c*     pux_c = _unix_file_form(dir_u, u2k(pre), u2_yes, u2k(ext));
  u2_ufil** fil_u;

  // uL(fprintf(uH, "tofu pox_c %s op %s\n", pox_c, u2_cr_string(u2h(mis))));

  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) )
    {
      break;
    }
    else fil_u = &((*fil_u)->nex_u);
  }
 
  if ( *fil_u && (c3__del == u2h(mis)) ) {
    u2_ufil* ded_u = *fil_u;

    *fil_u = ded_u->nex_u;
    _unix_unlink(ded_u->pax_c);
    _unix_file_free(ded_u);

    free(ded_u);
    free(pox_c);
    free(pux_c);
  }
  else {
    u2_noun god, oat;
    c3_c*   pax_c;

    if ( *fil_u ) {
      u2_noun old = _unix_file_load(*fil_u);
      c3_assert(c3__mut == u2h(mis));

      god = _unix_desk_sync_udon(u2k(u2t(mis)), old);
      _unix_unlink((*fil_u)->pax_c);
      free((*fil_u)->pax_c);
    } 
    else {
      c3_assert(c3__ins == u2h(mis));
      god = u2k(u2t(mis));
    }

    if ( u2_yes == u2du(god) ) {
      oat = u2_cke_jam(god);
      pax_c = pux_c; free(pox_c);
    } else {
      oat = god;
      pax_c = pox_c; free(pux_c);
    }

    if ( *fil_u ) {
      (*fil_u)->dot_c = (pax_c + ((*fil_u)->dot_c - (*fil_u)->pax_c));
      (*fil_u)->pax_c = pax_c;

      mpz_clear((*fil_u)->mod_mp);
      u2_cr_mp((*fil_u)->mod_mp, u2A->now);
    } 
    else {
      mpz_t mod_mp;

      u2_cr_mp(mod_mp, u2A->now);
      *fil_u = malloc(sizeof(u2_ufil));

      _unix_file_watch(*fil_u, dir_u, pax_c, mod_mp);
      mpz_clear(mod_mp);
    }

    _unix_save((*fil_u)->pax_c, oat);
  }
  u2z(pre); u2z(ext); u2z(mis);
}
Beispiel #4
0
/* _unix_dir_update(): update directory, true if changed.
*/
static u2_bean
_unix_dir_update(u2_udir* dir_u, DIR* rid_u)
{
  u2_bean cha = u2_no;

  // uL(fprintf(uH, "dir_update ON %s\n", dir_u->pax_c));
  /* use dry bits as markers
  */
  {
    u2_udir* dis_u;
    u2_ufil* fil_u;

    for ( dis_u = dir_u->dis_u; dis_u; dis_u = dis_u->nex_u ) {
      dis_u->dry = u2_yes;
    }
    for ( fil_u = dir_u->fil_u; fil_u; fil_u = fil_u->nex_u ) {
      fil_u->dry = u2_yes;
    }
  }

  /* iterate through directory, opening and updating
  */
  while ( 1 ) {
    struct dirent  ent_u;
    struct dirent* out_u;

    if ( readdir_r(rid_u, &ent_u, &out_u) != 0 ) {
      uL(fprintf(uH, "%s: %s\n", dir_u->pax_c, strerror(errno)));
      c3_assert(0);
    } 
    else if ( !out_u ) {
      break;
    }
    else if ( ('.' == out_u->d_name[0]) ) {    //  XX screws up some paths
      continue;
    }
    else {
      c3_c* pax_c = _unix_down(dir_u->pax_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);
        continue;
      } 
      else {
        if ( !S_ISDIR(buf_u.st_mode) ) {
          mpz_t    mod_mp;
          u2_ufil* fil_u;

          {
            u2_noun mod = c3_stat_mtime(&buf_u);

            u2_cr_mp(mod_mp, mod);
            u2z(mod);
          }
          for ( fil_u = dir_u->fil_u; fil_u; fil_u = fil_u->nex_u ) {
            if ( !strcmp(pax_c, fil_u->pax_c) ) {
              fil_u->dry = u2_no;
              cha = u2_or(cha, _unix_file_update(fil_u, mod_mp));
              break;
            }
          }
          if ( !fil_u ) {
            fil_u = malloc(sizeof(u2_ufil));
            // uL(fprintf(uH, "found file %s\n", pax_c));
            _unix_file_watch(fil_u, dir_u, pax_c, mod_mp);

            fil_u->nex_u = dir_u->fil_u;
            dir_u->fil_u = fil_u;
            cha = u2_yes;
          }
          mpz_clear(mod_mp);
        }
        else {
          DIR* red_u = _unix_opendir(pax_c);
          u2_udir* dis_u;

          for ( dis_u = dir_u->dis_u; dis_u; dis_u = dis_u->nex_u ) {
            if ( !strcmp(pax_c, dis_u->pax_c) ) {
              dis_u->dry = u2_no;
              cha = u2_or(cha, _unix_dir_update(dis_u, red_u));
              break;
            }
          }
          if ( !dis_u ) {
            dis_u = malloc(sizeof(u2_udir));
            // uL(fprintf(uH, "found directory %s\n", pax_c));
            _unix_dir_watch(dis_u, dir_u, pax_c); 
            _unix_dir_update(dis_u, red_u);

            dis_u->nex_u = dir_u->dis_u;
            dir_u->dis_u = dis_u;
            cha = u2_yes;
          }
        }
      }
    }
  }

  /* use dry bits as markers
  */
  {
    u2_udir** dis_u;
    u2_ufil** fil_u;

    for ( dis_u = &(dir_u->dis_u); *dis_u; ) {
      if ( u2_no == (*dis_u)->dry ) {
        (*dis_u)->dry = u2_yes;
        dis_u = &(*dis_u)->nex_u;
      }
      else {
        u2_udir* ded_u = *dis_u;
        u2_udir* nex_u = ded_u->nex_u;

        // uL(fprintf(uH, "removed directory %s\n", ded_u->pax_c));
        _unix_dir_free(ded_u);
        free(ded_u);

        *dis_u = nex_u;
        cha = u2_yes;
      }
    }

    for ( fil_u = &(dir_u->fil_u); *fil_u; ) {
      if ( u2_no == (*fil_u)->dry ) {
        fil_u = &(*fil_u)->nex_u;
      }
      else {
        u2_ufil* ded_u = *fil_u;
        u2_ufil* nex_u = ded_u->nex_u;

        // uL(fprintf(uH, "removed file %s\n", ded_u->pax_c));
        _unix_file_free(ded_u);
        free(ded_u);

        *fil_u = nex_u;
        cha = u2_yes;
      }
    }
  }
  closedir(rid_u);
  // uL(fprintf(uH, "dir_update OFF %s\n", dir_u->pax_c));
  return cha;
}
Beispiel #5
0
/* u2_unix_ef_look(): update the root.
*/
void
u2_unix_ef_look(void)
{
  u2_unix* unx_u = &u2_Host.unx_u;
  u2_noun  won;
  u2_uhot* hot_u; 

  //  find owners without directories
  {
    for ( won = u2A->own; u2_nul != won; won = u2t(won) ) {
      u2_noun who = u2h(won);
      mpz_t who_mp;

      u2_cr_mp(who_mp, who);
      for ( hot_u = unx_u->hot_u; 
            hot_u && (0 != mpz_cmp(who_mp, hot_u->who_mp));
            hot_u = hot_u->nex_u );

      mpz_clear(who_mp);
      if ( 0 == hot_u ) {
        _unix_hot_gain(u2k(who), u2_no);
      }
    }
  }

  //  find directories without owners
  {
    u2_uhot** het_u = &(unx_u->hot_u);

    while ( 0 != (hot_u=*het_u) ) {
      for ( won = u2A->own; u2_nul != won; won = u2t(won) ) {
        u2_noun who = u2h(won);
        mpz_t   who_mp;

        u2_cr_mp(who_mp, who);
        if ( 0 == mpz_cmp(who_mp, hot_u->who_mp) ) {
          break;
        }
        mpz_clear(who_mp);
      }

      if ( u2_nul == won ) {
        *het_u = hot_u->nex_u;
 
        // uL(fprintf(uH, "sync: lose %s\n", hot_u->dir_u.pax_c));
        _unix_hot_lose(hot_u);

        free(hot_u);
        continue;
      }
      else {
        het_u = &(hot_u->nex_u);
      }
    }
  }

  //  update all ships
  {
    u2_uhot* hot_u;

    for ( hot_u = unx_u->hot_u; hot_u; hot_u = hot_u->nex_u ) {
      _unix_ship_update(hot_u);
    }
  }
}
Beispiel #6
0
/* _unix_dir_update(): update directory.
*/
static void
_unix_dir_update(u2_udir* dir_u, DIR* rid_u)
{
  if ( u2_yes == dir_u->dry ) {
    return;
  }
  else {
    //  Update all wet subdirectories.
    //
    u2_udir** dis_u;
    u2_ufil** fil_u;

    for ( dis_u = &(dir_u->dis_u); *dis_u; ) {
      if ( u2_yes == (*dis_u)->dry ) {
        dis_u = &(*dis_u)->nex_u;
      }
      else {
        DIR* red_u = opendir((*dis_u)->pax_c);

        if ( 0 == red_u ) {
          u2_udir* ded_u = *dis_u;
          u2_udir* nex_u = ded_u->nex_u;

          // uL(fprintf(uH, "removed directory %s\n", ded_u->pax_c));
          _unix_dir_free(ded_u);

          *dis_u = nex_u;
        }
        else {
          _unix_dir_update(*dis_u, red_u);

          closedir(red_u);
          dis_u = &(*dis_u)->nex_u;
        }
      }
    }

    //  Check all wet files to see if they need deleting.
    //
    for ( fil_u = &(dir_u->fil_u); *fil_u; ) {
      if ( u2_yes == (*fil_u)->dry ) {
        fil_u = &(*fil_u)->nex_u;
      }
      else {
        struct stat buf_u;

        if ( -1 == stat((*fil_u)->pax_c, &buf_u) ||
             !(S_IFREG & buf_u.st_mode) )
        {
          u2_ufil* ded_u = *fil_u;
          u2_ufil* nex_u = ded_u->nex_u;

          // uL(fprintf(uH, "removed file %s\n", ded_u->pax_c));
          _unix_file_free(ded_u);
          *fil_u = nex_u;
        }
        else {
          fil_u = &(*fil_u)->nex_u;
        }
      }
    }

    //  Scan for new files/directories.  XX - this is O(n^2) brute
    //  force, and could be done by smarter event processing.
    //
    while ( 1 ) {
      struct dirent  ent_u;
      struct dirent* out_u;

      if ( readdir_r(rid_u, &ent_u, &out_u) != 0 ) {
        // uL(fprintf(uH, "%s: %s\n", dir_u->pax_c, strerror(errno)));
        c3_assert(0);
      }
      else if ( !out_u ) {
        break;
      }
      else if ( ('.' == out_u->d_name[0]) ) {    //  XX screws up some paths
        continue;
      }
      else {
        c3_c* pax_c = _unix_down(dir_u->pax_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);
          continue;
        }
        else {
          if ( !S_ISDIR(buf_u.st_mode) ) {
            mpz_t    mod_mp;
            u2_ufil* fil_u;

            if ( ( NULL == strrchr(out_u->d_name, '.')) ||
                 ( '~' == out_u->d_name[strlen(out_u->d_name) - 1] )
               ) {
              continue;
            }

            {
              u2_noun mod = c3_stat_mtime(&buf_u);

              u2_cr_mp(mod_mp, mod);
              u2z(mod);
            }
            for ( fil_u = dir_u->fil_u; fil_u; fil_u = fil_u->nex_u ) {
              if ( !strcmp(pax_c, fil_u->pax_c) ) {
                break;
              }
            }
            if ( !fil_u ) {
              fil_u = c3_malloc(sizeof(u2_ufil));

              // uL(fprintf(uH, "found file %s\n", pax_c));
              _unix_file_watch(fil_u, dir_u, pax_c, mod_mp);

              fil_u->nex_u = dir_u->fil_u;
              dir_u->fil_u = fil_u;
            }
            mpz_clear(mod_mp);
          }
          else {
            u2_udir* dis_u;

            for ( dis_u = dir_u->dis_u; dis_u; dis_u = dis_u->nex_u ) {
              if ( !strcmp(pax_c, dis_u->pax_c) ) {
                break;
              }
            }
            if ( !dis_u ) {
              DIR* red_u = _unix_opendir(pax_c);
              dis_u = c3_malloc(sizeof(u2_udir));

              // uL(fprintf(uH, "found directory %s\n", pax_c));
              _unix_dir_watch(dis_u, dir_u, pax_c);
              _unix_dir_update(dis_u, red_u);

              dis_u->nex_u = dir_u->dis_u;
              dir_u->dis_u = dis_u;

              closedir(red_u);
            } else {
              free(pax_c);
            }
          }
        }
      }
    }
  }
}
Beispiel #7
0
/* u2_unix_ef_look(): update the root.
*/
void
u2_unix_ef_look(void)
{
  u2_unix* unx_u = &u2_Host.unx_u;
  u2_noun  won;
  u2_uhot* hot_u;

  if ( u2_nul != u2A->roe ) {
    //  We can't generate a working %into event here because there
    //  are other events, possibly containing %into, that are queued;
    //  they will change the state of %clay and cause a patch that
    //  doesn't work.
    //
    return;
  }

  //  find owners without directories
  {
    for ( won = u2A->own; u2_nul != won; won = u2t(won) ) {
      u2_noun who = u2h(won);
      mpz_t who_mp;

      u2_cr_mp(who_mp, who);
      for ( hot_u = unx_u->hot_u;
            hot_u && (0 != mpz_cmp(who_mp, hot_u->who_mp));
            hot_u = hot_u->nex_u );

      mpz_clear(who_mp);
      if ( 0 == hot_u ) {
        _unix_hot_gain(u2k(who), u2_no);
      }
    }
  }

  //  find directories without owners
  {
    u2_uhot** het_u = &(unx_u->hot_u);

    while ( 0 != (hot_u=*het_u) ) {
      for ( won = u2A->own; u2_nul != won; won = u2t(won) ) {
        u2_noun who = u2h(won);
        mpz_t   who_mp;
        c3_w    cmp_w;

        u2_cr_mp(who_mp, who);
        cmp_w = mpz_cmp(who_mp, hot_u->who_mp);
        mpz_clear(who_mp);
        if ( 0 == cmp_w ) {
          break;
        }
      }

      if ( u2_nul == won ) {
        *het_u = hot_u->nex_u;

        // uL(fprintf(uH, "sync: lose %s\n", hot_u->dir_u.pax_c));
        _unix_hot_lose(hot_u);

        free(hot_u);
        continue;
      }
      else {
        het_u = &(hot_u->nex_u);
      }
    }
  }

  //  update all ships
  {
    u2_uhot* hot_u;

    for ( hot_u = unx_u->hot_u; hot_u; hot_u = hot_u->nex_u ) {
      _unix_ship_update(hot_u);
    }
  }
}
Beispiel #8
0
/* _unix_desk_sync_tofu(): sync out file install.
*/
static void
_unix_desk_sync_tofu(u2_udir* dir_u,
                     u2_noun  pre,
                     u2_noun  ext,
                     u2_noun  mis)
{
  c3_c*     pox_c = _unix_file_form(dir_u, u2k(pre), u2_no, u2k(ext));
  c3_c*     pux_c = _unix_file_form(dir_u, u2k(pre), u2_yes, u2k(ext));
  u2_ufil** fil_u;

  // uL(fprintf(uH, "tofu pox_c %s op %s\n", pox_c, u2_cr_string(u2h(mis))));

#ifdef SYNCLOG
  c3_w slot = u2_Host.unx_u.lot_w++ % 1024;
  free(u2_Host.unx_u.sylo[slot].pax_c);
  u2_Host.unx_u.sylo[slot].pax_c = 0;
#endif

  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) )
    {
      break;
    }
    else fil_u = &((*fil_u)->nex_u);
  }

  if ( *fil_u && (c3__del == u2h(mis)) ) {
    u2_ufil* ded_u = *fil_u;

#ifdef SYNCLOG
    u2_Host.unx_u.sylo[slot].unx   = u2_no;
    u2_Host.unx_u.sylo[slot].wer_m = c3_s4('t','o','f','u');
    u2_Host.unx_u.sylo[slot].wot_m = c3__del;
    u2_Host.unx_u.sylo[slot].pax_c = strdup(ded_u->pax_c);
#endif

    *fil_u = ded_u->nex_u;
    _unix_unlink(ded_u->pax_c);
    _unix_file_free(ded_u);

    free(pox_c);
    free(pux_c);
  }
  else {
    u2_noun god, oat;
    c3_c*   pax_c;

    if ( *fil_u ) {
      u2_noun old = _unix_file_load(*fil_u);
      c3_assert(c3__mut == u2h(mis));

      god = _unix_desk_sync_udon(u2k(u2t(mis)), old);
      _unix_unlink((*fil_u)->pax_c);
      free((*fil_u)->pax_c);
    }
    else {
      c3_assert(c3__ins == u2h(mis));
      god = u2k(u2t(mis));
    }

    if ( u2_yes == u2du(god) ) {
      oat = u2_cke_jam(god);
      pax_c = pux_c; free(pox_c);
    } else {
      oat = god;
      pax_c = pox_c; free(pux_c);
    }

#ifdef SYNCLOG
    u2_Host.unx_u.sylo[slot].unx   = u2_no;
    u2_Host.unx_u.sylo[slot].wer_m = c3_s4('t','o','f','u');
    u2_Host.unx_u.sylo[slot].wot_m = u2h(mis);
    u2_Host.unx_u.sylo[slot].pax_c = strdup(pax_c);
#endif

    _unix_save(pax_c, oat);

    if ( *fil_u ) {
      (*fil_u)->dot_c = (pax_c + ((*fil_u)->dot_c - (*fil_u)->pax_c));
      (*fil_u)->pax_c = pax_c;

      mpz_clear((*fil_u)->mod_mp);
      u2_cr_mp((*fil_u)->mod_mp, u2A->now);
    }
    else {
      mpz_t mod_mp;

      u2_cr_mp(mod_mp, u2A->now);
      *fil_u = c3_malloc(sizeof(u2_ufil));

      _unix_file_watch(*fil_u, dir_u, pax_c, mod_mp);
      mpz_clear(mod_mp);
    }
  }
  u2z(pre); u2z(ext); u2z(mis);
}