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.