// Perforce Skill Server by Shiv Sikand (c) SGI 1999 // $Id$ #include <clientapi.h> #include <unistd.h> #include <signal.h> #include <signaler.h> #include "time.h" #include <fcntl.h> #define STRLEN 1024 #define IPCIOBUFF 4096 // default input/output for -i/-o commands int redirect_in=0; FILE *redirect_out=stdout; FILE *logfile; int error=0; volatile sig_atomic_t keep_going = 1; int olength=0; // argument handling extern "C" int split_quote_args (char *s, char **argv, char **dp); extern "C" char *handle_options (char *s,char *port,char *xfile, char *ifile, char *ofile, char *client, char *dir,char *user,int *appendp); extern "C" void catch_alarm(int sig); // Do some subclassing to handle different pipes class skillClientUser : public ClientUser { public: void InputData( StrBuf *strbuf, Error *e ); void OutputInfo( char level, const_char *data ); void OutputBinary( const_char *data, int length ); void OutputText( const_char *data, int length ); void OutputError( const_char *errBuf ); }; void skillClientUser::OutputError( const_char *errBuf ) { error=1; olength=olength+strlen(errBuf); if(olength>IPCIOBUFF) { olength=olength-IPCIOBUFF; } fwrite( errBuf, 1, strlen( errBuf ), stdout); } void skillClientUser::InputData( StrBuf *buf, Error *e ) { int n; int f; buf->Clear(); do { char *b = buf->Alloc( FileBufferSize ); //n = freadText( b, FileBufferSize, redirect_in ); n = read( redirect_in, b, FileBufferSize); buf->SetEnd( b + n ); } while( n > 0 ); buf->Terminate(); } void skillClientUser::OutputText( const_char *data, int length ) { olength=olength+length; if(olength>IPCIOBUFF) { olength=olength-IPCIOBUFF; } fwrite( data, 1, length, redirect_out ); } void skillClientUser::OutputBinary( const_char *data, int length ) { olength=olength+length; if(olength>IPCIOBUFF) { olength=olength-IPCIOBUFF; } fwrite( data, 1, length, redirect_out ); } void skillClientUser::OutputInfo( char level, const_char *data ) { switch( level ) { default: case '0': break; case '1': fprintf(redirect_out, "... " ); olength=olength+4; if(olength>IPCIOBUFF) { olength=olength-IPCIOBUFF; }break; case '2': fprintf(redirect_out, "... ... " ); olength=olength+8; if(olength>IPCIOBUFF) { olength=olength-IPCIOBUFF; }break; } olength=olength+strlen(data)+1; if(olength>IPCIOBUFF) { olength=olength-IPCIOBUFF; } fwrite( data, 1, strlen( data ), redirect_out ); fputc( '\n', redirect_out ); } void main () { int argc; int z; pid_t pid; int cnt; char d[STRLEN], *argv[STRLEN]; char port[STRLEN], xfile[STRLEN], mclient[STRLEN], dir[STRLEN]; char user[STRLEN], ofile[STRLEN],ifile[STRLEN]; char buff[STRLEN]; char fname[STRLEN]; int append; StrBuf sptr; int i,x_mode=0,padspacing=0; char s[STRLEN], *s1, *d1; FILE *xfile_in; FILE *last_redirect_out; int last_redirect_in; struct timespec rqtp; Error e; skillClientUser ui; ClientApi client( &ui ); signaler.Catch(); /* Disable buffering for Skill IPC interface setvbuf(stderr,NULL, _IONBF, 0 ); setvbuf(stdout,NULL, _IONBF, 0 );*/ // Set up signal handler signal(SIGHUP, catch_alarm); signal(SIGINT, catch_alarm); signal(SIGQUIT, catch_alarm); signal(SIGKILL, catch_alarm); signal(SIGPIPE, catch_alarm); signal(SIGTERM, catch_alarm); // Connect to server client.Init( &e ); //e.Abort(); // Run the command "argv[1] argv[2...]" while(keep_going) { strcpy(s, ""); gets(s); // gets will keep returning EOFS if it the parent dies if(!strcmp("",s)) { keep_going=0; } d1 = d; s1 = handle_options (s, port, xfile, ifile, ofile, mclient, dir, user, &append); argc = split_quote_args (s1, argv, &d1); if (*port) { client.SetPort(port); } if (*ofile) { // p4 changes -o > filename // now called as -o filename changes last_redirect_out = redirect_out; if(append) redirect_out=fopen(ofile,"a"); else redirect_out=fopen(ofile,"w"); if(!redirect_out) { printf("Error: Failed to open append pipe %s\n",ofile); continue; } } if(*ifile) { // p4 submit -i < filename // now called as -i filename submit -i last_redirect_in = redirect_in; redirect_in=open(ifile,O_RDONLY); if(!redirect_in) { printf("Error: Failed to open read pipe %s\n",ifile); continue; } } if (*xfile) { // this is the -x command xfile_in=fopen(xfile, "r"); if(!xfile_in) { printf("Failed to open -x file %s for read\n",xfile); continue; } x_mode=1; } if (*mclient) { client.SetClient(mclient); } if (*dir) { client.SetCwd(dir); } if (*user) { client.SetUser(user); } // Run the command if(x_mode) { // -x file mode // open the file for read // set up the args // and iterate over the contents of the file while (fgets (buff, STRLEN, xfile_in)) { client.SetArgv( argc - 1, argv + 1 ); // strip off the newline olength=0; sptr.Set(buff,strlen(buff)-1); client.SetVar("", (StrPtr *)&sptr); client.Run(argv[0]); } fclose(xfile_in); x_mode=0; } else { // Single command mode olength=0; client.SetArgv( argc - 1, argv + 1 ); client.Run(argv[0]); } if(*ofile) { // Reset fclose(redirect_out); redirect_out=last_redirect_out; } if(*ifile) { // Reset close(redirect_in); redirect_in=last_redirect_in; } // always write this to stdout fflush(stderr); if(error) { fflush(stdout); fprintf(stdout,"p4skillservercmddoneerr"); error=0; } else { fflush(stdout); fprintf(stdout,"p4skillservercmddone"); } fflush(stdout); } // Close connection client.Final( &e ); //e.Abort(); exit(0); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 3329 | Shiv Sikand |
Spotted weird sync problem between Solaris and Linux Backed out experimental padding change in main.C and made sure that Linux and Solaris builds were identical |
||
#2 | 3002 | Shiv Sikand |
Changes for 2002.2 API build Linux Makefile |
||
#1 | 1675 | Shiv Sikand | New 2.2 tree |