9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] ndb/requery
@ 2009-01-01 23:32 erik quanstrom
  0 siblings, 0 replies; 2+ messages in thread
From: erik quanstrom @ 2009-01-01 23:32 UTC (permalink / raw)
  To: 9fans

[-- 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 $*

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [9fans] ndb/requery
@ 2009-07-03 22:47 erik quanstrom
  0 siblings, 0 replies; 2+ messages in thread
From: erik quanstrom @ 2009-07-03 22:47 UTC (permalink / raw)
  To: 9fans

i had a use for listing ip addresses by domain the
other day.  grep and awk were making a few mistakes
so i decided to bring out the big guns.  then
ndb/requery dom 'example.com$' ip did what i wanted.
contrib/pull quanstro/ndbrequery.

- erik

     NDBREQUERY(8)                                       NDBREQUERY(8)

     NAME
          requery - search ndb tuple values by regular expression

     SYNOPSIS
          ndb/requery [ -i ] [ -f ndbfile ] attr regex [ rattr ]

     DESCRIPTION
          Ndb/requery searches the database dbfile (/lib/ndb/local by
          default) for an attribute of type attr and value that
          matches regex. The -i flag specifies a case-insensitive
          search.



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-07-03 22:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-01 23:32 [9fans] ndb/requery erik quanstrom
2009-07-03 22:47 erik quanstrom

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).