Merge remote-tracking branch 'origin/release-candidate' into lighter-than-eyre

This commit is contained in:
Elliot Glaysher 2019-01-16 10:26:22 -08:00
commit 6ffbea1071
48 changed files with 1086 additions and 1134 deletions

View File

@ -1,3 +1,4 @@
dist: xenial
language: node_js
node_js:
- 4
@ -32,6 +33,8 @@ addons:
packages:
- python3
- python3-pip
- python3-setuptools
- python3-wheel
- libgmp3-dev
- libsigsegv-dev
- openssl

View File

@ -1 +1 @@
00c79de3df4ecae9f499053990471d420f0e79a0
d318b2cfcf33ac41aeaacb03e8b5593f8eb5e690

View File

@ -26,6 +26,16 @@ function exit() {
}
Promise.resolve(urbit)
// XX temporary
// send ctrl-x to select dojo
//
.then(function(){
return urbit.expect(/talk\[\] /)
.then(function() {
return urbit.pty.write("\x18")
})
.then(function() { return urbit })
})
.then(actions.safeBoot)
.then(actions.test)
.then(exit)

View File

@ -2,49 +2,35 @@
Thank you for your interest in contributing to urbit.
## Fake `~zod`s
See [urbit.org/docs/getting-started](https://urbit.org/docs/getting-started/#arvo)
for basic orientation and usage instructions.
## Fake ships
You may have an identity on the live network, but doing all your
development on the live network would be cumbersome and unnecessary.
Standard practice in urbit development is to work on a fake `~zod`. A
fake `~zod` will get its initial files from a directory you specify
rather than trying to sync them over the network, which is invaluable
for working in Hoon. Also, a fake `~zod` or any fake urbit instances you
start do not talk to the live network, but to a fake network that exists
only on your computer.
Standard practice in urbit development is to work on a fake `~zod`.
Fake ships use deterministic keys (derived from the ship address)
and don't talk to the live network. They can talk to each other over
the local loopback.
First, you'll want to check out the Arvo repository. Arvo is kept in its
own repository, and changes more rapidly than the main C project does.
To start a fake ship, simply specify the name with `-F`:
git clone https://github.com/urbit/arvo
```
$ urbit -F zod
```
The arvo repository can live safely inside the main urbit repository if
you want, since it's listed in .gitignore. However, vere will use the
path you specify on the command line with the `-A` option.
You can also pass a name for the *pier* (or ship directory):
To start a fake `~zod`, the command is:
```
$ urbit -F zod my-fake-zod
```
$ urbit -c -F zod -A [arvo checkout] [pier directory]
To resume a fake ship, just pass the name of the pier:
To resume one that was already created, just as on the live network,
remove `-c` and `-A [arvo checkout]` (but leave the rest of the options
there). `-F` uses the fake network.
## Kernel development
Working on either C or non-kernel Hoon should not bring any surprises,
but the Hoon kernel (anything under `arvo/arvo/`) is bootstrapped
from `urbit.pill`, and must be recompiled if any changes are made. This
should happen automatically when you make changes, but if it doesn't,
the command to manually recompile the kernel and install the new kernel
is `|reset` in `dojo`. This rebuilds from the `arvo` directory in the
`home` desk in `%clay`. Currently, `|reset` does not reload apps like
`dojo` itself, which will still reference the old kernel. To force them
to reload, make a trivial edit to their main source file (under the
`app` directory) in `%clay`.
If you do any kernel development, be sure to read the section below about
pills.
```
$ urbit fake-zod/
```
## Git practice
@ -54,16 +40,22 @@ what you are doing, skip down to the Style section.
Start by cloning the repository on your work machine:
git clone https://github.com/urbit/urbit
```
$ git clone https://github.com/urbit/urbit
```
And, additionally, fork the repository on GitHub by clicking the "Fork"
button. Add your fork as a remote:
git remote add [username] https://github.com/[username]/urbit
```
$ git remote add [username] https://github.com/[username]/urbit
```
and set it as the default remote to push to:
git config --local remote.pushDefault [username]
```
$ git config --local remote.pushDefault [username]
```
This is good practice for any project that uses git. You will pull
upstream branches from urbit/urbit and push to your personal urbit fork
@ -73,12 +65,16 @@ Next, start a new branch to do your work on. For `urbit`, please use the
latest tagged release as your starting point. For other repositories,
anywhere pointed to by `master` is alright to start from.
git checkout -b [branch name] [starting point]
```
$ git checkout -b [branch name] [starting point]
```
Now you are free to do your work on this branch. When finished, you may
want to clean up your commits:
git rebase -i [starting point]
```
$ git rebase -i [starting point]
```
Then you can push to your public fork with `git push` and make a pull
request via the GitHub UI.
@ -96,73 +92,66 @@ compound statement. One thing to watch out for is top-level sections in
source files that are denoted by comments and are actually indented one
level.
Hoon will be a less familiar language to many contributors. Some of our
less obvious stylistic rules are:
Hoon will be a less familiar language to many contributors. More details
are forthcoming; for now, the `%ford` vane (in
[`sys/vane/ford.hoon`](https://github.com/urbit/arvo/blob/master/sys/vane/ford.hoon))
is the highest quality code in the kernel.
- Keep your source files 80 characters or less wide. Many urbit
developers use 80 character terminals/tmux panes/&c.
- Tab characters are actually a syntax error, so be extra sure your
editor is not inserting any. Trailing whitespace is *usually* not a
syntax error, but avoiding it is encouraged.
- The kernel convention is that line comments start at column 57 with
the `::` followed by 2 spaces. This leaves 20 characters for the
comment. Outside the kernel, things are less strict.
- Tall arms within a core are conventionally separated by empty comments
(just `::`) at the same indentation level as the initial `++` or `+-`.
The last arm in a core is not followed by an empty comment, because it
is visually closed by the `--` that closes the core. The empty comment
is also sometimes omitted in data structure definitions.
## Kernel development
Working on either C or non-kernel Hoon should not bring any surprises, but
the Hoon kernel (anything under `sys/` in [urbit/arvo](https://github.com/urbit/arvo))
is bootstrapped from `urbit.pill`, and must be recompiled if any changes are
made. This should happen automatically when you make changes, but if it doesn't,
the command to manually recompile the kernel and install the new kernel
is `|reset` in `dojo`. This rebuilds from the `sys` directory in the
`home` desk in `%clay`. Currently, `|reset` does not reload apps like
`dojo` itself, which will still reference the old kernel. To force them
to reload, make a trivial edit to their main source file (under the
`app` directory) in `%clay`.
## The kernel and pills
urbit bootstraps itself using a binary blob called `urbit.pill`. You
probably remember it being fetched from `bootstrap.urbit.org` before
your first boot. This is just the compiled version of the kernel, which
you can find in the `arvo/arvo/` directory - `hoon.hoon`, `zuse.hoon`,
and so on.
your first boot. This is the compiled version of the kernel (which
you can find in the `sys` directory of [urbit/arvo](https://github.com/urbit/arvo)),
along with a complete copy of the Arvo repository as source.
The procedure for creating `urbit.pill` is often called "soliding". It
is somewhat similar to `|reset`, but instead of replacing your running
kernel, it writes the compiled kernel to a file. The command to solid
is, on a fakezod:
is:
.urbit/pill +solid
```
> .urbit/pill +solid
```
When the compilation finishes, your `urbit.pill` will be found in the
`[pier]/.urb/put/` directory.
You can boot a new ship from your local pill with `-B`:
```
$ urbit -F zod -B path/to/urbit.pill fake-zod
```
Ordinarily, `http://bootstrap.urbit.org/latest.pill` will be updated
to match whatever's on `master` in the `arvo` repository with every
merge to `master`. Older pills will be stored with the `git` SHA1 of the
relevant commit as `[sha1].pill`.
merge to `master`. Older pills will be stored with the first 10
characters of the `git` SHA1 of the relevant commit as `git-[sha1].pill`.
If you're doing heavy kernel hacking and want to submit intermediate
pills for your branch, please include them with your pull request, and
they'll be uploaded to `bootstrap.urbit.org` when your branch is merged.
The continuous-integration build of the `urbit/arvo` repository
uploads these pills for any successful build (if the commit or pull-request
affects the `sys/` directory).
## Debug urbit with `gdb`
You can boot from one of these pills by passing the path to an Arvo
working copy with `-A` (and `-s` for *search*):
Follow the build instructions in README.md but run `make` with argument `DEBUG=yes`:
(If you've already built urbit first run `make clean`.)
make DEBUG=yes
Run `gdb`, while loading `bin/urbit` and its symbol table:
gdb bin/urbit
Set a breakpoint on `main()` (optional):
break main
Run your urbit comet `mycomet`:
run mycomet
Continue from the breakpoint on `main()`:
continue
```
$ git clone https://github.com/urbit/arvo
$ urbit -F zod -A path/to/arvo -s fake-zod
```
## What to work on
@ -180,12 +169,10 @@ eager to have outside contributions on. Check here first!
## Staying in touch
The urbit developers communicate on urbit itself. Joining the
`urbit-meta` channel on `talk` is highly recommended, as is reading the
forums at [http://urbit.org/fora](http://urbit.org/fora). Subscribing to
`urbit-dev` on Google Groups is also recommended, since this is where
continuity breach notifications are sent.
`urbit-meta` channel on
[`:talk`](https://urbit.org/docs/learn/arvo/arvo-internals/messaging/)
is highly recommended, as is reading the forums at
[http://urbit.org/fora](http://urbit.org/fora).
Pull requests in non-GitHub forms can go to Raymond Pasco
([ray@the.ug](mailto:ray@the.ug)). Questions or other communications
about contributing to Urbit can go to Raymond Pasco or Philip Monk
([philip.monk@tlon.io](mailto:philip.monk@tlon.io)).
Questions or other communications about contributing to Urbit can go to
[support@urbit.org](mailto:support@urbit.org).

View File

@ -1,15 +1,17 @@
> The Urbit address space is now live on the Ethereum blockchain. Were calling it Azimuth and you can find it at [`0x223c067f8cf28ae173ee5cafea60ca44c335fecb`](https://etherscan.io/address/0x223c067f8cf28ae173ee5cafea60ca44c335fecb) or [`azimuth.eth`](https://etherscan.io/address/azimuth.eth). Owners of Azimuth points (galaxies, stars or planets) can use [Bridge](https://github.com/urbit/bridge/releases) to manage them and view their balance now. Sometime in the next few days, owners of Azimuth points will be able to boot Arvo, the Urbit OS, from their Azimuth point and request access to one of our cities: private communities for chat and discussion. These new cities use Landscape, a brand new UI for using Urbit in the browser.
# Install instructions
To install and run Urbit please follow the instructions at
[urbit.org/docs/using/install](http://urbit.org/docs/using/install). Packages
and source tarballs are available there. You'll be on the live network in a few
minutes.
[urbit.org/docs/getting-started/](https://urbit.org/docs/getting-started/).
Packages and source tarballs are available there. You'll be on the live network
in a few minutes.
If you're doing development on Urbit, keep reading.
# Build instructions
[![Build Status](https://travis-ci.org/urbit/urbit.svg?branch=maint-0.4)](https://travis-ci.org/urbit/urbit)
[![Build Status](https://travis-ci.org/urbit/urbit.svg?branch=master)](https://travis-ci.org/urbit/urbit)
## External dependencies
@ -23,24 +25,22 @@ If you're doing development on Urbit, keep reading.
- [libcurl](https://curl.haxx.se/libcurl/)
- [libuv](http://libuv.org)
- curses implementation (ncurses on Linux distributions, OS curses otherwise)
- [re2c](http://re2c.org)
Most of these dependencies are unfortunate; we aim to drastically shrink the
list in upcoming versions. `vere` proper makes use of GMP, OpenSSL, libcurl, and
libsigsegv. The multiple build tools are a result of bundled libraries, slated
for future unbundling or removal wherever possible.
libsigsegv.
## Building
Urbit uses Meson build system.
Some libraries which are not found in major distributions:
- ed25519
- http-parser legacy version 0.1.0
- libh2o
- murmur3
- softfloat3
- urbit-scrypt
- commonmark legacy version 0.12.0
- scrypt
are included as git submodules. To build urbit from source, perform the following steps:
@ -63,6 +63,7 @@ To set a prefix for installation use
## Configuration & compilation for legacy meson
The syntax for legacy meson (Version `0.29`) is a bit different.
1. Manually create `build` directory and invoke meson as `meson . ./build`
2. If you want to set options, this is done in one step.
Use `meson -D [options] . ./build` to prepare customized build.
@ -71,34 +72,11 @@ Once the project is configured, use `ninja` to build it.
To install it into the default prefix, use `ninja install`.
If you want to specify custom `DESTDIR`, use `DESTDIR=... ninja install`.
## Building the Debian Package
To build a .deb file for installation on Debian platforms, perform the
following steps:
+ Run `sudo apt install devscripts` to install the `debuild` utility.
+ Update the `debian/changelog` to reflect the changes in this release.
+ If necessary, update the year of the copyright in `debian/copyright`.
+ Clean any build artifacts: Run `make clean` and delete the `bin` directory,
if it exists.
+ Run `tar -xcvf ../urbit-x.y.z.orig.tar.gz .` from the top-level folder in
the repo. This command will create an archive in the directory above the
current directory, which will be used in packaging.
+ Run `debuild -us -uc`, also from the top-level folder in the repo. This
creates a .deb file in the folder above the current directory.
The resulting .deb file should now exist in the folder above the current
directory. To test that the .deb file works properly, you can perform the
following steps:
+ Uninstall urbit: `sudo apt remove urbit`.
+ Run `sudo dpkg -i ../urbit-x.y.z_amd64.deb` to install the new version.
+ Boot up a ship using the `urbit` command.
## Contact
If you have any questions, problems, patches, or proposals for patches, please
feel free to get in touch in whatever way is most convenient:
- Post to `/urbit-meta` on Urbit `:talk`. (You can do this via
[urbit.org/stream](https://urbit.org/stream) without a running Urbit).
- Post to `/urbit-meta` on Urbit [`:talk`](https://urbit.org/docs/learn/arvo/arvo-internals/messaging/).
- Post to [urbit.org/fora](https://urbit.org/fora/).
- Email us directly [questions@urbit.org](mailto:questions@urbit.org).

View File

@ -55,6 +55,11 @@
int
c3_cooked();
/* Fill 16 words (64 bytes) with high-quality entropy.
*/
void
c3_rand(c3_w* rad_w);
/* Short integers.
*/
# define c3_s1(a) ( (a) )

View File

@ -2,8 +2,6 @@
**
** This file is in the public domain.
*/
/** Must be compiled on gcc with C99 support.
**/
#include "config.h"
@ -33,6 +31,7 @@
# include <setjmp.h>
# include <stdio.h>
# include <signal.h>
# include <sys/syscall.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <sys/mman.h>
@ -50,6 +49,7 @@
# include <machine/endian.h>
# include <machine/byte_order.h>
# include <stdio.h>
# include <sys/random.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <sys/mman.h>
@ -140,7 +140,6 @@
# define c3_bswap_16(x) bswap_16(x)
# define c3_bswap_32(x) bswap_32(x)
# define c3_bswap_64(x) bswap_64(x)
# elif defined(U3_OS_osx)
# define c3_bswap_16(x) NXSwapShort(x)
# define c3_bswap_32(x) NXSwapInt(x)
@ -149,7 +148,7 @@
# error "port: byte swap"
# endif
/* Sync
/* Sync.
*/
# if defined(U3_OS_linux)
# define c3_sync(fd) (fdatasync(fd))
@ -161,7 +160,7 @@
# error "port: sync"
# endif
/* Purge
/* Purge.
*/
# if defined(U3_OS_linux)
# include <stdio_ext.h>
@ -172,7 +171,7 @@
# error "port: fpurge"
# endif
/* Stat struct
/* Stat.
*/
# if defined(U3_OS_linux)
# define c3_stat_mtime(dp) (u3_time_t_in_ts((dp)->st_mtime))
@ -186,13 +185,20 @@
# error "port: timeconvert"
# endif
/* Entropy
/* Entropy.
*/
#define c3_rand u3_sist_rand
# if defined(U3_OS_linux)
# define c3_getentropy(B, L) \
((L) == syscall(SYS_getrandom, B, L, 0) ? 0 : -1)
# elif defined(U3_OS_bsd) || defined(U3_OS_osx)
# define c3_getentropy getentropy
# else
# error "port: getentropy"
# endif
/* Static assertion
/* Static assertion.
*/
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
#define STATIC_ASSERT(e,m) \
# define ASSERT_CONCAT_(a, b) a##b
# define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
# define STATIC_ASSERT(e,m) \
;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(int)(!!(e)) }

View File

@ -54,11 +54,11 @@
u3_noun u3qc_dvr(u3_atom, u3_atom);
u3_noun u3qc_end(u3_atom, u3_atom, u3_atom);
u3_noun u3qc_gor(u3_atom, u3_atom);
u3_noun u3qc_hor(u3_atom, u3_atom);
u3_noun u3qc_lsh(u3_atom, u3_atom, u3_atom);
u3_noun u3qc_mas(u3_atom);
u3_noun u3qc_met(u3_atom, u3_atom);
u3_noun u3qc_mix(u3_atom, u3_atom);
u3_noun u3qc_mor(u3_atom, u3_atom);
u3_noun u3qc_muk(u3_atom, u3_atom, u3_atom);
u3_noun u3qc_peg(u3_atom, u3_atom);
u3_noun u3qc_pow(u3_atom, u3_atom);
@ -69,7 +69,6 @@
u3_noun u3qc_rsh(u3_atom, u3_atom, u3_atom);
u3_noun u3qc_swp(u3_atom, u3_atom);
u3_noun u3qc_sqt(u3_atom);
u3_noun u3qc_vor(u3_atom, u3_atom);
/** Tier 4.
**/

View File

@ -53,11 +53,11 @@
u3_noun u3wc_dvr(u3_noun);
u3_noun u3wc_end(u3_noun);
u3_noun u3wc_gor(u3_noun);
u3_noun u3wc_hor(u3_noun);
u3_noun u3wc_lsh(u3_noun);
u3_noun u3wc_mas(u3_noun);
u3_noun u3wc_met(u3_noun);
u3_noun u3wc_mix(u3_noun);
u3_noun u3wc_mor(u3_noun);
u3_noun u3wc_mug(u3_noun);
u3_noun u3wc_muk(u3_noun);
u3_noun u3wc_peg(u3_noun);
@ -69,7 +69,6 @@
u3_noun u3wc_rsh(u3_noun);
u3_noun u3wc_swp(u3_noun);
u3_noun u3wc_sqt(u3_noun);
u3_noun u3wc_vor(u3_noun);
u3_noun u3wcp_ins(u3_noun);
u3_noun u3wcp_ind(u3_noun);

View File

@ -32,63 +32,46 @@
c3_o
u3r_mean(u3_noun a, ...);
/* u3r_mug():
**
** Compute and/or recall the mug (31-bit hash) of (a).
/* u3r_mug_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_w
u3r_mug(u3_noun a);
u3r_mug_bytes(const c3_y *buf_y,
c3_w len_w);
/* u3r_mug_string():
**
** Compute the mug of `a`, LSB first.
/* u3r_mug_chub(): Compute the mug of `num`, LSW first.
*/
c3_w
u3r_mug_chub(c3_d num_d);
/* u3r_mug_string(): Compute the mug of `a`, LSB first.
*/
c3_w
u3r_mug_string(const c3_c *a_c);
/* u3r_mug_words():
**
** Compute the mug of `buf`, `len`, LSW first.
/* u3r_mug_words(): 31-bit nonzero MurmurHash3 on raw words.
*/
c3_w
u3r_mug_words(const c3_w *buf_w,
c3_w len_w);
u3r_mug_words(const c3_w* key_w, c3_w len_w);
/* u3r_mug_d():
**
** Compute the mug of `num`, LSW first.
/* u3r_mug_both(): Join two mugs.
*/
c3_w
u3r_mug_d(c3_d num_d);
u3r_mug_both(c3_w lef_w, c3_w rit_w);
/* u3r_mug_bytes():
**
** Compute the mug of `buf`, `len`, LSW first.
/* u3r_mug_cell(): Compute the mug of the cell `[hed tel]`.
*/
c3_w
u3r_mug_bytes(const c3_y *buf_w,
c3_w len_w);
u3r_mug_cell(u3_noun hed,
u3_noun tel);
/* u3r_mug_cell():
**
** Compute the mug of `[a b]`.
*/
c3_w
u3r_mug_cell(u3_noun a,
u3_noun b);
/* u3r_mug_trel():
**
** Compute the mug of `[a b c]`.
/* u3r_mug_trel(): Compute the mug of `[a b c]`.
*/
c3_w
u3r_mug_trel(u3_noun a,
u3_noun b,
u3_noun c);
/* u3r_mug_qual():
**
** Compute the mug of `[a b c d]`.
/* u3r_mug_qual(): Compute the mug of `[a b c d]`.
*/
c3_w
u3r_mug_qual(u3_noun a,
@ -96,13 +79,10 @@
u3_noun c,
u3_noun d);
/* u3r_mug_both():
**
** Join two mugs.
/* u3r_mug(): MurmurHash3 on a noun.
*/
c3_w
u3r_mug_both(c3_w a_w,
c3_w b_w);
u3r_mug(u3_noun veb);
/* u3r_fing():
**
@ -422,6 +402,16 @@
c3_w* c_w,
u3_atom d);
/* u3r_chubs():
**
** Copy double-words (a_w) through (a_w + b_w - 1) from (d) to (c).
*/
void
u3r_chubs(c3_w a_w,
c3_w b_w,
c3_d* c_d,
u3_atom d);
/* u3r_string(): `a`, a text atom, as malloced C string.
*/
c3_c*

View File

@ -134,7 +134,7 @@
c3_w ipf_w; // ward ip
c3_s por_s; // ward port
c3_o sec; // secure connection
u3_atom sip; // ward ship
c3_d who_d[2]; // ward ship
c3_c* hot_c; // ward hostname
uv_buf_t non_u; // nonce
struct _u3_http* htp_u; // local server backlink
@ -155,7 +155,7 @@
typedef struct _u3_ward {
uv_tcp_t tcp_u; // listener handle
uv_timer_t tim_u; // expiration timer
u3_atom sip; // reverse proxy for ship
c3_d who_d[2]; // reverse proxy for ship
c3_s por_s; // listening on port
uv_buf_t non_u; // nonce
struct _u3_wcon* won_u; // candidate upstream connections
@ -582,6 +582,7 @@
c3_o abo; // -a, abort aggressively
c3_c* pil_c; // -B, bootstrap from
c3_o bat; // -b, batch create
c3_o can; // -C, chain-only, no eth snapshot
c3_o nuu; // -c, new pier
c3_o dry; // -D, dry compute, no checkpoint
c3_o dem; // -d, daemon
@ -597,6 +598,7 @@
c3_c* key_c; // -k, private key file
c3_o net; // -L, local-only networking
c3_s rop_s; // -l, raft port
c3_c* sap_c; // -m, eth snapshot url
c3_c* nam_c; // -n, unix hostname
c3_o pro; // -P, profile
c3_s por_s; // -p, ames port
@ -605,7 +607,7 @@
c3_c* raf_c; // -r, raft flotilla
c3_o has; // -S, Skip battery hashes
c3_o git; // -s, pill url from arvo git hash
c3_o etn; // -t, use snapshot exclusively to boot
c3_o etn; // -t, trust snapshot for pre-boot
c3_c* url_c; // -u, pill url
c3_o vno; // -V, replay without reboots
c3_o veb; // -v, verbose (inverse of -q)
@ -1189,11 +1191,6 @@
void
u3_sist_get(const c3_c* key_c, c3_y* val_y);
/* u3_sist_rand(): fill 8 words (32 bytes) with high-quality entropy.
*/
void
u3_sist_rand(c3_w* rad_w);
/** HTTP client.
**/
/* u3_cttp_ef_thus(): send %thus effect to cttp.
@ -1213,12 +1210,12 @@
u3_cttp_io_exit(void);
/* u3_dawn_come(): mine a comet under star (unit)
/* u3_dawn_come(): mine a comet
*/
u3_noun
u3_dawn_come(u3_noun star);
u3_dawn_come(void);
/* u3_dawn_vent(): validatated boot event
/* u3_dawn_vent(): validated boot event
*/
u3_noun
u3_dawn_vent(u3_noun seed);

View File

@ -1,46 +0,0 @@
/* j/3/hor.c
**
*/
#include "all.h"
/* functions
*/
u3_noun
u3qc_hor(u3_noun a,
u3_noun b)
{
if ( c3y == u3ud(a) ) {
if ( c3y == u3ud(b) ) {
return u3qc_gor(a, b);
} else {
return c3y;
}
} else {
if ( c3y == u3ud(b) ) {
return c3n;
}
else {
u3_noun h_a = u3h(a);
u3_noun h_b = u3h(b);
if ( c3y == u3r_sing(h_a, h_b) ) {
return u3qc_gor(u3t(a), u3t(b));
} else {
return u3qc_gor(h_a, h_b);
}
}
}
}
u3_noun
u3wc_hor(u3_noun cor)
{
u3_noun a, b;
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0)) ) {
return u3m_bail(c3__exit);
} else {
return u3qc_hor(a, b);
}
}

View File

@ -1,4 +1,4 @@
/* j/3/vor.c
/* j/3/mor.c
**
*/
#include "all.h"
@ -7,7 +7,7 @@
/* functions
*/
u3_noun
u3qc_vor(u3_atom a,
u3qc_mor(u3_atom a,
u3_atom b)
{
c3_w c_w = u3r_mug(u3r_mug(a));
@ -19,13 +19,13 @@
else return (c_w < d_w) ? c3y : c3n;
}
u3_noun
u3wc_vor(u3_noun cor)
u3wc_mor(u3_noun cor)
{
u3_noun a, b;
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0)) ) {
return u3m_bail(c3__exit);
} else {
return u3qc_vor(a, b);
return u3qc_mor(a, b);
}
}

View File

@ -16,20 +16,30 @@
c3_y *key_y;
c3_w out_w;
c3_assert(u3r_met(5, seed) <= 1);
c3_assert(u3r_met(0, len) <= 31);
c3_assert(u3r_met(3, key) <= len);
c3_assert( u3r_met(5, seed) <= 1 );
c3_assert( u3r_met(0, len) <= 31 );
c3_assert( u3r_met(3, key) <= len );
seed_w = u3r_word(0, seed);
len_w = u3r_word(0, len);
if (len_w > 0) { /* can't u3a_calloc 0 bytes */
key_y = u3a_calloc(sizeof(c3_y), len);
} else {
// can't u3a_calloc 0 bytes
//
if ( 0 == len_w ) {
key_y = 0;
}
u3r_bytes(0, len, key_y, key);
else {
key_y = u3a_calloc(sizeof(c3_y), len_w);
}
MurmurHash3_x86_32(key_y, len, seed_w, &out_w);
// Efficiency: unnecessary copy.
//
// We could calculate the hash directly against
// the atom internals, a la u3r_mug
//
u3r_bytes(0, len_w, key_y, key);
MurmurHash3_x86_32(key_y, len_w, seed_w, &out_w);
u3a_free(key_y);
return u3i_words(1, &out_w);

View File

@ -31,7 +31,7 @@
return u3m_bail(c3__exit);
}
else {
if ( c3y == u3qc_vor(u3h(n_l_a), u3h(n_r_a)) ) {
if ( c3y == u3qc_mor(u3h(n_l_a), u3h(n_r_a)) ) {
u3_noun new_right = u3nt(u3k(n_a),
u3k(r_l_a),
u3k(r_a));

View File

@ -25,7 +25,7 @@
|| c3n == u3r_cell(n_e, &p_n_e, &q_n_e) ) {
return u3m_bail(c3__exit);
} else {
if ( c3y == u3qc_vor(p_n_d, p_n_e) ) {
if ( c3y == u3qc_mor(p_n_d, p_n_e) ) {
return u3nt(u3k(n_d),
u3k(l_d),
_b_dif_join(u3k(r_d), u3k(e)));

View File

@ -40,7 +40,7 @@
else if ( c3n == u3r_cell(n_b, &p_n_b, &q_n_b) ) {
return u3m_bail(c3__exit);
}
else if ( c3y == u3qc_vor(p_n_a, p_n_b) ) {
else if ( c3y == u3qc_mor(p_n_a, p_n_b) ) {
if ( c3y == u3r_sing(p_n_a, p_n_b) ) {
return u3nt(
u3k(n_b),

View File

@ -41,7 +41,7 @@
if ( c3y == u3qc_gor(b, pn_a) ) {
d = u3qdb_put(l_a, b, c);
if ( c3y == u3qc_vor(pn_a, u3h(u3h(d))) ) {
if ( c3y == u3qc_mor(pn_a, u3h(u3h(d))) ) {
return u3nt(u3k(n_a),
d,
u3k(r_a));
@ -64,7 +64,7 @@
else {
d = u3qdb_put(r_a, b, c);
if ( c3y == u3qc_vor(pn_a, u3h(u3h(d))) ) {
if ( c3y == u3qc_mor(pn_a, u3h(u3h(d))) ) {
return u3nt(u3k(n_a),
u3k(l_a),
d);

View File

@ -40,7 +40,7 @@
else if ( c3n == u3r_cell(lr_b, &l_b, &r_b) ) {
return u3m_bail(c3__exit);
}
else if ( c3y == u3qc_vor(p_n_a, p_n_b) ) {
else if ( c3y == u3qc_mor(p_n_a, p_n_b) ) {
if ( c3y == u3r_sing(p_n_a, p_n_b) ) {
return u3nt(u3k(n_b),
u3qdb_uni(u3k(l_a),

View File

@ -25,7 +25,7 @@
u3_noun c, n_c, l_c, r_c;
u3_noun d;
if ( c3y == u3qc_hor(b, n_a) ) {
if ( c3y == u3qc_gor(b, n_a) ) {
c = _i_bif_putroot(l_a, b);
u3r_trel(c, &n_c, &l_c, &r_c);
d = u3nt(u3k(n_c),

View File

@ -29,7 +29,7 @@
return u3m_bail(c3__exit);
}
else {
if ( c3y == u3qc_vor(n_l_a, n_r_a) ) {
if ( c3y == u3qc_mor(n_l_a, n_r_a) ) {
u3_noun new_right = u3nt(u3k(n_a),
u3k(r_l_a),
u3k(r_a));
@ -72,7 +72,7 @@
return u3m_bail(c3__exit);
}
else if ( c3n == u3r_sing(n_a, b) ) {
if ( c3y == u3qc_hor(b, n_a) ) {
if ( c3y == u3qc_gor(b, n_a) ) {
return u3nt(u3k(n_a),
u3qdi_del(l_a, b),
u3k(r_a));

View File

@ -21,7 +21,7 @@
|| c3n == u3r_trel(e, &n_e, &l_e, &r_e) ) {
return u3m_bail(c3__exit);
} else {
if ( c3y == u3qc_vor(n_d, n_e) ) {
if ( c3y == u3qc_mor(n_d, n_e) ) {
return u3nt(u3k(n_d),
u3k(l_d),
_i_dif_join(u3k(r_d), u3k(e)));

View File

@ -24,7 +24,7 @@
return c3y;
}
else {
if ( c3y == u3qc_hor(b, n_a) ) {
if ( c3y == u3qc_gor(b, n_a) ) {
return u3qdi_has(l_a, b);
}
else return u3qdi_has(r_a, b);

View File

@ -28,7 +28,7 @@
return u3m_bail(c3__exit);
}
else {
if ( c3y == u3qc_vor(n_b, n_a) ) {
if ( c3y == u3qc_mor(n_b, n_a) ) {
c = a; a = b; b = c;
c = n_a; n_a = n_b; n_b = c;
c = lr_a; lr_a = lr_b; lr_b = c;
@ -44,7 +44,7 @@
u3qdi_int(l_a, l_b),
u3qdi_int(r_a, r_b));
}
else if ( c3y == u3qc_hor(n_b, n_a) ) {
else if ( c3y == u3qc_gor(n_b, n_a) ) {
return u3qdi_uni(u3qdi_int(l_a,
u3nt(n_b,
l_b,

View File

@ -28,7 +28,7 @@
return u3m_bail(c3__exit);
}
else {
if ( c3y == u3qc_vor(n_b, n_a) ) {
if ( c3y == u3qc_mor(n_b, n_a) ) {
c = a; a = b; b = c;
c = n_a; n_a = n_b; n_b = c;
c = lr_a; lr_a = lr_b; lr_b = c;
@ -44,7 +44,7 @@
u3qdi_mer(l_a, l_b),
u3qdi_mer(r_a, r_b));
}
else if ( c3y == u3qc_hor(n_b, n_a) ) {
else if ( c3y == u3qc_gor(n_b, n_a) ) {
return u3qdi_mer(u3nt(n_a,
u3qdi_mer(l_a,
u3nt(n_b,

View File

@ -27,10 +27,10 @@
return u3m_bail(c3__exit);
}
else {
if ( c3y == u3qc_hor(b, n_a) ) {
if ( c3y == u3qc_gor(b, n_a) ) {
c = u3qdi_put(l_a, b);
if ( c3y == u3qc_vor(n_a, u3h(c)) ) {
if ( c3y == u3qc_mor(n_a, u3h(c)) ) {
return u3nt(u3k(n_a),
c,
u3k(r_a));
@ -52,7 +52,7 @@
else {
c = u3qdi_put(r_a, b);
if ( c3y == u3qc_vor(n_a, u3h(c)) ) {
if ( c3y == u3qc_mor(n_a, u3h(c)) ) {
return u3nt(u3k(n_a),
u3k(l_a),
c);

View File

@ -23,11 +23,11 @@ _in_uni(u3_noun a, u3_noun b)
{
return u3m_bail(c3__exit);
}
else if ( c3n == u3qc_vor(n_a, n_b) ) {
else if ( c3n == u3qc_mor(n_a, n_b) ) {
if ( c3y == u3r_sing(n_a, n_b) ) {
return u3nt(u3k(n_b), _in_uni(l_a, l_b), _in_uni(r_a, r_b));
}
else if ( c3y == u3qc_hor(n_a, n_b) ) {
else if ( c3y == u3qc_gor(n_a, n_b) ) {
naw = u3nt(u3k(n_a), u3k(l_a), u3_nul);
sub = _in_uni(naw, l_b);
neb = u3nt(u3k(n_b), sub, u3k(r_b));
@ -47,7 +47,7 @@ _in_uni(u3_noun a, u3_noun b)
else if ( c3y == u3r_sing(n_b, n_a) ) {
return u3nt(u3k(n_b), _in_uni(l_a, l_b), _in_uni(r_a, r_b));
}
else if ( c3y == u3qc_hor(n_b, n_a) ) {
else if ( c3y == u3qc_gor(n_b, n_a) ) {
neb = u3nt(u3k(n_b), u3k(l_b), u3_nul);
sub = _in_uni(l_a, neb);
naw = u3nt(u3k(n_a), sub, u3k(r_a));

View File

@ -815,8 +815,6 @@ static u3j_harm _141_two_end_a[] = {{".2", u3wc_end, c3y}, {}};
static c3_c* _141_two_end_ha[] = {0};
static u3j_harm _141_two_gor_a[] = {{".2", u3wc_gor, c3y}, {}};
static c3_c* _141_two_gor_ha[] = {0};
static u3j_harm _141_two_hor_a[] = {{".2", u3wc_hor, c3y}, {}};
static c3_c* _141_two_hor_ha[] = {0};
static u3j_harm _141_two_lsh_a[] = {{".2", u3wc_lsh, c3y}, {}};
static c3_c* _141_two_lsh_ha[] = {0};
static u3j_harm _141_two_mas_a[] = {{".2", u3wc_mas, c3y}, {}};
@ -825,6 +823,8 @@ static u3j_harm _141_two_met_a[] = {{".2", u3wc_met, c3y}, {}};
static c3_c* _141_two_met_ha[] = {0};
static u3j_harm _141_two_mix_a[] = {{".2", u3wc_mix, c3y}, {}};
static c3_c* _141_two_mix_ha[] = {0};
static u3j_harm _141_two_mor_a[] = {{".2", u3wc_mor, c3y}, {}};
static c3_c* _141_two_mor_ha[] = {0};
static u3j_harm _141_two_mug_a[] = {{".2", u3wc_mug, c3y}, {}};
static c3_c* _141_two_mug_ha[] = {0};
static u3j_harm _141_two_muk_a[] = {{".2", u3wc_muk, c3y}, {}};
@ -847,8 +847,6 @@ static u3j_harm _141_two_swp_a[] = {{".2", u3wc_swp, c3y}, {}};
static c3_c* _141_two_swp_ha[] = {0};
static u3j_harm _141_two_sqt_a[] = {{".2", u3wc_sqt, c3y}, {}};
static c3_c* _141_two_sqt_ha[] = {0};
static u3j_harm _141_two_vor_a[] = {{".2", u3wc_vor, c3y}, {}};
static c3_c* _141_two_vor_ha[] = {0};
static u3j_harm _141_two_xeb_a[] = {{".2", u3wc_xeb, c3y}, {}};
static c3_c* _141_two_xeb_ha[] = {0};
@ -980,13 +978,13 @@ static u3j_core _141_two_d[] =
{ "dvr", 7, _141_two_dvr_a, 0, _141_two_dvr_ha },
{ "end", 7, _141_two_end_a, 0, _141_two_end_ha },
{ "gor", 7, _141_two_gor_a, 0, _141_two_gor_ha },
{ "hor", 7, _141_two_hor_a, 0, _141_two_hor_ha },
{ "jam", 7, _141_two_jam_a, 0, _141_two_jam_ha },
{ "lsh", 7, _141_two_lsh_a, 0, _141_two_lsh_ha },
{ "mas", 7, _141_two_mas_a, 0, _141_two_mas_ha },
{ "mat", 7, _141_two_mat_a, 0, _141_two_mat_ha },
{ "met", 7, _141_two_met_a, 0, _141_two_met_ha },
{ "mix", 7, _141_two_mix_a, 0, _141_two_mix_ha },
{ "mor", 7, _141_two_mor_a, 0, _141_two_mor_ha },
{ "mug", 7, _141_two_mug_a, 0, _141_two_mug_ha },
{ "muk", 59, _141_two_muk_a, 0, _141_two_muk_ha },
{ "rap", 7, _141_two_rap_a, 0, _141_two_rap_ha },
@ -999,7 +997,6 @@ static u3j_core _141_two_d[] =
{ "peg", 7, _141_two_peg_a, 0, _141_two_peg_ha },
{ "pow", 7, _141_two_pow_a, 0, _141_two_pow_ha },
{ "sqt", 7, _141_two_sqt_a, 0, _141_two_sqt_ha },
{ "vor", 7, _141_two_vor_a, 0, _141_two_vor_ha },
{ "xeb", 7, _141_two_xeb_a, 0, _141_two_xeb_ha },
{ "by", 7, 0, _141_two__by_d, _141_two__by_ha },

View File

@ -59,11 +59,11 @@ jets_c_src = [
'jets/c/dis.c',
'jets/c/end.c',
'jets/c/gor.c',
'jets/c/hor.c',
'jets/c/lsh.c',
'jets/c/mas.c',
'jets/c/met.c',
'jets/c/mix.c',
'jets/c/mor.c',
'jets/c/mug.c',
'jets/c/muk.c',
'jets/c/peg.c',
@ -75,8 +75,7 @@ jets_c_src = [
'jets/c/rip.c',
'jets/c/rsh.c',
'jets/c/swp.c',
'jets/c/sqt.c',
'jets/c/vor.c',
'jets/c/sqt.c'
]
jets_d_src = [
@ -237,7 +236,7 @@ endforeach
incdir = include_directories('include/')
conf_data = configuration_data()
conf_data.set('URBIT_VERSION', '"0.6.0"')
conf_data.set('URBIT_VERSION', '"0.7.0"')
conf_data.set('U3_MEMORY_DEBUG', get_option('gc'))
conf_data.set('U3_CPU_DEBUG', get_option('prof'))
conf_data.set('U3_EVENT_TIME_DEBUG', get_option('event-time'))
@ -364,8 +363,6 @@ install: false)
test('test-hashtable', test_hashtable)
test_mem_sources = noun_src + jets_all_src + vere_sans_main + ['tests/test.c']
test_mem = executable('test-mem',
sources : test_sources + ['tests/test.c'],
include_directories : incdir,
@ -375,3 +372,13 @@ dependencies: deps + os_deps,
install: false)
test('test-mem', test_mem, should_fail: true)
test_hash = executable('test-hash',
sources : test_sources + ['tests/hash_tests.c'],
include_directories : incdir,
c_args : os_c_flags,
link_args: os_link_flags,
dependencies: deps + os_deps,
install: false)
test('test-hash', test_hash)

View File

@ -858,16 +858,16 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
/* Load any patch files; apply them to images.
*/
if ( 0 != (pat_u = _ce_patch_open()) ) {
printf("_ce_patch_apply\r\n");
printf("boot: _ce_patch_apply\r\n");
_ce_patch_apply(pat_u);
printf("_ce_image_sync\r\n");
printf("boot: _ce_image_sync\r\n");
_ce_image_sync(&u3P.nor_u);
_ce_image_sync(&u3P.sou_u);
printf("_ce_patch_delete\r\n");
printf("boot: _ce_patch_delete\r\n");
_ce_patch_delete();
printf("_ce_patch_free\r\n");
printf("boot: _ce_patch_free\r\n");
_ce_patch_free(pat_u);
}
@ -886,7 +886,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
perror("protect");
c3_assert(0);
}
printf("protected loom\r\n");
printf("boot: protected loom\r\n");
}
/* If the images were empty, we are logically booting.

View File

@ -2,6 +2,7 @@
**
*/
#include "all.h"
#include <murmur3.h>
/* _frag_word(): fast fragment/branch prediction for top word.
*/
@ -207,256 +208,6 @@ u3r_mean(u3_noun som,
return _mean_extract(som, len_w, prs_m);
}
static __inline__ c3_w
_mug_fnv(c3_w has_w)
{
return (has_w * ((c3_w)16777619));
}
static __inline__ c3_w
_mug_out(c3_w has_w)
{
return (has_w >> 31) ^ (has_w & 0x7fffffff);
}
static __inline__ c3_w
_mug_both(c3_w lef_w, c3_w rit_w)
{
c3_w bot_w = _mug_fnv(lef_w ^ _mug_fnv(rit_w));
c3_w out_w = _mug_out(bot_w);
if ( 0 != out_w ) {
return out_w;
}
else {
return _mug_both(lef_w, ++rit_w);
}
}
/* u3r_mug_both():
**
** Join two mugs.
*/
c3_w
u3r_mug_both(c3_w lef_w, c3_w rit_w)
{
return _mug_both(lef_w, rit_w);
}
static __inline__ c3_w
_mug_bytes_in(c3_w off_w, c3_w nby_w, const c3_y* byt_y)
{
c3_w i_w;
for ( i_w = 0; i_w < nby_w; i_w++ ) {
off_w = _mug_fnv(off_w ^ byt_y[i_w]);
}
return off_w;
}
static c3_w
_mug_bytes(c3_w off_w, c3_w nby_w, const c3_y* byt_y)
{
c3_w has_w = _mug_bytes_in(off_w, nby_w, byt_y);
c3_w out_w = _mug_out(has_w);
if ( 0 != out_w ) {
return out_w;
}
else {
return _mug_bytes(++off_w, nby_w, byt_y);
}
}
static __inline__ c3_w
_mug_words_in(c3_w off_w, c3_w nwd_w, const c3_w* wod_w)
{
if ( 0 == nwd_w ) {
return off_w;
} else {
c3_w i_w, x_w;
for ( i_w = 0; i_w < (nwd_w - 1); i_w++ ) {
x_w = wod_w[i_w];
{
c3_y a_y = (x_w & 0xff);
c3_y b_y = ((x_w >> 8) & 0xff);
c3_y c_y = ((x_w >> 16) & 0xff);
c3_y d_y = ((x_w >> 24) & 0xff);
off_w = _mug_fnv(off_w ^ a_y);
off_w = _mug_fnv(off_w ^ b_y);
off_w = _mug_fnv(off_w ^ c_y);
off_w = _mug_fnv(off_w ^ d_y);
}
}
x_w = wod_w[nwd_w - 1];
if ( x_w ) {
off_w = _mug_fnv(off_w ^ (x_w & 0xff));
x_w >>= 8;
if ( x_w ) {
off_w = _mug_fnv(off_w ^ (x_w & 0xff));
x_w >>= 8;
if ( x_w ) {
off_w = _mug_fnv(off_w ^ (x_w & 0xff));
x_w >>= 8;
if ( x_w ) {
off_w = _mug_fnv(off_w ^ (x_w & 0xff));
}
}
}
}
}
return off_w;
}
static c3_w
_mug_words(c3_w off_w, c3_w nwd_w, const c3_w* wod_w)
{
c3_w has_w = _mug_words_in(off_w, nwd_w, wod_w);
c3_w out_w = _mug_out(has_w);
if ( 0 != out_w ) {
return out_w;
}
else {
return _mug_words(++off_w, nwd_w, wod_w);
}
}
/* u3r_mug():
**
** Compute and/or recall the mug (31-bit FNV1a hash) of (a).
*/
c3_w
u3r_mug(u3_noun veb)
{
c3_assert(u3_none != veb);
if ( _(u3a_is_cat(veb)) ) {
c3_w x_w = veb;
return _mug_words(2166136261U, (veb ? 1 : 0), &x_w);
} else {
u3a_noun* veb_u = u3a_to_ptr(veb);
if ( veb_u->mug_w ) {
return veb_u->mug_w;
}
else {
if ( _(u3a_is_cell(veb)) ) {
u3a_cell* veb_u = u3a_to_ptr(veb);
u3_noun hed = veb_u->hed;
u3_noun tel = veb_u->tel;
veb_u->mug_w = u3r_mug_cell(hed, tel);
return veb_u->mug_w;
}
else {
u3a_atom* veb_u = u3a_to_ptr(veb);
c3_w len_w = veb_u->len_w;
veb_u->mug_w = _mug_words(2166136261U, len_w, veb_u->buf_w);
return veb_u->mug_w;
}
}
}
}
/* u3r_mug_words():
**
** Compute the mug of `buf`, `len`, LSW first.
*/
c3_w
u3r_mug_words(const c3_w *buf_w,
c3_w len_w)
{
return _mug_words(2166136261U, len_w, buf_w);
}
/* u3r_mug_d():
**
** Compute the mug of `num`, LSW first.
*/
c3_w
u3r_mug_d(c3_d num_d)
{
c3_w buf_w[2];
buf_w[0] = (c3_w)(num_d & 0xffffffffULL);
buf_w[1] = (c3_w)(num_d >> 32ULL);
return u3r_mug_words(buf_w, 2);
}
/* u3r_mug_bytes():
**
** Compute the mug of `buf`, `len`, LSW first.
*/
c3_w
u3r_mug_bytes(const c3_y *buf_w,
c3_w len_w)
{
return _mug_bytes(2166136261U, len_w, buf_w);
}
/* u3r_mug_string():
**
** Compute the mug of `a`, LSB first.
*/
c3_w
u3r_mug_string(const c3_c *a_c)
{
return _mug_bytes(2166136261U, strlen(a_c), (c3_y *)a_c);
}
/* u3r_mug_cell():
**
** Compute the mug of the cell `[hed tel]`.
*/
c3_w
u3r_mug_cell(u3_noun hed,
u3_noun tel)
{
c3_w lus_w = u3r_mug(hed);
c3_w biq_w = u3r_mug(tel);
return u3r_mug_both(lus_w, biq_w);
}
/* u3r_mug_trel():
**
** Compute the mug of `[a b c]`.
*/
c3_w
u3r_mug_trel(u3_noun a,
u3_noun b,
u3_noun c)
{
return u3r_mug_both
(u3r_mug(a), u3r_mug_both(u3r_mug(b), u3r_mug(c)));
}
/* u3r_mug_qual():
**
** Compute the mug of `[a b c d]`.
*/
c3_w
u3r_mug_qual(u3_noun a,
u3_noun b,
u3_noun c,
u3_noun d)
{
return u3r_mug_both
(u3r_mug(a),
u3r_mug_both(u3r_mug(b),
u3r_mug_both(u3r_mug(c), u3r_mug(d))));
}
/* _sang_one(): unify but leak old.
*/
static void
@ -1601,6 +1352,21 @@ u3r_words(c3_w a_w,
}
}
/* u3r_chubs():
**
** Copy double-words (a_w) through (a_w + b_w - 1) from (d) to (c).
*/
void
u3r_chubs(c3_w a_w,
c3_w b_w,
c3_d* c_d,
u3_atom d)
{
/* XX: assumes little-endian
*/
u3r_words(a_w * 2, b_w * 2, (c3_w *)c_d, d);
}
/* u3r_chop():
**
** Into the bloq space of `met`, from position `fum` for a
@ -1710,173 +1476,254 @@ u3r_tape(u3_noun a)
return a_y;
}
#if 0
/* Finalization mix for better avalanching.
*/
static c3_w
_mur_fmix(c3_w h_w)
{
h_w ^= h_w >> 16;
h_w *= 0x85ebca6b;
h_w ^= h_w >> 13;
h_w *= 0xc2b2ae35;
h_w ^= h_w >> 16;
return h_w;
}
/* _mur_words(): raw MurmurHash3 on raw words.
*/
static c3_w
_mur_words(c3_w syd_w, const c3_w* key_w, c3_w len_w)
{
c3_w goc_w = syd_w;
c3_w lig_w = 0xcc9e2d51;
c3_w duf_w = 0x1b873593;
c3_w i_w;
for ( i_w = 0; i_w < len_w; i_w++ ) {
c3_w kop_w = key_w[i_w];
kop_w *= lig_w;
kop_w = c3_rotw(15, kop_w);
kop_w *= duf_w;
goc_w ^= kop_w;
goc_w = c3_rotw(13, goc_w);
goc_w = (goc_w * 5) + 0xe6546b64;
}
goc_w ^= len_w;
goc_w = _mur_fmix(goc_w);
return goc_w;
}
/* u3_mur_words(): 31-bit nonzero MurmurHash3 on raw words.
/* u3r_mug_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_w
u3_mur_words(const c3_w* key_w, c3_w len_w)
u3r_mug_bytes(const c3_y *buf_y,
c3_w len_w)
{
c3_w syd_w = 0xcafebabe;
c3_w ham_w = 0;
while ( 1 ) {
c3_w haz_w = _mur_words(syd_w, key_w, len_w);
c3_w ham_w = (haz_w >> 31) ^ (haz_w & 0x7fffffff);
if ( 0 != ham_w ) return ham_w;
else syd_w++;
while ( 0 == ham_w ) {
c3_w haz_w;
MurmurHash3_x86_32(buf_y, len_w, syd_w, &haz_w);
ham_w = (haz_w >> 31) ^ (haz_w & 0x7fffffff);
syd_w++;
}
return ham_w;
}
/* u3_mur_both():
**
** Join two murs.
/* u3r_mug_chub(): Compute the mug of `num`, LSW first.
*/
c3_w
u3_mur_both(c3_w lef_w, c3_w rit_w)
u3r_mug_chub(c3_d num_d)
{
c3_w buf_w[2];
buf_w[0] = (c3_w)(num_d & 0xffffffffULL);
buf_w[1] = (c3_w)(num_d >> 32ULL);
return u3r_mug_words(buf_w, 2);
}
/* u3r_mug_string(): Compute the mug of `a`, LSB first.
*/
c3_w
u3r_mug_string(const c3_c *a_c)
{
return u3r_mug_bytes((c3_y*)a_c, strlen(a_c));
}
/* u3r_mug_words(): 31-bit nonzero MurmurHash3 on raw words.
*/
c3_w
u3r_mug_words(const c3_w* key_w, c3_w len_w)
{
c3_w byt_w = 0;
c3_w wor_w;
while ( 0 < len_w ) {
wor_w = key_w[--len_w];
byt_w += _(u3a_is_cat(wor_w)) ? u3r_met(3, wor_w) : 4;
}
return u3r_mug_bytes((c3_y*)key_w, byt_w);
}
/* u3r_mug_both(): Join two mugs.
*/
c3_w
u3r_mug_both(c3_w lef_w, c3_w rit_w)
{
c3_w ham_w = lef_w ^ (0x7fffffff ^ rit_w);
return u3_mur_words(&ham_w, (0 == ham_w) ? 0 : 1);
return u3r_mug_words(&ham_w, (0 == ham_w) ? 0 : 1);
}
/* u3_mur(): MurmurHash3 on a noun.
/* u3r_mug_cell(): Compute the mug of the cell `[hed tel]`.
*/
c3_w
u3_mur(u3_noun veb)
{
if ( u3_fly_is_cat(veb) ) {
return u3_mur_words(&veb, (0 == veb) ? 0 : 1);
}
else {
c3_w mur_w;
if ( (mur_w=*u3_at_dog_mur(veb)) ) {
return mur_w;
}
if ( u3dog_is_pom(veb) ) {
mur_w = u3_mur_both(u3_mur(u3h(veb)), u3_mur(u3t(veb)));
}
else {
c3_w len_w = u3_met(5, veb);
c3_w* buf_w = malloc(4 * len_w);
u3_words(0, len_w, buf_w, veb);
mur_w = u3_mur_words(buf_w, len_w);
free(buf_w);
}
*u3_at_dog_mur(veb) = mur_w;
return mur_w;
}
}
/* u3_mur_string():
**
** Compute the mur of `a`, LSB first.
*/
c3_w
u3_mur_string(const c3_c *a_c)
{
c3_w len_w = strlen(a_c);
c3_w wor_w = ((len_w + 3) >> 2);
c3_w* buf_w = alloca(4 * wor_w);
c3_w i_w;
for ( i_w = 0; i_w < wor_w; i_w++ ) { buf_w[i_w] = 0; }
for ( i_w = 0; i_w < len_w; i_w++ ) {
c3_w inx_w = (i_w >> 2);
c3_w byt_w = (i_w & 3);
buf_w[inx_w] |= (a_c[i_w] << (8 * byt_w));
}
return u3_mur_words(buf_w, wor_w);
}
/* u3_mur_cell():
**
** Compute the mur of the cell `[hed tel]`.
*/
c3_w
u3_mur_cell(u3_noun hed,
u3r_mug_cell(u3_noun hed,
u3_noun tel)
{
c3_w lus_w = u3_mur(hed);
c3_w biq_w = u3_mur(tel);
c3_w lus_w = u3r_mug(hed);
c3_w biq_w = u3r_mug(tel);
return u3_mur_both(lus_w, biq_w);
return u3r_mug_both(lus_w, biq_w);
}
/* u3_mur_trel():
**
** Compute the mur of `[a b c]`.
*/
c3_w
u3_mur_trel(u3_noun a,
u3_noun b,
u3_noun c)
// mugframe: head and tail mugs of veb, 0 if uncalculated
//
typedef struct mugframe
{
return u3_mur_both(u3_mur(a), u3_mur_both(u3_mur(b), u3_mur(c)));
}
u3_noun veb;
c3_w a;
c3_w b;
} mugframe;
/* u3_mur_qual():
**
** Compute the mur of `[a b c d]`.
*/
c3_w
u3_mur_qual(u3_noun a,
u3_noun b,
u3_noun c,
u3_noun d)
static inline mugframe*
_mug_push(c3_ys mov, c3_ys off, u3_noun veb)
{
return u3_mur_both(u3_mur(a),
u3_mur_both(u3_mur(b),
u3_mur_both(u3_mur(c), u3_mur(d))));
}
#endif
u3R->cap_p += mov;
// ensure we haven't overflowed the stack
// (off==0 means we're on a north road)
//
if ( 0 == off ) {
c3_assert(u3R->cap_p > u3R->hat_p);
}
else {
c3_assert(u3R->cap_p < u3R->hat_p);
}
mugframe* cur = u3to(mugframe, u3R->cap_p + off);
cur->veb = veb;
cur->a = 0;
cur->b = 0;
return cur;
}
static inline mugframe*
_mug_pop(c3_ys mov, c3_ys off, c3_w mug_w)
{
u3R->cap_p -= mov;
mugframe* fam = u3to(mugframe, u3R->cap_p + off);
// the bottom of the stack
//
if ( u3_none == fam->veb ) {
return fam;
}
// place return value in head of previous frame if not already calculated
//
if ( 0 == fam->a ) {
fam->a = mug_w;
}
// otherwise, place the return value in the tail
//
else if ( 0 == fam->b ) {
fam->b = mug_w;
}
// shouldn't reach
//
else {
c3_assert(0);
}
return fam;
}
// _mug_cat(): return the mug of a direct atom
//
static c3_w
_mug_cat(u3_atom veb)
{
c3_w len_w = u3r_met(3, veb);
return u3r_mug_bytes((c3_y*)&veb, len_w);
}
/* _mug_pug(): statefully mug an indirect atom
*/
static c3_w
_mug_pug(u3_atom veb)
{
u3a_atom* vat_u = (u3a_atom*)(u3a_to_ptr(veb));
c3_w len_w = u3r_met(3, veb);
c3_w mug_w = u3r_mug_bytes((c3_y*)vat_u->buf_w, len_w);
vat_u->mug_w = mug_w;
return mug_w;
}
/* _mug_atom(): mug an atom, either direct or indirect
*/
static c3_w
_mug_atom(u3_atom veb)
{
if ( _(u3a_is_cat(veb)) ) {
return _mug_cat(veb);
}
else {
return _mug_pug(veb);
}
}
// u3r_mug(): statefully mug a noun using a 31-bit MurmurHash3
//
c3_w
u3r_mug(u3_noun veb)
{
c3_assert( u3_none != veb );
if ( _(u3a_is_atom(veb)) ) {
return _mug_atom(veb);
}
c3_y wis_y = c3_wiseof(mugframe);
c3_o nor_o = u3a_is_north(u3R);
c3_ys mov = ( c3y == nor_o ? -wis_y : wis_y );
c3_ys off = ( c3y == nor_o ? 0 : -wis_y );
// stash the current stack pointer
//
u3p(mugframe) empty = u3R->cap_p;
// set the bottom of our stack
//
mugframe* don = _mug_push(mov, off, u3_none);
mugframe* fam = _mug_push(mov, off, veb);
c3_w mug_w;
c3_w a;
c3_w b;
u3a_noun* veb_u;
u3_noun hed, tal;
while ( don != fam ) {
a = fam->a;
b = fam->b;
veb = fam->veb;
veb_u = u3a_to_ptr(veb);
c3_assert(_(u3a_is_cell(veb)));
// already mugged; pop stack
//
if ( veb_u->mug_w ) {
mug_w = veb_u->mug_w;
fam = _mug_pop(mov, off, mug_w);
}
// neither head nor tail are mugged; start with head
//
else if ( 0 == a ) {
hed = u3h(veb);
if ( _(u3a_is_atom(hed)) ) {
fam->a = _mug_atom(hed);
}
else {
fam = _mug_push(mov, off, hed);
}
}
// head is mugged, but not tail; mug tail or push tail onto stack
//
else if ( 0 == b ) {
tal = u3t(veb);
if ( _(u3a_is_atom(tal)) ) {
fam->b = _mug_atom(tal);
}
else {
fam = _mug_push(mov, off, tal);
}
}
// both head and tail are mugged; combine them and pop stack
//
else {
mug_w = u3r_mug_both(a, b);
veb_u->mug_w = mug_w;
fam = _mug_pop(mov, off, mug_w);
}
}
u3R->cap_p = empty;
return mug_w;
}

View File

@ -4,9 +4,9 @@
#include <stdio.h>
#include "all.h"
#define _CVX_WISH 4
#define _CVX_POKE 10
#define _CVX_PEEK 47
#define _CVX_WISH 22
#define _CVX_POKE 47
#define _CVX_PEEK 46
int WISH;
/* _cv_nock_wish(): call wish through hardcoded interface.

105
tests/hash_tests.c Normal file
View File

@ -0,0 +1,105 @@
#include "all.h"
/* _setup(): prepare for tests.
*/
static void
_setup(void)
{
u3m_init(c3y);
u3m_pave(c3y, c3n);
}
/* _test_mug(): spot check u3r_mug hashes.
*/
static void
_test_mug(void)
{
if ( 0x4d441035 != u3r_mug_string("Hello, world!") ) {
fprintf(stderr, "fail (a)\r\n");
exit(1);
}
if ( 0x4d441035 != u3r_mug(u3i_string("Hello, world!")) ) {
fprintf(stderr, "fail (b)\r\n");
exit(1);
}
if ( 0x79ff04e8 != u3r_mug_bytes(0, 0) ) {
fprintf(stderr, "fail (c)\r\n");
exit(1);
}
if ( 0x64dfda5c != u3r_mug(u3i_string("xxxxxxxxxxxxxxxxxxxxxxxxxxxx")) ) {
fprintf(stderr, "fail (d)\r\n");
exit(1);
}
if ( 0x389ca03a != u3r_mug_cell(0, 0) ) {
fprintf(stderr, "fail (e)\r\n");
exit(1);
}
if ( 0x389ca03a != u3r_mug_cell(1, 1) ) {
fprintf(stderr, "fail (f)\r\n");
exit(1);
}
if ( 0x5258a6c0 != u3r_mug_cell(0, u3qc_bex(32)) ) {
fprintf(stderr, "fail (g)\r\n");
exit(1);
}
if ( 0x2ad39968 != u3r_mug_cell(u3qa_dec(u3qc_bex(128)), 1) ) {
fprintf(stderr, "fail (h)\r\n");
exit(1);
}
{
// stick some zero bytes in a string
//
u3_noun str = u3kc_lsh(3, 1,
u3kc_mix(u3qc_bex(212),
u3i_string("abcdefjhijklmnopqrstuvwxyz")));
c3_w byt_w = u3r_met(3, str);
c3_w wor_w = u3r_met(5, str);
c3_y* str_y = c3_malloc(byt_w);
c3_w* str_w = c3_malloc(4 * wor_w);
c3_d str_d = 0;
u3r_bytes(0, byt_w, str_y, str);
u3r_words(0, wor_w, str_w, str);
str_d |= str_w[0];
str_d |= ((c3_d)str_w[1] << 32ULL);
if ( 0x34d08717 != u3r_mug(str) ) {
fprintf(stderr, "fail (i) (1) \r\n");
exit(1);
}
if ( 0x34d08717 != u3r_mug_bytes(str_y, byt_w) ) {
fprintf(stderr, "fail (i) (2)\r\n");
exit(1);
}
if ( 0x34d08717 != u3r_mug_words(str_w, wor_w) ) {
fprintf(stderr, "fail (i) (3)\r\n");
exit(1);
}
if ( u3r_mug_words(str_w, 2) != u3r_mug_chub(str_d) ) {
fprintf(stderr, "fail (i) (4)\r\n");
exit(1);
}
}
}
/* main(): run all test cases.
*/
int
main(int argc, char* argv[])
{
_setup();
_test_mug();
return 0;
}

View File

@ -1,15 +1,9 @@
/* v/http.c
/* vere/ames.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
@ -420,7 +414,7 @@ _ames_io_start()
uL(fprintf(uH,
" ...perhaps you've got two copies of vere running?\n"));
}
exit(1);
u3_lo_bail();
}
uv_udp_getsockname(&sam_u->wax_u, (struct sockaddr *)&add_u, &add_i);

View File

@ -1,17 +1,10 @@
/* v/behn.c
/* vere/behn.c
**
** This file is in the public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <dirent.h>
#include <stdint.h>
#include <uv.h>
#include <curses.h>
#include <termios.h>

View File

@ -1,19 +1,16 @@
/* v/cttp.c
/* vere/cttp.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include <openssl/ssl.h>
#include <h2o.h>
#include "all.h"
#include "vere/vere.h"

View File

@ -2,12 +2,46 @@
**
** ethereum-integrated pre-boot validation
*/
#include <unistd.h>
#include <curl/curl.h>
#include <uv.h>
#include "all.h"
#include "vere/vere.h"
/* _dawn_oct_to_buf(): +octs to uv_buf_t
*/
static uv_buf_t
_dawn_oct_to_buf(u3_noun oct)
{
if ( c3n == u3a_is_cat(u3h(oct)) ) {
u3_lo_bail();
}
c3_w len_w = u3h(oct);
c3_y* buf_y = c3_malloc(1 + len_w);
buf_y[len_w] = 0;
u3r_bytes(0, len_w, buf_y, u3t(oct));
u3z(oct);
return uv_buf_init((void*)buf_y, len_w);
}
/* _dawn_buf_to_oct(): uv_buf_t to +octs
*/
static u3_noun
_dawn_buf_to_oct(uv_buf_t buf_u)
{
u3_noun len = u3i_words(1, (c3_w*)&buf_u.len);
if ( c3n == u3a_is_cat(len) ) {
u3_lo_bail();
}
return u3nc(len, u3i_bytes(buf_u.len, (const c3_y*)buf_u.base));
}
/* _dawn_curl_alloc(): allocate a response buffer for curl
*/
static size_t
@ -74,37 +108,51 @@ _dawn_post_json(c3_c* url_c, uv_buf_t lod_u)
return buf_u;
}
/* _dawn_oct_to_buf(): +octs to uv_buf_t
*/
static uv_buf_t
_dawn_oct_to_buf(u3_noun oct)
{
if ( c3n == u3a_is_cat(u3h(oct)) ) {
u3_lo_bail();
}
c3_w len_w = u3h(oct);
c3_y* buf_y = c3_malloc(1 + len_w);
buf_y[len_w] = 0;
u3r_bytes(0, len_w, buf_y, u3t(oct));
u3z(oct);
return uv_buf_init((void*)buf_y, len_w);
}
/* _dawn_buf_to_oct(): uv_buf_t to +octs
/* _dawn_get_jam(): GET a jammed noun from url_c
*/
static u3_noun
_dawn_buf_to_oct(uv_buf_t buf_u)
_dawn_get_jam(c3_c* url_c)
{
u3_noun len = u3i_words(1, (c3_w*)&buf_u.len);
CURL *curl;
CURLcode result;
long cod_l;
if ( c3n == u3a_is_cat(len) ) {
uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0);
if ( !(curl = curl_easy_init()) ) {
fprintf(stderr, "failed to initialize libcurl\n");
u3_lo_bail();
}
return u3nc(len, u3i_bytes(buf_u.len, (const c3_y*)buf_u.base));
// XX require TLS, pin default cert?
curl_easy_setopt(curl, CURLOPT_URL, url_c);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _dawn_curl_alloc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
result = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &cod_l);
// XX retry?
if ( CURLE_OK != result ) {
fprintf(stderr, "failed to fetch %s: %s\n",
url_c, curl_easy_strerror(result));
u3_lo_bail();
}
if ( 300 <= cod_l ) {
fprintf(stderr, "error fetching %s: HTTP %ld\n", url_c, cod_l);
u3_lo_bail();
}
curl_easy_cleanup(curl);
// throw away the length from the octs
//
u3_noun octs = _dawn_buf_to_oct(buf_u);
u3_noun jammed = u3k(u3t(octs));
u3z(octs);
return u3ke_cue(jammed);
}
/* _dawn_eth_rpc(): ethereum JSON RPC with request/response as +octs
@ -249,7 +297,7 @@ _dawn_turf(c3_c* dns_c)
return tuf;
}
/* u3_dawn_vent(): validatated boot event
/* u3_dawn_vent(): validated boot event
*/
u3_noun
u3_dawn_vent(u3_noun seed)
@ -259,14 +307,23 @@ u3_dawn_vent(u3_noun seed)
u3_noun ship = u3h(seed);
u3_noun rank = u3do("clan:title", u3k(ship));
// load snapshot if exists
// load snapshot from file
//
if ( 0 != u3_Host.ops_u.ets_c ) {
fprintf(stderr, "boot: loading ethereum snapshot\r\n");
u3_noun raw_snap = u3ke_cue(u3m_file(u3_Host.ops_u.ets_c));
sap = u3nc(u3_nul, raw_snap);
}
// load snapshot from HTTP URL
//
else if ( 0 != u3_Host.ops_u.sap_c ) {
u3_noun raw_snap = _dawn_get_jam(u3_Host.ops_u.sap_c);
sap = u3nc(u3_nul, raw_snap);
}
// no snapshot
//
else {
printf("dawn: no ethereum snapshot specified\n");
sap = u3_nul;
}
@ -276,7 +333,7 @@ u3_dawn_vent(u3_noun seed)
//
c3_c* url_c = ( 0 != u3_Host.ops_u.eth_c ) ?
u3_Host.ops_u.eth_c :
"https://ropsten.infura.io/v3/196a7f37c7d54211b4a07904ec73ad87";
"https://mainnet.infura.io/v3/196a7f37c7d54211b4a07904ec73ad87";
// pin block number
//
@ -299,7 +356,7 @@ u3_dawn_vent(u3_noun seed)
}
{
// +point:constitution:ethe: on-chain state
// +point:azimuth: on-chain state
//
u3_noun pot;
@ -313,7 +370,7 @@ u3_dawn_vent(u3_noun seed)
else if ( c3__pawn == rank ) {
// irrelevant, just bunt +point
//
pot = u3v_wish("*point:constitution:ethe");
pot = u3v_wish("*point:azimuth");
}
else {
u3_noun who;
@ -426,36 +483,12 @@ u3_dawn_vent(u3_noun seed)
return u3nc(c3__dawn, u3nq(seed, pon, zar, u3nq(tuf, bok, url, sap)));
}
/* u3_dawn_come(): mine a comet under star (unit)
/* _dawn_come(): mine a comet under a list of stars
*/
u3_noun
u3_dawn_come(u3_noun star)
static u3_noun
_dawn_come(u3_noun stars)
{
u3_noun seed;
if ( u3_nul == star ) {
// XX ~marzod hardcoded
// choose from list, at random, &c
//
star = 256;
}
else {
// XX parse and validate
//
u3_noun tar = u3k(u3t(star));
u3z(star);
star = tar;
}
{
u3_noun sar = u3dc("scot", 'p', u3k(star));
c3_c* tar_c = u3r_string(sar);
fprintf(stderr, "boot: mining a comet under %s\r\n", tar_c);
free(tar_c);
u3z(sar);
}
{
c3_w eny_w[16];
u3_noun eny;
@ -463,7 +496,10 @@ u3_dawn_come(u3_noun star)
c3_rand(eny_w);
eny = u3i_words(16, eny_w);
seed = u3dc("come:dawn", u3k(star), u3k(eny));
fprintf(stderr, "boot: mining a comet. May take up to an hour.\r\n");
fprintf(stderr, "If you want to boot faster, get an Azimuth point.\r\n");
seed = u3dc("come:dawn", u3k(stars), u3k(eny));
u3z(eny);
}
@ -476,7 +512,16 @@ u3_dawn_come(u3_noun star)
u3z(who);
}
u3z(star);
u3z(stars);
return seed;
}
/* u3_dawn_come(): mine a comet under a list of stars we download
*/
u3_noun
u3_dawn_come()
{
return _dawn_come(
_dawn_get_jam("https://bootstrap.urbit.org/comet-stars.jam"));
}

View File

@ -1,27 +1,23 @@
/* v/http.c
/* vere/http.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/err.h>
#include <h2o.h>
#include "all.h"
#include "vere/vere.h"
#include <picohttpparser.h>
#include <tls.h>
#include "all.h"
#include "vere/vere.h"
typedef struct _u3_h2o_serv {
h2o_globalconf_t fig_u; // h2o global config
h2o_context_t ctx_u; // h2o ctx
@ -41,6 +37,10 @@ static void _http_form_free(void);
static const c3_i TCP_BACKLOG = 16;
// XX temporary, add to u3_http_ef_form
//
#define PROXY_DOMAIN "arvo.network"
/* _http_vec_to_meth(): convert h2o_iovec_t to meth
*/
static u3_weak
@ -1904,22 +1904,32 @@ _proxy_warc_free(u3_warc* cli_u)
/* _proxy_warc_new(): allocate ship-specific proxy client
*/
static u3_warc*
_proxy_warc_new(u3_http* htp_u, u3_atom sip, c3_s por_s, c3_o sec)
_proxy_warc_new(u3_http* htp_u, u3_atom sip, u3_atom non, c3_s por_s, c3_o sec)
{
u3_warc* cli_u = c3_malloc(sizeof(*cli_u));
u3_warc* cli_u = c3_calloc(sizeof(*cli_u));
cli_u->htp_u = htp_u;
cli_u->por_s = por_s;
// XX set here instead of u3_http_ef_that() ?
cli_u->non_u = uv_buf_init(0, 0);
cli_u->sip = sip;
cli_u->sec = sec;
// XX set here instead of _proxy_ward_resolve() ?
cli_u->hot_c = 0;
cli_u->nex_u = 0;
cli_u->pre_u = 0;
u3r_chubs(0, 2, cli_u->who_d, sip);
_proxy_warc_link(cli_u);
{
c3_w len_w = u3r_met(3, non);
c3_assert( 256 > len_w );
c3_y* non_y = c3_malloc(1 + len_w);
non_y[0] = (c3_y)len_w;
u3r_bytes(0, len_w, non_y + 1, non);
cli_u->non_u = uv_buf_init((c3_c*)non_y, 1 + len_w);
}
u3z(non);
u3z(sip);
return cli_u;
}
@ -2385,7 +2395,6 @@ _proxy_ward_free(uv_handle_t* han_u)
{
u3_ward* rev_u = han_u->data;
u3z(rev_u->sip);
free(rev_u->non_u.base);
free(rev_u);
}
@ -2420,18 +2429,16 @@ _proxy_ward_close(u3_ward* rev_u)
static u3_ward*
_proxy_ward_new(u3_pcon* con_u, u3_atom sip)
{
u3_ward* rev_u = c3_malloc(sizeof(*rev_u));
u3_ward* rev_u = c3_calloc(sizeof(*rev_u));
rev_u->tcp_u.data = rev_u;
rev_u->tim_u.data = rev_u;
rev_u->con_u = con_u;
rev_u->sip = sip;
rev_u->por_s = 0; // set after opened
rev_u->won_u = 0;
rev_u->nex_u = 0;
rev_u->pre_u = 0;
u3r_chubs(0, 2, rev_u->who_d, sip);
_proxy_ward_link(con_u, rev_u);
u3z(sip);
return rev_u;
}
@ -2456,11 +2463,10 @@ _proxy_wcon_peek_read_cb(uv_stream_t* upt_u,
c3_w len_w = rev_u->non_u.len;
// XX await further reads if siz_w < len_w ?
if ( ((len_w + 1) != siz_w) ||
(len_w != buf_u->base[0]) ||
(0 != memcmp(rev_u->non_u.base, buf_u->base + 1, len_w)) ) {
uL(fprintf(uH, "proxy: ward auth fail\n"));
// uL(fprintf(uH, "proxy: ward auth fail\n"));
_proxy_wcon_unlink(won_u);
_proxy_wcon_close(won_u);
}
@ -2541,14 +2547,31 @@ _proxy_ward_timer_cb(uv_timer_t* tim_u)
static void
_proxy_ward_plan(u3_ward* rev_u)
{
u3_noun non;
{
c3_w* non_w = c3_malloc(64);
c3_w len_w;
c3_rand(non_w);
non = u3i_words(16, non_w);
len_w = u3r_met(3, non);
// the nonce is saved to authenticate u3_wcon
// and will be freed with u3_ward
//
rev_u->non_u = uv_buf_init((c3_c*)non_w, len_w);
}
// XX confirm duct
u3_noun pax = u3nq(u3_blip, c3__http, c3__prox,
u3nc(u3k(u3A->sen), u3_nul));
u3_noun wis = u3nc(c3__wise, u3nq(u3k(rev_u->sip),
u3_noun wis = u3nc(c3__wise, u3nq(u3i_chubs(2, rev_u->who_d),
rev_u->por_s,
u3k(rev_u->con_u->sec),
u3i_words(16, (c3_w*)rev_u->non_u.base)));
non));
u3v_plan(pax, wis);
}
@ -2557,7 +2580,7 @@ _proxy_ward_plan(u3_ward* rev_u)
static void
_proxy_ward_start(u3_pcon* con_u, u3_noun sip)
{
u3_ward* rev_u = _proxy_ward_new(con_u, sip);
u3_ward* rev_u = _proxy_ward_new(con_u, u3k(sip));
uv_tcp_init(u3L, &rev_u->tcp_u);
@ -2585,28 +2608,27 @@ _proxy_ward_start(u3_pcon* con_u, u3_noun sip)
rev_u->por_s = ntohs(add_u.sin_port);
#if 0
{
c3_w* non_w = c3_malloc(64);
c3_rand(non_w);
u3_noun non = u3i_words(16, non_w);
c3_w len_w = u3r_met(3, non);
rev_u->non_u = uv_buf_init((c3_c*)non_w, len_w);
u3z(non);
u3_noun who = u3dc("scot", 'p', u3k(sip));
c3_c* who_c = u3r_string(who);
fprintf(stderr, "\r\nward for %s started on %u\r\n", who_c, rev_u->por_s);
free(who_c);
u3z(who);
}
#endif
_proxy_ward_plan(rev_u);
uv_timer_init(u3L, &rev_u->tim_u);
// XX how long?
//
uv_timer_init(u3L, &rev_u->tim_u);
uv_timer_start(&rev_u->tim_u, _proxy_ward_timer_cb, 300 * 1000, 0);
// XX u3_lo_shut(c3y);
}
u3z(sip);
}
/* _proxy_ward_connect_cb(): ward connection callback
@ -2703,16 +2725,15 @@ _proxy_ward_resolve(u3_warc* cli_u)
hin_u.ai_socktype = SOCK_STREAM;
hin_u.ai_protocol = IPPROTO_TCP;
// XX why the conditional?
//
if ( 0 == cli_u->hot_c ) {
// XX revisit
c3_assert( 0 != u3_Host.sam_u.dns_c );
u3_noun sip = u3dc("scot", 'p', u3k(cli_u->sip));
u3_noun sip = u3dc("scot", 'p', u3i_chubs(2, cli_u->who_d));
c3_c* sip_c = u3r_string(sip);
c3_w len_w = 1 + strlen(sip_c) + strlen(u3_Host.sam_u.dns_c);
c3_w len_w = 1 + strlen(sip_c) + strlen(PROXY_DOMAIN);
cli_u->hot_c = c3_malloc(len_w);
// incremented to skip '~'
snprintf(cli_u->hot_c, len_w, "%s.%s", sip_c + 1, u3_Host.sam_u.dns_c);
snprintf(cli_u->hot_c, len_w, "%s.%s", sip_c + 1, PROXY_DOMAIN);
free(sip_c);
u3z(sip);
@ -2806,37 +2827,42 @@ _proxy_parse_sni(const uv_buf_t* buf_u, c3_c** hot_c)
return u3_pars_good;
}
/* _proxy_parse_ship(): determine destination for proxied request
/* _proxy_parse_ship(): determine destination (unit ship) for proxied request
*/
static u3_noun
_proxy_parse_ship(c3_c* hot_c)
{
u3_noun sip = u3_nul;
c3_c* dom_c;
if ( 0 == hot_c ) {
return sip;
return u3_nul;
}
dom_c = strchr(hot_c, '.');
else {
c3_c* dom_c = strchr(hot_c, '.');
if ( 0 == dom_c ) {
return sip;
return u3_nul;
}
// XX revisit
c3_assert( 0 != u3_Host.sam_u.dns_c );
else {
// length of the first subdomain
//
c3_w dif_w = dom_c - hot_c;
c3_w dns_w = strlen(u3_Host.sam_u.dns_c);
if ( (dns_w != strlen(hot_c) - (dif_w + 1)) ||
(0 != strncmp(dom_c + 1, u3_Host.sam_u.dns_c, dns_w)) ) {
return sip;
}
c3_w dns_w = strlen(PROXY_DOMAIN);
// validate that everything after the first subdomain
// matches the proxy domain
// (skipped if networking is disabled)
//
if ( (c3y == u3_Host.ops_u.net) &&
( (dns_w != strlen(hot_c) - (dif_w + 1)) ||
(0 != strncmp(dom_c + 1, PROXY_DOMAIN, dns_w)) ) )
{
return u3_nul;
}
else {
// attempt to parse the first subdomain as a @p
//
u3_noun sip;
c3_c* sip_c = c3_malloc(2 + dif_w);
strncpy(sip_c + 1, hot_c, dif_w);
sip_c[0] = '~';
sip_c[1 + dif_w] = 0;
@ -2846,6 +2872,8 @@ _proxy_parse_ship(c3_c* hot_c)
return sip;
}
}
}
}
/* _proxy_dest(): proxy to destination
@ -2863,9 +2891,9 @@ _proxy_dest(u3_pcon* con_u, u3_noun sip)
_proxy_loop_connect(con_u);
}
else {
// XX check if (sein:title sip) == our
// XX check will
// XX extract bytes from hip, this could leak
// XX we should u3v_peek %j /=sein= to confirm
// that we're sponsoring this ship
//
_proxy_ward_start(con_u, u3k(hip));
}
}
@ -3107,10 +3135,8 @@ u3_http_ef_that(u3_noun tat)
!( c3y == sec || c3n == sec ) ||
( c3n == u3ud(non) ) ) {
uL(fprintf(uH, "http: that: invalid card\n"));
u3z(tat);
return;
}
else {
u3_http* htp_u;
u3_warc* cli_u;
@ -3120,37 +3146,28 @@ u3_http_ef_that(u3_noun tat)
}
}
// XX we should inform our sponsor if we aren't running a server
// so this situation can be avoided
//
if ( 0 == htp_u ) {
uL(fprintf(uH, "http: that: no %s server\n", (c3y == sec) ?
"secure" : "insecure"));
u3z(tat);
return;
}
else {
cli_u = _proxy_warc_new(htp_u, (u3_atom)u3k(sip), (u3_atom)u3k(non),
(c3_s)por, (c3_o)sec);
// XX extract bytes from sip, this could leak
cli_u = _proxy_warc_new(htp_u, (u3_atom)sip, (c3_s)por, (c3_o)sec);
// XX add to constructor
c3_w len_w = u3r_met(3, non);
c3_assert( 256 > len_w );
c3_y* non_y = c3_malloc(1 + len_w);
non_y[0] = (c3_y)len_w;
u3r_bytes(0, len_w, non_y + 1, non);
cli_u->non_u = uv_buf_init((c3_c*)non_y, 1 + len_w);
// resolve to loopback if networking is disabled
//
if ( c3n == u3_Host.ops_u.net ) {
cli_u->ipf_w = INADDR_LOOPBACK;
_proxy_ward_connect(cli_u);
u3z(tat);
return;
}
else {
_proxy_ward_resolve(cli_u);
}
}
}
u3z(tat);
}

View File

@ -1,17 +1,11 @@
/* v/loop.c
/* vere/loop.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>

View File

@ -1,16 +1,9 @@
/* v/main.c
/* vere/main.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <gmp.h>
#include <stdint.h>
#include <limits.h>
#include <uv.h>
#include <sigsegv.h>
@ -20,8 +13,7 @@
#include <dirent.h>
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include "h2o.h"
#include <h2o.h>
#define U3_GLOBAL
#define C3_GLOBAL
@ -75,12 +67,16 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.abo = c3n;
u3_Host.ops_u.bat = c3n;
u3_Host.ops_u.can = c3n;
u3_Host.ops_u.dem = c3n;
u3_Host.ops_u.dry = c3n;
u3_Host.ops_u.etn = c3n;
u3_Host.ops_u.gab = c3n;
u3_Host.ops_u.git = c3n;
u3_Host.ops_u.has = c3n;
// always disable hashboard
// XX temporary, remove once hashes are added
//
u3_Host.ops_u.has = c3y;
u3_Host.ops_u.net = c3y;
u3_Host.ops_u.nuu = c3n;
u3_Host.ops_u.pro = c3n;
@ -94,7 +90,9 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.raf_c = 0;
u3_Host.ops_u.nam_c = 0;
while ( (ch_i=getopt(argc, argv,"G:B:K:A:H:w:u:j:e:E:f:F:k:p:LabcdgqstvxPDRS")) != -1 ) {
while ( -1 != (ch_i=getopt(argc, argv,
"G:B:K:A:H:w:u:j:e:E:f:F:k:m:p:LabcCdgqstvxPDRS")) ) {
switch ( ch_i ) {
case 'B': {
u3_Host.ops_u.pil_c = strdup(optarg);
@ -157,6 +155,10 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.key_c = strdup(optarg);
break;
}
case 'm': {
u3_Host.ops_u.sap_c = strdup(optarg);
break;
}
case 'p': {
if ( c3n == _main_readw(optarg, 65536, &arg_w) ) {
return c3n;
@ -171,6 +173,7 @@ _main_getopt(c3_i argc, c3_c** argv)
case 'a': { u3_Host.ops_u.abo = c3y; break; }
case 'b': { u3_Host.ops_u.bat = c3y; break; }
case 'c': { u3_Host.ops_u.nuu = c3y; break; }
case 'C': { u3_Host.ops_u.can = c3y; break; }
case 'd': { u3_Host.ops_u.dem = c3y; break; }
case 'g': { u3_Host.ops_u.gab = c3y; break; }
case 'P': { u3_Host.ops_u.pro = c3y; break; }
@ -207,18 +210,6 @@ _main_getopt(c3_i argc, c3_c** argv)
c3_t imp_t = ( (0 != u3_Host.ops_u.who_c) && (4 == strlen(u3_Host.ops_u.who_c)) );
if ( u3_Host.ops_u.ets_c == 0 && c3y == u3_Host.ops_u.etn ) {
fprintf(stderr, "can't trust Ethereum snapshot without specifying "
"snapshot with -E\n");
return c3n;
}
if ( (0 == u3_Host.ops_u.fak_c) && (0 == u3_Host.ops_u.eth_c) && imp_t ) {
fprintf(stderr, "can't create a new galaxy without specifying "
"the Ethereum gateway with -e\n");
return c3n;
}
if ( u3_Host.ops_u.gen_c != 0 && u3_Host.ops_u.nuu == c3n ) {
fprintf(stderr, "-G only makes sense when bootstrapping a new instance\n");
return c3n;
@ -247,12 +238,51 @@ _main_getopt(c3_i argc, c3_c** argv)
if ( u3_Host.ops_u.nuu != c3y && u3_Host.ops_u.url_c != 0 ) {
fprintf(stderr, "-u only makes sense when bootstrapping a new instance\n");
return c3n;
}
if ( u3_Host.ops_u.nuu != c3y && u3_Host.ops_u.sap_c != 0 ) {
fprintf(stderr, "-m only makes sense when bootstrapping a new instance\n");
return c3n;
}
if ( u3_Host.ops_u.fak_c != 0 && u3_Host.ops_u.sap_c != 0 ) {
fprintf(stderr, "-m and -F cannot be used together\n");
return c3n;
}
if ( u3_Host.ops_u.ets_c != 0 && u3_Host.ops_u.sap_c != 0 ) {
fprintf(stderr, "-m and -E cannot be used together\n");
return c3n;
}
if ( u3_Host.ops_u.can == c3y && u3_Host.ops_u.sap_c != 0 ) {
fprintf(stderr, "-m and -C cannot be used together\n");
return c3n;
}
if ( u3_Host.ops_u.can == c3y && u3_Host.ops_u.ets_c != 0 ) {
fprintf(stderr, "-C and -E cannot be used together\n");
return c3n;
}
if ( u3_Host.ops_u.eth_c == 0 && imp_t ) {
u3_Host.ops_u.eth_c = "http://eth-mainnet.urbit.org:8545";
}
if ( u3_Host.ops_u.sap_c == 0 && u3_Host.ops_u.can == c3n ) {
u3_Host.ops_u.sap_c =
"https://bootstrap.urbit.org/urbit-" URBIT_VERSION ".snap";
}
if ( u3_Host.ops_u.url_c != 0 && u3_Host.ops_u.pil_c != 0 ) {
fprintf(stderr, "-B and -u cannot be used together\n");
return c3n;
} else if ( u3_Host.ops_u.nuu == c3y
&& u3_Host.ops_u.url_c == 0
&& u3_Host.ops_u.git == c3n ) {
u3_Host.ops_u.url_c = "https://bootstrap.urbit.org/urbit-" URBIT_VERSION ".pill";
u3_Host.ops_u.url_c =
"https://bootstrap.urbit.org/urbit-" URBIT_VERSION ".pill";
} else if ( u3_Host.ops_u.nuu == c3y
&& u3_Host.ops_u.url_c == 0
@ -325,7 +355,7 @@ u3_ve_usage(c3_i argc, c3_c** argv)
"where ship_name is a @p phonetic representation of an urbit address\n",
"without the leading '~', and options is some subset of the following:\n",
"\n",
"-A dir Use dir for initial galaxy sync\n",
"-A dir Use dir for initial arvo sync\n",
"-B pill Bootstrap from this pill\n",
"-b Batch create\n",
"-c pier Create a new urbit in pier/\n",
@ -358,8 +388,8 @@ u3_ve_usage(c3_i argc, c3_c** argv)
" https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md\n",
"\n",
"Simple Usage: \n",
" %s -c <mycomet> to create a comet (anonymous urbit)\n",
" %s -w <myplanet> -t <myticket> if you have a ticket\n",
" %s -c <my-comet> to create a comet (anonymous urbit)\n",
" %s -w <my-planet> -k <my-key-file> if you own a planet\n",
" %s <myplanet or mycomet> to restart an existing urbit\n",
0
};
@ -544,11 +574,35 @@ main(c3_i argc,
printf("~\n");
// printf("welcome.\n");
printf("urbit %s\n", URBIT_VERSION);
printf("urbit: home is %s\n", u3_Host.dir_c);
// 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) ) {
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);
free(abs_c);
} else {
printf("boot: home is %s\n", abs_c);
free(abs_c);
}
// printf("vere: hostname is %s\n", u3_Host.ops_u.nam_c);
if ( c3y == u3_Host.ops_u.dem && c3n == u3_Host.ops_u.bat ) {
printf("urbit: running as daemon\n");
printf("boot: running as daemon\n");
}
// Seed prng. Don't panic -- just for fuzz testing.

View File

@ -1,10 +1,6 @@
/* v/raft.c
/* vere/raft.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <uv.h>
#include "all.h"

View File

@ -1,17 +1,10 @@
/* v/reck.c
/* vere/reck.c
**
** This file is in the public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <dirent.h>
#include <stdint.h>
#include <uv.h>
#include <curses.h>
#include <termios.h>

View File

@ -1,16 +1,10 @@
/* v/save.c
/* vere/save.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <stdint.h>
#include <termios.h>
#include <uv.h>

View File

@ -1,23 +1,13 @@
/* v/sist.c
/* vere/sist.c
**
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <uv.h>
#include "all.h"
#include "vere/vere.h"
#if defined(U3_OS_linux)
#define DEVRANDOM "/dev/urandom"
#else
#define DEVRANDOM "/dev/random"
#endif
/* u3_sist_pack(): write a blob to disk, transferring.
*/
c3_d
@ -31,24 +21,24 @@ u3_sist_pack(c3_w tem_w, c3_w typ_w, c3_w* bob_w, c3_w len_w)
lar_u.tem_w = tem_w;
lar_u.typ_w = typ_w;
lar_u.syn_w = u3r_mug_d(tar_d);
lar_u.syn_w = u3r_mug_chub(tar_d);
lar_u.mug_w = u3r_mug_both(u3r_mug_words(bob_w, len_w),
u3r_mug_both(u3r_mug(lar_u.tem_w),
u3r_mug(lar_u.typ_w)));
u3r_mug_both(u3r_mug_words(&lar_u.tem_w, 1),
u3r_mug_words(&lar_u.typ_w, 1)));
lar_u.ent_d = u3A->ent_d;
u3A->ent_d++;
lar_u.len_w = len_w;
if ( -1 == lseek64(lug_u->fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "sist_pack: seek failed, lseek: %s\n", strerror(errno)));
uL(fprintf(uH, "sist: seek failed, lseek: %s\n", strerror(errno)));
c3_assert(0);
}
if ( sizeof(lar_u) != write(lug_u->fid_i, &lar_u, sizeof(lar_u)) ) {
uL(fprintf(uH, "sist_pack: write failed, write: %s\n", strerror(errno)));
uL(fprintf(uH, "sist: write failed, write: %s\n", strerror(errno)));
c3_assert(0);
}
if ( -1 == lseek64(lug_u->fid_i, 4ULL * lug_u->len_d, SEEK_SET) ) {
uL(fprintf(uH, "sist_pack: seek failed, lseek: %s\n", strerror(errno)));
uL(fprintf(uH, "sist: seek failed, lseek: %s\n", strerror(errno)));
c3_assert(0);
}
#if 0
@ -60,7 +50,7 @@ u3_sist_pack(c3_w tem_w, c3_w typ_w, c3_w* bob_w, c3_w len_w)
lar_u.mug_w));
#endif
if ( (4 * len_w) != write(lug_u->fid_i, bob_w, (4 * len_w)) ) {
uL(fprintf(uH, "sist_pack: write failed, write: %s\n", strerror(errno)));
uL(fprintf(uH, "sist: write failed, write: %s\n", strerror(errno)));
c3_assert(0);
}
lug_u->len_d += (c3_d)(lar_u.len_w + c3_wiseof(lar_u));
@ -268,16 +258,18 @@ _sist_sing(u3_noun ovo)
/* _sist_cask(): ask for a passcode.
*/
static u3_noun
_sist_cask(c3_c* dir_c, u3_noun nun)
_sist_cask(c3_c* dir_c)
{
c3_c paw_c[60];
u3_noun key;
c3_c paw_c[60];
u3_utty* uty_u = c3_calloc(sizeof(u3_utty));
uty_u->fid_i = 0;
uH;
// disable terminal echo when typing in passcode
//
if ( 0 != tcgetattr(uty_u->fid_i, &uty_u->bak_u) ) {
c3_assert(!"init-tcgetattr");
}
@ -288,50 +280,59 @@ _sist_cask(c3_c* dir_c, u3_noun nun)
}
while ( 1 ) {
printf("passcode for %s%s? ~", dir_c, (c3y == nun) ? " [none]" : "");
printf("passcode for %s? ~", dir_c);
paw_c[0] = 0;
c3_fpurge(stdin);
fgets(paw_c, 59, stdin);
printf("\n");
if ( '\n' == paw_c[0] ) {
if ( c3y == nun ) {
key = 0; break;
// exit on EOF (ie, ctrl-d)
//
if ( 0 == paw_c[0]) {
u3_lo_bail();
}
else {
// re-prompt on early return
//
if ( '\n' == paw_c[0] ) {
continue;
}
}
else {
c3_c* say_c = c3_malloc(strlen(paw_c) + 2);
{
c3_c* say_c = c3_malloc(2 + strlen(paw_c));
u3_noun say;
if ( '~' == paw_c[0] ) {
say_c[0] = 0;
}
else {
say_c[0] = '~';
say_c[1] = 0;
}
strncat(say_c, paw_c, strlen(paw_c) - 1);
say = u3do("slay", u3i_string(say_c));
say = u3dc("slaw", 'p', u3i_string(say_c));
free(say_c);
if ( (u3_nul == say) ||
(u3_blip != u3h(u3t(say))) ||
('p' != u3h(u3t(u3t(say)))) )
{
if ( u3_nul == say ) {
printf("invalid passcode\n");
continue;
}
key = u3k(u3t(u3t(u3t(say))));
key = u3k(u3t(say));
u3z(say);
break;
}
}
if ( 0 != tcsetattr(uty_u->fid_i, TCSADRAIN, &uty_u->bak_u) ) {
c3_assert(!"init-tcsetattr");
}
free(uty_u);
uL(0);
return key;
}
@ -400,23 +401,15 @@ _sist_bask(c3_c* pop_c, u3_noun may)
}
#endif
/* u3_sist_rand(): fill a 512-bit (16-word) buffer.
/* c3_rand(): fill a 512-bit (16-word) buffer.
*/
void
u3_sist_rand(c3_w* rad_w)
c3_rand(c3_w* rad_w)
{
#if defined(U3_OS_bsd) && defined(__OpenBSD__)
if (-1 == getentropy(rad_w, 64)) {
c3_assert(!"lo_rand");
if ( 0 != c3_getentropy(rad_w, 64) ) {
uL(fprintf(uH, "c3_rand getentropy: %s\n", strerror(errno)));
u3_lo_bail();
}
#else
c3_i fid_i = open(DEVRANDOM, O_RDONLY);
if ( 64 != read(fid_i, (c3_y*) rad_w, 64) ) {
c3_assert(!"lo_rand");
}
close(fid_i);
#endif
}
/* _sist_fast(): offer to save passcode by mug in home directory.
@ -431,8 +424,8 @@ _sist_fast(u3_noun pas, c3_l key_l)
u3_noun yek = u3dc("scot", 'p', pas);
c3_c* yek_c = u3r_string(yek);
printf("saving passcode in %s/.urb/code.%s\r\n", hom_c, gum_c);
printf("(for real security, write it down and delete the file...)\r\n");
printf("boot: saving passcode in %s/.urb/code.%s\r\n", hom_c, gum_c);
printf("boot: for more security, write it down and delete the file\r\n");
{
c3_i fid_i;
@ -485,7 +478,7 @@ _sist_staf(c3_l key_l)
u3z(say);
return 0;
}
uL(fprintf(uH, "loaded passcode from %s\n", ful_c));
uL(fprintf(uH, "boot: loaded passcode from %s\n", ful_c));
pas = u3k(u3t(u3t(u3t(say))));
u3z(say);
@ -530,7 +523,7 @@ _sist_zest()
if ( ((fid_i = open(ful_c, pig_i, 0600)) < 0) ||
(fstat(fid_i, &buf_b) < 0) )
{
uL(fprintf(uH, "can't create record (%s)\n", ful_c));
uL(fprintf(uH, "zest: can't create record (%s)\n", ful_c));
u3_lo_bail();
}
#ifdef F_NOCACHE
@ -604,7 +597,7 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
c3_assert(led_u.mag_l == u3r_mug('f'));
if ( -1 == lseek64(fid_i, 4ULL * end_d, SEEK_SET) ) {
uL(fprintf(uH, "rest_nuu failed (a), lseek64: %s\n", strerror(errno)));
uL(fprintf(uH, "rest: rest_nuu failed (a), lseek64: %s\n", strerror(errno)));
u3_lo_bail();
}
@ -625,7 +618,7 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
u3_lo_bail();
}
if ( lar_u.syn_w != u3r_mug_d(tar_d) ) {
if ( lar_u.syn_w != u3r_mug_chub(tar_d) ) {
uL(fprintf(uH, "rest_nuu failed (d)\n"));
u3_lo_bail();
}
@ -690,9 +683,10 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
lar_u.ent_d = ent_d;
lar_u.tem_w = 0;
lar_u.typ_w = c3__ov;
lar_u.mug_w = u3r_mug_both(u3r_mug(ovo),
u3r_mug_both(u3r_mug(0),
u3r_mug(c3__ov)));
u3_noun moo = u3nt(u3k(ovo), u3_nul, c3__ov);
lar_u.mug_w = u3r_mug(moo);
u3z(moo);
img_w = c3_malloc(lar_u.len_w << 2);
u3r_words(0, lar_u.len_w, img_w, ovo);
@ -780,7 +774,7 @@ _sist_rest()
u3_uled led_u;
if ( sizeof(led_u) != read(fid_i, &led_u, sizeof(led_u)) ) {
uL(fprintf(uH, "record (%s) is corrupt (a)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (a)\n", ful_c));
u3_lo_bail();
}
@ -825,12 +819,12 @@ _sist_rest()
u3_noun key;
while ( 1 ) {
pas = pas ? pas : _sist_cask(u3_Host.dir_c, c3n);
pas = pas ? pas : _sist_cask(u3_Host.dir_c);
key = _sist_fatt(sal_l, pas);
if ( u3r_mug(key) != key_l ) {
uL(fprintf(uH, "incorrect passcode\n"));
uL(fprintf(uH, "rest: incorrect passcode\n"));
u3z(key);
pas = 0;
}
@ -855,7 +849,7 @@ _sist_rest()
if ( -1 == lseek64(fid_i, 4ULL * end_d, SEEK_SET) ) {
uL(fprintf(uH, "end_d %" PRIu64 ", lseek64: %s\n", end_d,
strerror(errno)));
uL(fprintf(uH, "record (%s) is corrupt (c)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (c)\n", ful_c));
u3_lo_bail();
}
@ -868,25 +862,25 @@ _sist_rest()
// uL(fprintf(uH, "rest: reading event at %" PRIx64 "\n", end_d));
if ( -1 == lseek64(fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "record (%s) is corrupt (d)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (d)\n", ful_c));
u3_lo_bail();
}
if ( sizeof(u3_ular) != read(fid_i, &lar_u, sizeof(u3_ular)) ) {
uL(fprintf(uH, "record (%s) is corrupt (e)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (e)\n", ful_c));
u3_lo_bail();
}
if ( lar_u.syn_w != u3r_mug_d(tar_d) ) {
if ( lar_u.syn_w != u3r_mug_chub(tar_d) ) {
if ( c3n == rup ) {
uL(fprintf(uH, "corruption detected; attempting to fix\n"));
uL(fprintf(uH, "rest: corruption detected; attempting to fix\n"));
rup = c3y;
}
uL(fprintf(uH, "lar:%x mug:%x\n", lar_u.syn_w, u3r_mug_d(tar_d)));
uL(fprintf(uH, "lar:%x mug:%x\n", lar_u.syn_w, u3r_mug_chub(tar_d)));
end_d--; u3Z->lug_u.len_d--;
continue;
}
else if ( c3y == rup ) {
uL(fprintf(uH, "matched at %x\n", lar_u.syn_w));
uL(fprintf(uH, "rest: matched at %x\n", lar_u.syn_w));
rup = c3n;
}
@ -907,8 +901,8 @@ _sist_rest()
}
else {
if ( lar_u.ent_d != (ent_d - 1ULL) ) {
uL(fprintf(uH, "record (%s) is corrupt (g)\n", ful_c));
uL(fprintf(uH, "lar_u.ent_d %" PRIx64 ", ent_d %" PRIx64 "\n", lar_u.ent_d, ent_d));
uL(fprintf(uH, "rest: record (%s) is corrupt (g)\n", ful_c));
uL(fprintf(uH, "rest: lar_u.ent_d %" PRIx64 ", ent_d %" PRIx64 "\n", lar_u.ent_d, ent_d));
u3_lo_bail();
}
ent_d -= 1ULL;
@ -923,25 +917,32 @@ _sist_rest()
img_w = c3_malloc(4 * lar_u.len_w);
if ( -1 == lseek64(fid_i, 4ULL * end_d, SEEK_SET) ) {
uL(fprintf(uH, "record (%s) is corrupt (h)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (h)\n", ful_c));
u3_lo_bail();
}
if ( (4 * lar_u.len_w) != read(fid_i, img_w, (4 * lar_u.len_w)) ) {
uL(fprintf(uH, "record (%s) is corrupt (i)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (i)\n", ful_c));
u3_lo_bail();
}
ron = u3i_words(lar_u.len_w, img_w);
free(img_w);
// this validation is disabled, as it broke when mug
// was switched from FNV to Murmur3
// event-log encryption is enabled, so any actual corruption
// that this check would've caught will still be caught below
//
#if 0
if ( lar_u.mug_w !=
u3r_mug_both(u3r_mug(ron),
u3r_mug_both(u3r_mug(lar_u.tem_w),
u3r_mug(lar_u.typ_w))) )
u3r_mug_both(u3r_mug_words(&lar_u.tem_w, 1),
u3r_mug_words(&lar_u.typ_w, 1))) )
{
uL(fprintf(uH, "record (%s) is corrupt (j)\n", ful_c));
uL(fprintf(uH, "rest: record (%s) is corrupt (j)\n", ful_c));
u3_lo_bail();
}
#endif
if ( c3__ov != lar_u.typ_w ) {
u3z(ron);
@ -1243,7 +1244,7 @@ u3_sist_boot(void)
sed = sist_key(des);
}
else {
sed = u3_dawn_come(u3_nul);
sed = u3_dawn_come();
}
u3A->fak = c3n;

View File

@ -1,15 +1,9 @@
/* v/term.c
/* vere/term.c
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
@ -17,6 +11,7 @@
#include <curses.h>
#include <termios.h>
#include <term.h>
#include "all.h"
#include "vere/vere.h"
@ -50,10 +45,11 @@ _term_alloc(uv_handle_t* had_u,
)
{
// this read can range from a single byte to a paste buffer
// 32 bytes has been chosen heuristically
// 123 bytes has been chosen because its not a power of 2
// this is probably still broken
//
void* ptr_v = c3_malloc(32);
*buf = uv_buf_init(ptr_v, 32);
void* ptr_v = c3_malloc(123);
*buf = uv_buf_init(ptr_v, 123);
}
@ -721,8 +717,15 @@ _term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i)
u3_lo_open();
{
if ( siz_i == UV_EOF ) {
// nothing
} else if ( siz_i < 0 ) {
// We hear EOF (on the third read callback) if
// 2x the _term_alloc() buffer size is pasted.
// The process hangs if we do nothing (and ctrl-z
// then corrupts the event log), so we force shutdown.
//
fprintf(stderr, "term: hangup (EOF)\r\n");
u3_lo_bail();
}
else if ( siz_i < 0 ) {
uL(fprintf(uH, "term %d: read: %s\n", uty_u->tid_l, uv_strerror(siz_i)));
}
else {

View File

@ -1,17 +1,10 @@
/* v/time.c
/* vere/time.c
**
** This file is in the public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <dirent.h>
#include <stdint.h>
#include <uv.h>
#include <curses.h>
#include <termios.h>

View File

@ -1,20 +1,10 @@
/* v/unix.c
/* vere/unix.c
**
** This file is in the public domain.
*/
#include "all.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <dirent.h>
#include <stdint.h>
#include <uv.h>
#include <termios.h>
#include <term.h>
@ -22,6 +12,7 @@
#include <libgen.h>
#include <ftw.h>
#include "all.h"
#include "vere/vere.h"
/* _unix_down(): descend path.

View File

@ -1,17 +1,10 @@
/* v/walk.c
/* vere/walk.c
**
** This file is in the public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <dirent.h>
#include <stdint.h>
#include <uv.h>
#include <curses.h>
#include <termios.h>