This is nilist.c in view mode; [Download] [Up]
/* nilist.c
Turn the netinfo database into human-readable text. Someday I
hope there will be a parser for this to turn it back, or even
better a new netinfo server that reads this format database.
Being able to edit the database as text (with the abilities to
search, compare, and copy arbitrary regions) is much more
"user friendly" than the fanciest panels of buttons!
Written by Bill Spitzak, May 1990.
SPITZAK @ MCIMAIL.COM
============================================================================
Syntax of the output file:
(originally I hoped to make this compatable with the "slash"
notation favored by the NeXT "niutil -read" program. However
this required extensive quoting of the pathnames that are very
common field values. So I dumped that for this notation.)
... means repeat the last object zero or more times.
comment: '#' <any character except newline>... <newline>
tokencharacter:
'a' .. 'z'
'A' .. 'Z'
'0' .. '9'
'.'
'/'
'_'
'-'
(others may be added if common in field names)
word: tokencharacter...
quoted_string: '"' <normal C-string stuff>... '"'
name:
word
quoted_string
property: name
value: name
subdirectory: name
entry:
property value... ';'
subdirectory '{' entry... '}'
file: entry...
*/
#include <netinfo/ni.h>
printname(char *n) {
char *p; int c;
if (!n) return;
/* search to see if any characters need to be quoted: */
if (*n) for (p = n; ;) {
c = *p++;
if (!c) {printf("%s",n); return;}
if (c>='a' && c<='z' || c>='A' && c<='Z' || c>='0' && c<='9'
|| index("/._-",c));
else break;
}
putchar('"');
for (p = n; c = *p++;) {
switch (c) {
case '\b': c = 'b'; goto QUOTE;
case '\t': c = 't'; goto QUOTE;
case '\n': c = 'n'; goto QUOTE;
case '\f': c = 'f'; goto QUOTE;
case '\r': c = 'r'; goto QUOTE;
case '\\':
case '"':
QUOTE: putchar('\\'); putchar(c); break;
default:
if (c < ' ' || c >= 127) printf("\\%3o",c&255);
else putchar(c);
break;
}
}
putchar('"');
}
void nli(int level) { /* new line and indent */
int x; putchar('\n'); for (x=0; x < level; x++) putchar('\t');
}
listdirectory(void *handle, ni_id *dir,int level)
{
int n,m;
ni_proplist props;
ni_idlist idlist;
ni_id subdir;
ni_property *prop;
ni_namelist *list;
int itemcount;
int big;
int sepflag;
char *name;
char namebuf[20];
ni_read(handle,dir,&props);
ni_children(handle,dir,&idlist);
itemcount = props.ni_proplist_len + idlist.ni_idlist_len;
name = 0;
if (level) {
/* get the name out of the property list. If it is the only
name decrement the number of properties to print */
name = 0;
for (n = 0; n < props.ni_proplist_len; n++) {
prop = props.ni_proplist_val+n;
if (!strcmp(prop->nip_name,"name")) {
if (!prop->nip_val.ni_namelist_len) break;
name = prop->nip_val.ni_namelist_val[0];
if (prop->nip_val.ni_namelist_len == 1) itemcount--;
break;
}
}
if (name) printname(name); else printf("_%d",dir->nii_object);
big = itemcount > 3 || itemcount>1 && idlist.ni_idlist_len;
putchar(big ? ' ' : '\t'); putchar('{'); if (big) nli(level);
}
else big = 1;
sepflag = 0;
for (n = 0; n < props.ni_proplist_len; n++) {
prop = props.ni_proplist_val+n;
list = &prop->nip_val;
if (list->ni_namelist_len==1 &&
list->ni_namelist_val[0] == name) continue;
if (!big && sepflag++) putchar(' ');
printname(prop->nip_name);
for (m = 0; m < list->ni_namelist_len; m++) {
if (list->ni_namelist_val[m] == name) continue;
putchar(' ');
printname(list->ni_namelist_val[m]);
}
putchar(';');
if (big) nli(level);
}
for (n = 0; n < idlist.ni_idlist_len; n++) {
subdir.nii_object = idlist.ni_idlist_val[n];
subdir.nii_instance = 0;
listdirectory(handle,&subdir,level+1);
if (big) nli(level);
}
if (level) putchar('}');
ni_proplist_free(&props);
ni_idlist_free(&idlist);
}
listdomain(void *handle) {
ni_id dir;
ni_root(handle,&dir);
listdirectory(handle,&dir,0);
}
main(int argc, char **argv)
{
int n,status;
void *handle;
if (argc < 2) {argv[1] = "."; argc = 2;}
for (n = 1; n < argc; n++) {
handle = 0;
status = ni_open(0, argv[n], &handle);
if (status) printf("Error %d opening domain %s.\n",status,argv[n]);
else {listdomain(handle); ni_free(handle);}
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.