// // abook.m // QuantumSTEP // // modify address book // // abook [-?dtxgmp] // -? print help // --help print help // -d uid delete // -t uid list all attributes // -l uid attrib list attribute // -x uid attrib value change attribute // -ag uid Group add to (existing) or new group // -me uid set the me record // . as uid refers to the last one created by -cg or -cp or explicitly specified // -cg create group // -cp create person // -m show me record // -g show groups // -p show people // // Created by Dr. H. Nikolaus Schaller on Jan 21 2008. // Copyright (c) 2008 DSITRI. All rights reserved. // #include #include #define AB [ABAddressBook sharedAddressBook] @interface ABPerson (private) - (NSString *) format; @end @implementation ABPerson (private) - (NSString *) format; { NSMutableString *s=[NSMutableString string]; [s appendFormat:@"%@, %@", [self valueForProperty:kABLastNameProperty], [self valueForProperty:kABFirstNameProperty]]; return s; } @end int main(int argc, const char *argv[]) { NSAutoreleasePool *pool; NSProcessInfo *proc; NSArray *args; unsigned int i; NSString *lastuid=@"?"; pool = [NSAutoreleasePool new]; proc = [NSProcessInfo processInfo]; if (proc == nil) { NSLog(@"defaults: unable to get process information!\n"); [pool release]; exit(1); } args = [proc arguments]; for (i = 1; i < [args count]; i++) { if (i == 1 && ([[args objectAtIndex: i] isEqual: @"--help"] || [[args objectAtIndex: i] isEqual: @"-?"])) { printf( "abook [-?dtxgmp]\n" " -? print help\n" " --help print help\n" " -d uid delete\n" " -t uid list all attributes\n" " -l uid attrib list attribute\n" " -x uid attrib value change attribute\n" " -ag uid Group add to (existing) or new group\n" " -me uid set the 'me' record\n" " . as uid refers to the last one created by -cg or -cp or explicitly specified\n" " -cg create group\n" " -cp create person\n" " -m show 'me' record\n" " -g show groups\n" " -p show people\n" ); break; } else if ([[args objectAtIndex: i] isEqual: @"-g"]) { NSEnumerator *e=[[AB groups] objectEnumerator]; ABGroup *g; while((g=[e nextObject])) printf("%s\n", [[NSString stringWithFormat:@"%@: %@", [g uniqueId], [g valueForProperty:kABGroupNameProperty]] UTF8String]); } else if ([[args objectAtIndex: i] isEqual: @"-m"]) { if([AB me]) printf("%s\n", [[NSString stringWithFormat:@"%@: %@", [[AB me] uniqueId], [[AB me] format]] UTF8String]); else printf("no ME-Record defined\n"); } else if ([[args objectAtIndex: i] isEqual: @"-p"]) { NSEnumerator *e=[[AB people] objectEnumerator]; ABPerson *p; while((p=[e nextObject])) printf("%s\n", [[NSString stringWithFormat:@"%@: %@", [p uniqueId], [p format]] UTF8String]); } else if ([[args objectAtIndex: i] isEqual: @"-cg"]) { ABGroup *np=[[[ABGroup alloc] init] autorelease]; // create new (empty!) record [np setValue:@"new group" forProperty:kABGroupNameProperty]; [AB addRecord:np]; // if([currentRecord isKindOfClass:[ABGroup class]]) // [(ABGroup *) currentRecord addSubgroup:np]; // if a group is seleced -> automatically add to that group printf("c %s\n", [[NSString stringWithFormat:@"%@: %@", lastuid=[np uniqueId], [np valueForProperty:kABGroupNameProperty]] UTF8String]); } else if ([[args objectAtIndex: i] isEqual: @"-cp"]) { ABPerson *np=[[[ABPerson alloc] init] autorelease]; // create new (empty!) record [np setValue:@"new person" forProperty:kABLastNameProperty]; [AB addRecord:np]; // if([currentRecord isKindOfClass:[ABGroup class]]) // [(ABGroup *) currentRecord addMember:np]; // if a group is seleced -> automatically add to that group printf("c %s\n", [[NSString stringWithFormat:@"%@: %@", lastuid=[np uniqueId], [np format]] UTF8String]); } else if ([[args objectAtIndex: i] isEqual: @"-ag"]) { NSString *uid = [args objectAtIndex: ++i]; NSString *group = [args objectAtIndex: ++i]; ABRecord *r; if([uid isEqualToString:@"."]) uid=lastuid; else lastuid=uid; r = [AB recordForUniqueId:uid]; if(!r) printf("? %s not found\n", [uid UTF8String]); else { NSEnumerator *e=[[AB groups] objectEnumerator]; ABGroup *g; while((g=[e nextObject])) { if([[g valueForProperty:kABGroupNameProperty] isEqualToString:group]) break; } if(!g) { // create a new group g=[[[ABGroup alloc] init] autorelease]; [g setValue:group forProperty:kABGroupNameProperty]; [AB addRecord:g]; } if([r isKindOfClass:[ABPerson class]]) [g addMember:(ABPerson *) r]; else [g addSubgroup:(ABGroup *) r]; } } else if ([[args objectAtIndex: i] isEqual: @"-d"]) { NSString *uid = [args objectAtIndex: ++i]; ABRecord *r; if([uid isEqualToString:@"."]) uid=lastuid; else lastuid=uid; r = [AB recordForUniqueId:uid]; if(!r) printf("? %s not found\n", [uid UTF8String]); else if([AB removeRecord:r]) printf("d %s\n", [uid UTF8String]); else printf("! %s not removed\n", [uid UTF8String]); } else if ([[args objectAtIndex: i] isEqual: @"-me"]) { NSString *uid = [args objectAtIndex: ++i]; ABRecord *r; if([uid isEqualToString:@"."]) uid=lastuid; else lastuid=uid; r = [AB recordForUniqueId:uid]; if(!r) printf("? %s not found\n", [uid UTF8String]); else if([r isKindOfClass:[ABPerson class]]) { [AB setMe:(ABPerson *) r]; printf("m %s\n", [uid UTF8String]); } else printf("! %s not set\n", [uid UTF8String]); } else if ([[args objectAtIndex: i] isEqual: @"-t"]) { NSString *uid = [args objectAtIndex: ++i]; ABRecord *r; if([uid isEqualToString:@"."]) uid=lastuid; else lastuid=uid; r = [AB recordForUniqueId:uid]; if(!r) printf("? %s not found\n", [uid UTF8String]); else printf("%s", [[[[r class] properties] description] UTF8String]); // list attributes } else if ([[args objectAtIndex: i] isEqual: @"-x"]) { // check that arguments exist NSString *uid = [args objectAtIndex: ++i]; NSArray *attrib = [[args objectAtIndex: ++i] componentsSeparatedByString:@"."]; NSString *value = [args objectAtIndex: ++i]; ABRecord *r; if([uid isEqualToString:@"."]) uid=lastuid; else lastuid=uid; r = [AB recordForUniqueId:uid]; if(!r) printf("? %s not found\n", [uid UTF8String]); else { int j; id val=nil; NSString *prop=@""; for(j=0; j<[attrib count]; j++) { // process dotted path components prop=[attrib objectAtIndex:j]; if(j == 0) { // no sublevels if(j+1 == [attrib count]) [r setValue:value forProperty:prop], val=value; // last one else val=[r valueForProperty:prop]; // first level } else if(j == 1 && [[r class] typeOfProperty:prop] & kABMultiValueMask) { // first level can be a labeled multivalue object int k; for(k=0; k<[val count]; k++) if([[val labelAtIndex:k] isEqualToString:prop]) break; if(k == [val count]) { // label not found, create new entry if(!val) val=[[ABMutableMultiValue alloc] init]; // create new else val=[val mutableCopy]; // val comes from previous level [(ABMutableMultiValue *) val addValue:value withLabel:prop]; [r setValue:val forProperty:[attrib objectAtIndex:j-1]]; // update one level before [val release]; } else if(j+1 == [attrib count]) [val replaceValueAtIndex:k withValue:value], val=value; // change existing label else val=[val valueAtIndex:k]; // get from multivalue } else { // dictionary sublevels if(j+1 == [attrib count]) [val setObject:value forKey:prop], val=value; // last one else val=[val objectForKey:prop]; // assume NSDictionary } } if(!val) printf("? %s (%s) not found\n", [[args objectAtIndex: i-1] UTF8String], [prop UTF8String]); else printf("= %s %s\n", [[args objectAtIndex: i-1] UTF8String], [val UTF8String]); } } else if ([[args objectAtIndex: i] isEqual: @"-l"]) { // list // FIXME: check if uid and attrib exist NSString *uid = [args objectAtIndex: ++i]; NSArray *attrib = [[args objectAtIndex: ++i] componentsSeparatedByString:@"."]; ABRecord *r; if([uid isEqualToString:@"."]) uid=lastuid; else lastuid=uid; r = [AB recordForUniqueId:uid]; // handle special case with multi-value and directory value records! if(!r) printf("? %s not found\n", [uid UTF8String]); else { int j; id val=nil; NSString *prop=@""; for(j=0; j<[attrib count]; j++) { // process dotted path components prop=[attrib objectAtIndex:j]; if(j == 0) val=[r valueForProperty:prop]; // first level else if(j == 1 && [[r class] typeOfProperty:prop] & kABMultiValueMask) { // first level can be a labeled multivalue object int k; for(k=0; k<[val count]; k++) if([[val labelAtIndex:k] isEqualToString:prop]) break; if(k == [val count]) val=nil; // not found else val=[val valueAtIndex:k]; // get from multivalue } else val=[val objectForKey:prop]; // assume NSDictionary } if(val) printf("%s\n", [[val description] UTF8String]); else printf("? %s (%s) not found\n", [[args objectAtIndex: i-1] UTF8String], [prop UTF8String]); } } else if ([[args objectAtIndex: i] isEqual: @"-f"]) { // filter } else { fprintf(stderr, "Unknown option\n"); exit(1); } } [AB save]; [pool release]; exit(0); }