/** limpet.c **/ /** This program sucks out the subscriptions from the NetNewsWire preferences file, and creates an OPML file that contains all the key data. This is an easy way to keep multiple RSS-feed systems in sync, at least in terms of which subscriptions you desire. Obviously keeping them in sync last-read-time-wise is quite a bit more complex, particularly if you want to use this with multiple RSS apps. This is tested against NetNewsWire v1.0.3 and should work with earlier and later versions, but maybe not. :-) This program is released into the public domain. Enjoy! Author : Dave Taylor App Home: http://www.intuitive.com/limpet/ **/ #include #include #define PREFS "Library/Preferences/com.ranchero.NetNewsWire.plist" #define VERSION "1.0" #define SLEN 2048 #define contains(a,b) (strstr(a,b) != NULL) main() { FILE *fd; char buffer[SLEN], home[SLEN], name[SLEN], rss[SLEN]; chdir(getenv("HOME")); /* make sure we're in your HOME directory */ if ((fd = fopen(PREFS, "r")) == NULL) { fprintf(stderr, "Error: Can't open NetNewsWire preferences file to proceed.\n"); fprintf(stderr, "\tfilename = %s\n", PREFS); exit(1); } /** First, output the OPML header **/ printf("\n"); printf("\n", VERSION); printf("\n"); printf("\n"); printf("MySubscriptions\n"); printf("\n"); printf("\n"); /** now step through the .plist file looking for subscription info **/ while (fgets(buffer, SLEN, fd) != NULL) { if (contains(buffer, ">home<")) { fgets(home, SLEN, fd); prune(home); name[0] = rss[0] = 0; /* zero them out */ } else if (contains(buffer, ">name<")) { fgets(name, SLEN, fd); prune(name); } else if (contains(buffer, ">rss<")) { fgets(rss, SLEN, fd); prune(rss); printf("\n", rss); } } (void) fclose(fd); /* done, close file */ /** and wrap up with the OPML footer **/ printf("\n\n"); exit(0); } prune(char *string) { /* Clean up the given string, replacing it with the result. This is a lazy function with minimal error checking, but the .plist file is very well defined, so we're just extracting what's between the delimiters > and < here. */ char mybuffer[SLEN]; register int i,j = 0; for (i=0; string[i] != '>'; i++) /* do nothing */ ; i++; /* skip the '>' itself */ while (string[i] != '<') mybuffer[j++] = string[i++]; mybuffer[j] = 0; strcpy(string, mybuffer); }