#include #include #include #include #include #include #include #include #include using namespace std; /* version */ const char* versinfo = "0.0.5a"; void readmsg(int *x); void editmsg(char *x); void get_all_messages(char *x); void show_version(void); void show_help(void); void show_wenda(void); int msg_filter(const dirent *x); void countmsgs(void); char get_msg_filename(int *x); int main (int argc, char **argv) { if (!argv[1]) { cout << "Standard program - Just display list of message titles, numbered." << endl; exit(0); } else { /* check for non-standard arguments */ if (!strcmp(argv[1], "--version")) { show_version(); exit(0); } else if (!strcmp(argv[1], "--help")) { show_help(); exit(0); } /* this is an easter egg - it refers to Wenda from "Where's Wally" */ else if (!strcmp(argv[1], "--wenda")) { show_wenda(); exit(0); } } /* normal argument handler - thanks to Arvind */ for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'r': if (argc > i + 1) { /* thanks to Kamran - this range handler is brilliant :) */ get_all_messages(argv[i + 1]); i++; } else { cout << "Display list of message titles." << endl; } break; case 'w': // cout << "Write message."; break; case 'c': countmsgs(); exit(0); break; case 'e': if (argc > i + 1) { char * emsg; emsg = argv[i + 1]; editmsg(emsg); i++; } else { cout << "Please enter a message number to edit." << endl; } break; default: cout << "Unknown argument: " << argv[i][1] << endl; break; } } else { cout << "Extra arg: " << argv[i] << endl; } } return (0); } /* functions */ void readmsg(int *x) { string mbuffer, mbuffertmp; int mbuffertest, msglinelength; char *themsgfile; themsgfile = get_msg_filename(x); ifstream msgfile(themsgfile); if (! msgfile.is_open()) { cout << "Error opening file"; exit (1); } cout << "\n"; while (! msgfile.eof()) { getline(msgfile,mbuffer,'\n'); mbuffertmp = mbuffer; mbuffertest = mbuffertmp.empty(); if (mbuffertest == 0) { mbuffertmp = mbuffertmp.erase(1); if (mbuffertmp == "%") { msglinelength = mbuffer.length(); if (msglinelength > 1) { mbuffer = mbuffer.substr(2); cout << mbuffer << endl; } else { mbuffer = mbuffer.substr(1); cout << mbuffer << endl; } } else if (mbuffertmp == "T") { mbuffer = mbuffer.substr(7); cout << "-----------------------------------------" << endl; cout << " " << mbuffer << endl; cout << "-----------------------------------------" << endl; } else if (mbuffertmp == "D") { mbuffer = mbuffer.substr(6); long tmpdate; tmpdate = atol(mbuffer.c_str()); cout << "Last Modified: " << ctime(&tmpdate) << "\n"; } } } cout << "\n"; } /* ranges code thanks to Kamran - how cool is it? :D */ void get_all_messages(char *x) { int range1, range2, range[10], i = 0; string temp, arg(x); /* here's the really messy part. The program first checks whether the argument contains a ','. If yes, it then checks for a '-'. If yes, it handles the argument accordingly. */ while (arg.length() > 0) if (arg.find(",") < arg.length()) if (arg.find("-") < arg.length()) { int loc = arg.find_first_of(",-"); switch (arg[loc]) { case '-': arg.replace(loc, 1, "%"); temp = arg.substr(0, loc); range1 = atoi(temp.c_str()); int nextloc; nextloc = arg.find_first_of("-,"); if (nextloc < arg.length()) { temp = arg.substr(loc + 1, nextloc - loc - 1); arg.erase(0, nextloc + 1); } else { temp = arg.substr(loc + 3); arg.erase(0, loc + 1); } range2 = atoi(temp.c_str()); while (range1 <= range2) range[i++] = range1++; break; case ',': arg.replace(loc, 1, "%"); temp = arg.substr(0, loc); range[i++] = atoi(temp.c_str()); arg.erase(0, loc + 1); break; } } else { int loc = arg.find(","); temp = arg.substr(0, loc); range[i++] = atoi(temp.c_str()); arg.erase(0, loc + 1); } else if (arg.find("-") < arg.length()) { int loc = arg.find("-"); temp = arg.substr(0, loc); range1 = atoi(temp.c_str()); temp = arg.substr(loc + 1, arg.length() - loc - 1); range2 = atoi(temp.c_str()); while (range1 <= range2) range[i++] = range1++; arg.erase(0, loc + 3); } else { range[i++] = atoi(arg.c_str()); break; } //while ends here --i; for(int j = 0; j <= i; j++) { readmsg(range[j]); } } void editmsg(char *x) { pid_t pid = 0; x = strcat(x, "_tmp.txt"); if ((pid = fork ()) == 0) { // In child. execl("/usr/bin/vi", "vi",x,0); // Remember, not exit, but use _exit. _exit (0); } waitpid (pid, 0, 0); cout << "Message edited." << endl; } int msg_filter(const dirent *x) { char *msgindicator = ".message"; char *cmsgindicator; cmsgindicator = strstr(x->d_name,msgindicator); if (cmsgindicator) { return (1); } else { return (0); } } void countmsgs(void) { int n,t=0; struct dirent **countedlist; n = scandir(".", &countedlist, msg_filter, versionsort); if (n < 0) { perror("scandir"); } else { while(n--) { t++; free(countedlist[n]); } free(countedlist); } cout << "There are " << t << " messages." << endl; } char get_msg_filename(int *x) { struct dirent **msgarray; x = scandir(".", &msgarray, msg_filter, versionsort); char *fn; x = x-1; fn = msgarray[x]->d_name; return fn; } void show_version(void) { cout << "Grim " << versinfo << endl; } void show_help(void) { cout << "Help to be implemented" << endl; } void show_wenda(void) { cout << "This is an easter egg. I will make it more interesting later." << endl; }