Next: Namespace And Features, Previous: Internal Name Management, Up: Namespaces [Contents][Index]
The following example is a revised version of the suite of routines developed in Reading the User Database. See there for an explanation of how the code works.
The formulation here, due mainly to Andrew Schorr, is rather elegant.
All of the implementation functions and variables are in the
passwd namespace, whereas the main interface functions are
defined in the awk namespace.
# ns_passwd.awk --- access password file information
@namespace "passwd"
BEGIN {
# tailor this to suit your system
Awklib = "/usr/local/libexec/awk/"
}
function Init( oldfs, oldrs, olddol0, pwcat, using_fw, using_fpat)
{
if (Inited)
return
oldfs = FS
oldrs = RS
olddol0 = $0
using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
using_fpat = (PROCINFO["FS"] == "FPAT")
FS = ":"
RS = "\n"
pwcat = Awklib "pwcat"
while ((pwcat | getline) > 0) {
Byname[$1] = $0
Byuid[$3] = $0
Bycount[++Total] = $0
}
close(pwcat)
Count = 0
Inited = 1
FS = oldfs
if (using_fw)
FIELDWIDTHS = FIELDWIDTHS
else if (using_fpat)
FPAT = FPAT
RS = oldrs
$0 = olddol0
}
function awk::getpwnam(name)
{
Init()
return Byname[name]
}
function awk::getpwuid(uid)
{
Init()
return Byuid[uid]
}
function awk::getpwent()
{
Init()
if (Count < Total)
return Bycount[++Count]
return ""
}
function awk::endpwent()
{
Count = 0
}
As you can see, this version also follows the convention mentioned in Naming Library Function Global Variables, whereby global variable and function names start with a capital letter.
Here is a simple test program. Since it’s in a separate file, unadorned
identifiers are sought for in the awk namespace:
BEGIN {
while ((p = getpwent()) != "")
print p
}
Here’s what happens when it’s run:
$ gawk -f ns_passwd.awk -f testpasswd.awk -| root:x:0:0:root:/root:/bin/bash -| daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin -| bin:x:2:2:bin:/bin:/usr/sbin/nologin -| sys:x:3:3:sys:/dev:/usr/sbin/nologin …