// Prints out a graph representing the startup order for display with GraphViz #import // Change things here if you want the graph to look different static char *REQ_STYLE="style=bold"; static char *USE_STYLE="style=solid"; static char *PROV_STYLE="style=solid"; static char *DESCRIPTION_STYLE="shape=ellipse"; static char *SERVICE_STYLE="shape=box"; static char *RANK_DIR="TB"; void processFile(int i, NSString *fName) { NSDictionary *item = [NSDictionary dictionaryWithContentsOfFile: fName]; NSEnumerator *en; NSString *ss; printf(" node%d [label=\"%s\",%s];\n", i, [[item objectForKey: @"Description"] cString], DESCRIPTION_STYLE); en = [[item objectForKey: @"Uses"] objectEnumerator]; while ((ss = [en nextObject]) != nil) printf(" \"%s\" -> node%d [%s]\n", [ss cString], i, USE_STYLE); en = [[item objectForKey: @"Requires"] objectEnumerator]; while ((ss = [en nextObject]) != nil) printf(" \"%s\" -> node%d [%s]\n", [ss cString], i, REQ_STYLE); en = [[item objectForKey: @"Provides"] objectEnumerator]; while ((ss = [en nextObject]) != nil) printf(" node%d -> \"%s\" [%s]\n", i, [ss cString], PROV_STYLE); } int main(int argc, char **argv) { int i=0; NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init]; NSFileManager *fm = [NSFileManager defaultManager]; NSString *place, *subPlace; NSArray *places = [NSArray arrayWithObjects: @"/System/Library/StartupItems", @"/Library/StartupItems", nil]; printf("digraph class_relationships {\n node [%s];\n graph [rankdir = %s];\n", SERVICE_STYLE, RANK_DIR); NSEnumerator *en = [places objectEnumerator]; while((place = [en nextObject]) != nil) { NSEnumerator *en2 = [[fm directoryContentsAtPath: place] objectEnumerator]; while ((subPlace = [en2 nextObject]) != nil) processFile(++i, [NSString stringWithFormat: @"%@/%@/StartupParameters.plist", place, subPlace]); } printf("}\n"); return 0; }