main.C #1

  • //
  • guest/
  • robert_yu/
  • perforce/
  • cdsp4/
  • release/
  • 2.2/
  • skillserver/
  • main.C
  • View
  • Commits
  • Open Download .zip Download (6 KB)
// 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
#1 4529 robert_yu p4 integrate from public/perforce/cdsp4/release/2.2/...
//guest/perforce_software/cdsp4/release/2.2/skillserver/main.C
#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