Users browsing this thread: 3 Guest(s)
josuah
Long time nixers
(05-04-2020, 01:41 AM)Halfwit Wrote: (Also minor edit, I renamed ubqt to altid, located now at https://github.com/altid. Ubqt was used just everywhere)

That made me learn about Ubqt, hum, Altid, which is really nice ! I did not test it yet, but that is definitely a nice way to expose all these services out.

I like that vision with putting all different kinds of services though a same protocol, because such a waste of time wasted writing code for parsing protocols! (IMAP for instance...)

Instead of 9P + directory layout, the world seems to go the way of HTTP + JSON + JSON layout... I still prefer dedicated protocols (yeah, I'd rather waste this time) to go for better protocols than HTTP which is_terrible_ at serializing things.

HTTP is no smarter than FTP if you think of it: 9P is a single TCP/TLS/SSH/CurveCP/MinimaLT/Quic/... stream to achieve something, so it does not suffer from tcp+tls overhead.

For converting all these zillion of protocols to HTTP, you have to do ONE REQUEST PER COMMAND! Such as IMAP LOGIN, then another one for LIST, then another one for SELECT, then another one for FETCH, and then so on.

So if you use HTTP for anything different than fetching individual files, it is NOT network transparent anymore!

Oh what? you have network-transparent HTTP2 that multiplexes streams? You'll only get that after ALPN negociation (TLS-specific) though.

Now HTTP3 is not directly bound to QUIC? It still does make use of its complex API, that only QUIC has.

Yes, mapping all protocols to 9P (including twitter, why not! if one uses it...) wil definitely be a better choice. Also, 9P does support notifications, thorugh a blocking read(2) call from the client, with the server that pushes bytes (maybe one at a time?) on each event. This is 256 kind of event, then the client can go rescan everything on updates.

Definitely sounds reasonable!

Code:
service=twitter handle=@Myhandle logdir=none secret=redacted token=redacted listen_address=none

NDB! How else to configure services... Maybe factotum? ;)

Code:
$ cat ndb.c
#include "ndb.h"

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <ctype.h>

/*
* The Network Datbase: a simple text-based key-value entrys file format:
* http://code.9front.org/hg/plan9front/file/c4896008f196/sys/src/libndb
*
* This implementation uses a singly linked list for the entire database,
* with all lines and entries chained on the same linked list, with an
* aditionnal pointer to the begining of the line, and another to the
* begining of the tuple:
*/

#include "log.h"

static void *
ndb_new(struct ndb **entry)
{
    struct ndb *np;

    if ((np = calloc(sizeof(struct ndb), 1)) == NULL)
        return (NULL);
    np->entry = *entry = *entry ? *entry : np;
    return (np);
}

void
ndb_free(struct ndb *np)
{
    if (np)
        ndb_free(np->next);
    free(np);
}

/*
* key = 1*keychar
* keychar = ( '0'..'9' | 'a'..'z' | 'A'..'Z' | '_' | '-' )
*/
static char *
ndb_parse_key(char *s, struct ndb *new)
{
    char *key;
    size_t len;

    key = s;
    while (*s != '\0' && (isalnum(*s) || strchr("_-", *s)))
        s++;
    if (s == key)
        return (NULL);
    len = s-key;

    if (len >= sizeof(new->key))
        return (errno=ENAMETOOLONG, NULL);
    memcpy(new->key, key, len);
    return (s);
}

/*
* val = ( '"' *quotedchar '"' | *unquotchar )
* quotedchar = ( 0x20..0x21 | 0x23..0x7E | 0x80..0xFF)
* unquotchar = ( 0x21 | 0x24..0x26 | 0x5D..0x7E | 0x80..0xFF)
*/
static char *
ndb_parse_val(char *s, struct ndb *new)
{
    char *val;
    size_t len;

    if (*s == '"') {
        s++;
        val = s;
        while (*s >= 0x20 && *s != '"' && *s != 0x7f)
            s++;
        len = s-val;
        if (*s++ != '"')
            return (NULL);
    } else {
        val = s;
        while (*s >= 0x21 && *s != '"' && *s != 0x7f)
            s++;
        len = s-val;
    }

    if (len >= sizeof(new->val))
        return (errno=ENAMETOOLONG, NULL);
    memcpy(new->val, val, len);
    return (s);
}

/*
* tuple = key '=' val
*/
static char *
ndb_parse_tuple(char *s, struct ndb **entry, struct ndb **last)
{
    struct ndb *new;

    if ((new = ndb_new(entry)) == NULL)
        return (NULL);

    if ((s = ndb_parse_key(s, new)) == NULL)
        goto err;

    if (*s++ != '=')
        goto err;

    if ((s = ndb_parse_val(s, new)) == NULL)
        goto err;

    if (*last != NULL)
        (*last)->next = new;
    *last = new;
    return (s);
err:
    free(new);
    return (NULL);
}

/*
* ws = ( '\t' | '\r' | ' ' )
*/
static char *
ndb_parse_ws(char *s)
{
    if (!isblank(*s) && *s != '\r')
        return (NULL);
    while (isblank(*s) || *s == '\r')
        s++;
    return (s);
}

/*
* nl = 1*( [ ws ] [ '#' *non-nl ] '\n' )
*/
static char *
ndb_parse_nl(char *s, size_t *nl)
{
    char *beg;
    size_t n;

    for (n = 0 ;; n++, (*nl)++) {
        beg = s;
        if ((s = ndb_parse_ws(s)) == NULL)
            s = beg;
        if (*s == '#') {
            while (*s != '\0' && *s != '\n')
                s++;
        }
        if (*s != '\n') {
            s = beg;
            break;
        }
        s++;
    }
    if (n == 0)
        return (NULL);
    return (s);
}

/*
* line = tuple *( 1*ws tuple ) nl
*/
static char *
ndb_parse_line(char *s, struct ndb **entry, struct ndb **last, size_t *nl)
{
    char *cp;

    if ((s = ndb_parse_tuple(s, entry, last)) == NULL)
        return (NULL);

    while ((cp = ndb_parse_ws(s))) {
        s = cp;

        if ((cp = ndb_parse_tuple(s, entry, last)) == NULL)
            break;
        s = cp;
    }

    return (ndb_parse_nl(s, nl));
}

/*
* entry = line *( 1*ws line )
*/
static char *
ndb_parse_entry(char *s, struct ndb **last, size_t *nl)
{
    struct ndb *entry = NULL;
    char *cp;

    if ((cp = ndb_parse_line(s, &entry, last, nl)) == NULL)
        return (NULL);
    s = cp;

    while ((cp = ndb_parse_ws(s))) {
        s = cp;

        if ((cp = ndb_parse_line(s, &entry, last, nl)) == NULL)
            break;
        s = cp;
    }
    return (errno ? NULL : s);
}

/*
* base = *nl *( tuple *nl )
*/
static char *
ndb_parse_db(char *s, struct ndb **db, struct ndb **last, size_t *nl)
{
    char *cp;

    while ((cp = ndb_parse_nl(s, nl)))
        s = cp;

    *db = NULL;
    while ((cp = ndb_parse_entry(s, last, nl))) {
        s = cp;

        if (*db == NULL)
            *db = (*last)->entry;

        while ((cp = ndb_parse_nl(s, nl)))
            s = cp;
    }
    return (errno ? NULL : s);
}

static ssize_t
readfile(char const *path, char **s)
{
    ssize_t r, n;
    void *v;
    int fd;

    if ((fd = (path == NULL) ? 0 : open(path, O_RDONLY)) == -1)
        return (-1);

    r = n = 0;
    *s = NULL;
    do {
        n += r;
        if ((v = realloc(*s, n + 2048 + 1)) == NULL) {
            r = -1;
            goto err;
        }
        *s = v;
    } while ((r = read(fd, *s + n, 2048)) > 0);
    (*s)[n] = '\0';
err:
    if (fd > 0)
        close(fd);
    if (r == -1) {
        free(*s);
        *s = NULL;
    }
    return (r);
}

struct ndb *
ndb_parse_file(char const *path, size_t *nl, struct ndb **last)
{
    struct ndb *db;
    ssize_t r;
    char *s;

    *nl = 0;
    db = NULL;

    if ((r = readfile(path, &s)) == -1)
        return (NULL);
    if (memchr(s, '\0', r)) {
        errno = EBADMSG;
        return (NULL);
    }

    *nl = 1;
    if (ndb_parse_db(s, &db, last, nl) < s + r) {
        errno = EBADMSG;
        ndb_free(db);
        db = NULL;
    }
    free(s);
    return (db);
}

struct ndb *
ndb_open(char const **path, size_t *nl)
{
    struct ndb *db, *last, *np, *entry, *file;

    last = NULL;

    if ((db = np = ndb_parse_file(*path, nl, &last)) == NULL)
        return (NULL);

    if ((np = ndb_search(&np, NULL, "database", "")) == NULL)
        return (db);

    entry = np = np->entry;
    while ((file = ndb_search(&np, entry, "file", NULL))) {
        if (ndb_parse_file(file->val, nl, &last) == NULL) {
            *path = strdup(file->val);
            ndb_free(db);
            return (NULL);
        }
    }
    return (db);
}

struct ndb *
ndb_search(struct ndb **npp, struct ndb *entry, char const *key, char const *val)
{
    for (struct ndb *np = *npp; np; np = np->next) {
        if (entry && np->entry != entry->entry)
            break;
        if (strcmp(np->key, key) == 0) {
            if (!val || fnmatch(val, np->val, 0) == 0) {
                *npp = np->next;
                return (np);
            }
        }
    }
    return (NULL);
}

struct ndb *
ndb_related(struct ndb *this, char const *key)
{
    struct ndb *np, *entry;

    entry = this->entry;
    for (np = entry; np && np->entry == entry; np = np->next)
        if (strcmp(np->key, key) == 0)
            return ( np);
    return (NULL);
}

void
ndb_put_tuple(FILE *fp, struct ndb *np)
{
    char *fmt;

    fmt = np->val[strcspn(np->val, " \t")] == '\0' ? "%s=%s" : "%s=\"%s\"";
    fprintf(fp, fmt, np->key, np->val);
}

void
ndb_put_entry(FILE *fp, struct ndb *np, int nl)
{
    struct ndb *entry;
    int first;

    first = 1;
    for (np = entry = np->entry; np && np->entry == entry; np = np->next) {
        if (!first)
            fprintf(fp, nl ? "\n\t" : " ");
        ndb_put_tuple(fp, np);
        first = 0;
    }
}
$ cat ndb.h
#ifndef NDB_H
#define NDB_H

#include <time.h>
#include <stdint.h>
#include <stdio.h>

struct ndb {
    char        key[32];
    char        val[128];
    struct ndb    *next;        /* across multiple lines or tuples */
    struct ndb    *entry;        /* start of this entry */
};

/**/
void        ndb_free        (struct ndb *);
struct ndb *    ndb_search        (struct ndb **, struct ndb *, char const *, char const *);
struct ndb *    ndb_related        (struct ndb *, char const *);
struct ndb *    ndb_parse_file        (char const *, size_t *, struct ndb **);
struct ndb *    ndb_open        (char const **, size_t *);
void        ndb_put_tuple        (FILE *, struct ndb *);
void        ndb_put_entry        (FILE *, struct ndb *, int);

#endif

Yes I share code by pasting them on forums. True LOONIX way! Watchagonnado?


Messages In This Thread
Unix Ricing - by venam - 29-01-2017, 11:36 AM
RE: Unix Ricing - by jkl - 29-01-2017, 12:45 PM
RE: Unix Ricing - by venam - 29-01-2017, 01:02 PM
RE: Unix Ricing - by xero - 29-01-2017, 03:40 PM
RE: Unix Ricing - by nxll - 29-01-2017, 08:05 PM
RE: Unix Ricing - by venam - 08-04-2017, 05:04 AM
RE: Unix Ricing - by jkl - 08-04-2017, 08:28 AM
RE: Unix Ricing - by venam - 09-04-2017, 04:31 AM
RE: Unix Ricing - by mrtn - 10-04-2017, 04:57 AM
RE: Unix Ricing - by pyratebeard - 10-04-2017, 07:49 AM
RE: Unix Ricing - by jkl - 10-04-2017, 09:45 AM
RE: Unix Ricing - by evbo - 10-04-2017, 02:50 PM
RE: Unix Ricing - by Halfwit - 31-05-2019, 04:56 PM
RE: Unix Ricing - by Halfwit - 05-04-2020, 01:41 AM
RE: Unix Ricing - by josuah - 08-04-2020, 04:03 PM
RE: Unix Ricing - by venam - 09-04-2020, 02:11 AM
RE: Unix Ricing - by jkl - 09-04-2020, 02:25 AM
RE: Unix Ricing - by josuah - 09-04-2020, 05:10 AM