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 $*
next 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).