9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: erik quanstrom <quanstro@quanstro.net>
To: 9fans@9fans.net
Subject: [9fans] ndb/requery
Date: Thu,  1 Jan 2009 18:32:12 -0500	[thread overview]
Message-ID: <60686219d32d7c5ed978f2a2ed09ec99@quanstro.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 976 bytes --]

this is otherwise known as how to shove a round peg in a
square hole.  but the inefficency doesn't much matter.

i have an ancient unix program called tel.  i wrote it in
1988 so it has no relation to tel(1).  tel is a simple
address book.  recently it's been abused to store account
information that would be useless in factotum, such as dsl
account passwords.  the format has been blocks of name tab
value seperated by blank lines.

i've had two problems with tel.  foremost, it's insecure.
but it's always been a pain to search.

secstore would be secure enough and ndb could be easier to
search.  one problem.  ndb assumes full exact matches and i
don't often remember exactly.

the solution to that was ndb/requery, which matches regular
expressions but is otherwise the same as ndb/query.  for
example:
	; ndb/requery dom aska dom
	aska.quanstro.net
	oldaska.quanstro.net

stel is a little wrapper that takes care of security details.

- erik

[-- Attachment #2: ndbrequery.c --]
[-- Type: text/plain, Size: 2463 bytes --]

/*
 *  pattern search the network database for matches
 */
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
#include <regexp.h>

static	int	flag[127];
static	Biobuf	bout;

void
usage(void)
{
	fprint(2, "usage: pquery [-i] [-f ndbfile] attr value rattr\n");
	exits("usage");
}

static void
prmatch(Ndbtuple *nt, char *rattr)
{
	for(; nt; nt = nt->entry)
		if(rattr && strcmp(nt->attr, rattr) == 0)
			Bprint(&bout, "%s\n", nt->val);
		else if(!rattr)
			Bprint(&bout, "%s=%s ", nt->attr, nt->val);
	if(!rattr)
		Bprint(&bout, "\n");
}

char*
lower(char *s)
{
	char *p, c;

	for(p = s; c = *p; p++)
		if(c >= 'A' && c <= 'Z')
			*p = c - ('A' - 'a');
	return s;
}

int
iregex(Reprog *re, char *val)
{
	char *s;
	int r;

	if(!flag['i'])
		return regexec(re, val, 0, 0);
	s = lower(strdup(val));
	r = regexec(re, s, 0, 0);
	free(s);
	return r;
}

Ndbtuple*
research(char *dbfile, Ndb *db, char *attr, char *valre, char *rattr)
{
	int m;
	Reprog *re;
	Ndb *p;
	Ndbtuple *nt, *t;

	re = regcomp(valre);
	if(re == nil)
		sysfatal("regcomp: %r");
	for(m = 0; t = ndbparse(db); m = 0){
		/* why doesn't ndb do this for me? */
		if(strcmp(t->attr, "database") == 0){
			for(nt = t; nt; nt = nt->entry)
				if(strcmp(nt->attr, "file") == 0)
				if(strcmp(nt->val, dbfile) != 0){
					p = ndbopen(nt->val);
					if(p == nil)
						sysfatal("bad ndb file: %s\n", nt->val);
					research(nt->val, p, attr, valre, rattr);
					ndbclose(p);
				}
		}
		for(nt = t; nt; nt = nt->entry){
			if(flag['a'] || strcmp(nt->attr, attr) == 0)
				if(iregex(re, nt->val))
					m = 1;
		}
		if(m)
			prmatch(t, rattr);
		ndbfree(t);
	}
	free(re);
	return 0;
}

void
main(int argc, char **argv)
{
	char *dbfile, *attr, *val, *rattr;
	Ndb *db;

	dbfile = "/lib/ndb/local";
	ARGBEGIN{
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'a':
	case 'i':
		flag[ARGC()] = 1;
		break;
	default:
		usage();
	}ARGEND;

	attr = nil;
	if(flag['a'] == 0){
		attr = *argv++;
		if(attr == nil)
			usage();
	}
	val = *argv++;
	if(val == nil)
		usage();
	if(flag['i'])
		val = lower(val);
	rattr = *argv;

	if(Binit(&bout, 1, OWRITE) == -1)
		sysfatal("Binit: %r");
	db = ndbopen(dbfile);
	if(db == nil){
		fprint(2, "%s: no db files\n", argv0);
		exits("no db");
	}
	research(dbfile, db, attr, val, rattr);
	ndbclose(db);
	Bterm(&bout);
	exits(0);
}

[-- Attachment #3: stel --]
[-- Type: text/plain, Size: 235 bytes --]

#!/bin/rc
rfork en
if(~ $service cpu){
	echo dont run on cpu server>[1=2]
	exit usage
}
ramfs -p
cd /tmp
auth/secstore -g accounts.db
if(~ $#* 0 1)
	ndb/requery -f accounts.db -ai $*
if not
	ndb/requery -f accounts.db -i $*

             reply	other threads:[~2009-01-01 23:32 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-01 23:32 erik quanstrom [this message]
2009-07-03 22:47 erik quanstrom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=60686219d32d7c5ed978f2a2ed09ec99@quanstro.net \
    --to=quanstro@quanstro.net \
    --cc=9fans@9fans.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).