Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

jack.cc

Go to the documentation of this file.
00001 /** @file jack.cc */
00002 /* 
00003  * Copyright (C) 2002 Laird Breyer
00004  *  
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * 
00019  * Author:   Laird Breyer <laird@lbreyer.com>
00020  */
00021 
00022 #include <string>
00023 #include <time.h>
00024 #include <sys/time.h>
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <fcntl.h>
00028 #include <unistd.h>
00029 #include <sstream>
00030 #include <stdio.h>
00031 #include <readline/readline.h>
00032 #include <readline/history.h>
00033 
00034 static char defaultfifo[] = "";
00035 static char defaulttmpdir[] = "/tmp/";
00036 
00037 /// Opens both input and output FIFOs and sends commands to ripper
00038 int main(int argc, char** argv) {
00039 
00040   char *name = defaultfifo;
00041   char *tempdir = defaulttmpdir;
00042 
00043   argv++;
00044   for (int i = 1; i < argc; ++i, ++argv) {
00045     if ((*argv)[0] == '-' && (*argv)[1] != '\0') {  // option
00046       if (!strcmp(*argv, "--name")) {
00047         ++i;
00048         ++argv;
00049         if (i >= argc) {
00050           cerr << "usage: jack [--name monty]\n";
00051           exit(1);
00052         }
00053         name = *argv;
00054       } else if (!strcmp(*argv, "--temp_dir")) {
00055         ++i;
00056         ++argv;
00057         if (i >= argc) {
00058           cerr << "usage: jack [--temp_dir /tmp/]\n";
00059           exit(1);
00060         }
00061         tempdir = *argv;
00062       }
00063     }
00064   }
00065   ostringstream inputfifo;
00066   ostringstream outputfifo;
00067 
00068   char *command;
00069   char prompt[30];
00070 
00071   int ifd, ofd;
00072   fd_set iset, oset;
00073 
00074   // this is to liven up the prompt
00075   time_t tstart, tstop;
00076 
00077   inputfifo << tempdir << "ripper";
00078   if( *name ) {
00079     inputfifo << "." << name;
00080   }
00081   inputfifo << ".input";
00082 
00083   outputfifo << tempdir << "ripper";
00084   if( *name ) {
00085     outputfifo << "." << name;
00086   }
00087   outputfifo << ".output";
00088 
00089   // opening the FIFOs will block unless
00090   // the other end is already opened.
00091   // To prevent deadlock with ripper,
00092   // we mut open in nonblocking mode here
00093   if((ifd = open(outputfifo.str().c_str(), O_RDONLY|O_NONBLOCK)) < 0) {
00094     cerr << "error: FIFO cannot be opened [" << inputfifo.str() << "]" << endl;
00095     cerr << "is ripper listening?" << endl;
00096     exit(1);
00097   }
00098   if((ofd = open(inputfifo.str().c_str(), O_WRONLY|O_NONBLOCK|O_APPEND)) < 0) {
00099     cerr << "error: FIFO cannot be opened [" << outputfifo.str() << "]" << endl;
00100     cerr << "is ripper listening?" << endl;
00101     exit(1);
00102   }
00103 
00104   cout << "Welcome to jack. Command tokens are separated by spaces."
00105     "\nType help for a list of commands." << endl;
00106 
00107   FD_ZERO(&iset); FD_SET(ifd, &iset);
00108   FD_ZERO(&oset); FD_SET(ofd, &oset);
00109 
00110   // initialize readline
00111 
00112   char c;
00113   int size;
00114   bool quit = false;
00115   tstart = 0;
00116   while(!quit) {
00117 
00118     int retval = select(ifd+1, &iset, NULL, NULL, NULL); 
00119     if( retval > 0 ) {
00120       // data available
00121       if( (size = read(ifd, &c, 1)) >= 0) {
00122         if( c == '\r' ) { // end of communication marker
00123           time(&tstop);
00124           if( tstart > 0 ) {
00125             sprintf(prompt, "\ncomputation took %g seconds\n> ", 
00126                     difftime(tstop, tstart));
00127           } else {
00128             strcpy(prompt, "\n> ");
00129           }
00130           command = readline(prompt);
00131           if( command && *command ) {
00132             int k = 0;
00133             int n = strlen(command);
00134             do {
00135               retval = select(ofd+1, NULL, &oset, NULL, NULL);
00136               if( retval ) {
00137                 size = write(ofd, command + k, strlen(command + k));
00138                 k += size;
00139               }
00140             } while( k < n );
00141             if( strncmp(command,"quit",4) == 0) {
00142               quit = true;
00143             }
00144             add_history(command);
00145             free(command);
00146             command = (char *)NULL;
00147           }
00148           size = write(ofd, "\n", 1);
00149           time(&tstart);
00150         } else {
00151           cout << c;
00152         }
00153       } // else bad read
00154     }
00155   }
00156 
00157   // if we exit before ripper, the fifos don't get unlinked
00158   struct stat buf1, buf2;
00159   do {
00160     sleep(1);
00161   } while(fstat(ifd, &buf1) || fstat(ofd, &buf2));
00162 
00163   return 0;
00164 }
00165 

Generated on Wed May 29 11:37:14 2002 for MarkovPR by doxygen1.2.15