void power_off(void) { imx233_system_prepare_shutdown(); /* power down */ HW_POWER_RESET = BF_OR(POWER_RESET, UNLOCK_V(KEY), PWD(1)); while(1); }
#include <nss.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <support/support.h> #include "nss_test.h" /* The data in these tables is arbitrary, but the merged data based on the first two tables will be compared against the expected data in the pwd_expected table, and the tests[] array. */ static struct passwd pwd_table_1[] = { PWD (100), PWD (30), PWD (200), PWD (60), PWD (20000), PWD_LAST () }; static struct passwd pwd_table_2[] = { PWD (5), PWD_N(200, "name30"), PWD (16), PWD_LAST () }; void
#include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <support/support.h> #include "nss_test.h" static int hook_called = 0; /* Note: the values chosen here are arbitrary; they need only be unique within the table. However, they do need to match the "pwdids" array further down. */ static struct passwd pwd_table[] = { PWD (100), PWD (30), PWD (200), PWD (60), PWD (20000), PWD_LAST () }; void _nss_test1_init_hook(test_tables *t) { hook_called = 1; t->pwd_table = pwd_table; } static int
//Starts the server and listens for connections void Server::start(){ //check if directory exists //If it doesn't , try to create the directory char temp[1024]; //Get address info purposes struct sockaddr_storage otherAddr, otherAddr2; //Connectors address information socklen_t otherAddrLen, otherAddrLen2; int rv; int i; //Socket purposes int newfd; int newfd2; //port numbers unsigned short dataPort; //Handling child processes struct sigaction sa; //Char buffers char buffer[DATA_SIZE]; //String vector vector<string> tokens; //extra string(s) string errMsg = INVCOM; //Copy the string into character array //since chdir() takes char * as argument strncpy( temp, rootDir.c_str() , sizeof(temp) ); temp[ sizeof(temp) - 1 ] = 0; //Check if directory is valid //If no directory create one if( !validDir(temp) ){ if( mkdir(temp, 0777) != 0 ){ perror("mkdir"); exit(1); } } //change directory //call chdir() if(chdir(temp) != 0){ //If chdir fails perror("chdir"); exit(1); } if ( !getPWD() ){ cout << "Unable to get cwd" << endl; exit(1); } //We have now changed the program's pwd to root directory //Now create a socket and bind to the control port and start listening //for connections cs = controlSock = createSocket( controlPort); if(verbose) cout << "Control socket created" << endl; ds = dataSock = createSocket("0"); if(verbose) cout << "Data socket created" << endl; dataPort = getPort(dataSock); //Now we have successfully created the socket //and bound it to the control port //Start listening for connections //Entering the listening loop if ( listen (controlSock , BACKLOG) != 0 ) { perror("listen"); close(controlSock); exit(1); } if( listen(dataSock , BACKLOG) != 0 ){ perror("listen"); close(dataSock); exit(1); } //handle dead processes sa.sa_handler = sigchldHandler; //read all dead processes sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; if( sigaction( SIGCHLD, &sa , NULL ) == -1 ){ perror("sigaction"); exit(1); } //Handle user interrupts signal(SIGINT, userIntHandler); cout << "Waiting for connections ... " << endl; while(1){ otherAddrLen = sizeof ( otherAddr) ; newfd = accept ( controlSock , (struct sockaddr *) &otherAddr , &otherAddrLen ); cout << "Connection from " << getIPFromAddr(&otherAddr) << ":" << getPortFromAddr(&otherAddr) << endl; commsock = newfd; send(newfd, (unsigned short *)&dataPort, 2, 0); otherAddrLen2 = sizeof otherAddr2; newfd2 = accept(dataSock, (struct sockaddr *) &otherAddr2, &otherAddrLen2 ); datacommsock = newfd2; cout << "Connection to data socket from client port " << getPortFromAddr(&otherAddr2) << endl; if( fork() == 0 ){ //The code in this block is executed by the child process close(controlSock); //Child doesn't require the control socket close(dataSock); if(verbose){ cout << "Closing listener sockets" << endl; cout << "Child process created for communication with client" << endl; } if (dup2( newfd , 0 ) != 0 ){ perror("dup2"); exit(1); } do{ if(fgets( buffer, DATA_SIZE, stdin ) == NULL){ close(newfd); exit(1); } //Remove carriage return and new line characters for(rv = 0; rv < DATA_SIZE ; rv++){ if(buffer[rv] == '\r'){ buffer[rv] = 0; break; } if(buffer[rv] == '\n'){ buffer[rv] = 0; break; } } //Read buffer and find what command it is //Call the corresponding method string s(buffer); //convert the character array into string if(verbose){ cout << "Received command " + s << endl; } istringstream iss(s); //copy the tokens into the string vector copy( istream_iterator<string>(iss), istream_iterator<string>() , back_inserter<vector<string> >(tokens) ); //Copied the tokens into tokens rv = tokens.size(); if(rv > 0){ //If there is atleast one word if(tokens[0].compare("ls") == 0){ //The client requested a file listing ls(s, newfd2); } else if(tokens[0].compare("quit") == 0){ //The client closed the connection break; } else if(tokens[0].compare("cd") == 0){ //The client requested a directory change if(rv == 2){ cd(tokens[1], newfd2); } else{ sendMessage( errMsg.c_str() , errMsg.length() , ERROR, NF, dataSock ); } } else if( tokens[0].compare("pwd") == 0 ){ //Client requested a pwd PWD(newfd2); } else if(tokens[0].compare("get") == 0){ string temp=""; for(i=1; i < rv;i++){ temp = temp + tokens[i] + " "; } temp = temp.substr(0, temp.length()-1 ); getFile(temp, newfd2); } else if(tokens[0].compare("put") == 0){ string temp=""; for(i=1; i < rv;i++){ temp = temp + tokens[i] + " "; } temp = temp.substr(0, temp.length()-1 ); putFile(temp, newfd2); } else{ sendMessage( errMsg.c_str() , errMsg.length() , ERROR, NF, newfd2 ); } } tokens.clear(); //clear the tokens }while (1); //The client closed the connection //So, close the socket and quit the child process close(newfd); close(newfd2); cout << "Connection closed" << endl; exit(1); } close(newfd); } close(controlSock); }
status_t handle_request( RequestPB *pb ) { HTTPResponse response; pb->closeConnection = false; const char *sPtr; // General purpose string pointer // Temporary buffers int32 fieldSize = 1024; char fieldValue[1024]; char headBuffer[1024]; int32 contentLength = 0; // **** // Get PATH_INFO and SCRIPT_NAME from path; Setup absPath of CGI // **** char PATH_INFO[1024]; char SCRIPT_NAME[256]; // Get SCRIPT_NAME strxcpy( SCRIPT_NAME, pb->resourcePath->Path(), 255 ); strxcpy( PATH_INFO, pb->brURI->path+strlen( pb->resourcePath->Path()+1 ), 1023 ); // Make absolute CGI path from web-directory and requested path BPath absPath( pb->webDirectory->Path(), pb->resourcePath->Path()+1 ); // **** // Make sure CGI exists and Check Permission // **** if( pb->authenticate && !pb->realms->Authenticate( pb->request, &response, pb->brURI->path, absPath.Path(), S_IXOTH ) ) { pb->Logprintf( "%ld Status-Line: %s\n", pb->sn, response.GetStatusLine() ); return B_OK; } // **** // Setup meta-variables in new environment // **** char params[2048]; // Should we use the CGI script command line? // This should be done on a GET or HEAD where the URL query string // does not contain any unencoded '=' characters. if( *pb->brURI->query && ((pb->request->GetMethod() == METHOD_GET)||(pb->request->GetMethod() == METHOD_HEAD))&& !strchr( pb->brURI->query, '=' ) ) { uri_unescape_str( params, pb->brURI->query, 2048 ); } else uri_unescape_str( params, pb->brURI->params, 2048 ); // Environment to be used by the CGI Environment env( pb->environ ); // AUTH_TYPE if( pb->request->FindHeader( kHEAD_AUTHORIZATION, fieldValue, fieldSize ) ) { sPtr = fieldValue; sPtr = get_next_token( headBuffer, sPtr, fieldSize ); env.PutEnv( "AUTH_TYPE", headBuffer ); if( strcasecmp( headBuffer, "Basic" ) == 0 ) { // REMOTE_USER sPtr = get_next_token( headBuffer, sPtr, fieldSize ); decode_base64( headBuffer, headBuffer, fieldSize ); sPtr = get_next_token( fieldValue, headBuffer, fieldSize, ":" ); env.PutEnv( "REMOTE_USER", fieldValue ); } } // CONTENT_LENGTH if( pb->request->FindHeader( kHEAD_LENGTH, fieldValue, fieldSize ) ) env.PutEnv( "CONTENT_LENGTH", fieldValue ); // CONTENT_TYPE if( pb->request->FindHeader( kHEAD_TYPE, fieldValue, fieldSize ) ) env.PutEnv( "CONTENT_TYPE", fieldValue ); // GATEWAY_INTERFACE env.PutEnv( "GATEWAY_INTERFACE", "CGI/1.1" ); // HTTP_* for( int i=0; (sPtr = pb->request->HeaderAt( i )); i++ ) { sPtr = get_next_token( fieldValue, sPtr, fieldSize, ":" ); sprintf( headBuffer, "HTTP_%s", http_to_cgi_header( fieldValue ) ); sPtr = get_next_token( fieldValue, sPtr, fieldSize, ":" ); env.PutEnv( headBuffer, fieldValue ); } // PATH_INFO env.PutEnv( "PATH_INFO", PATH_INFO ); // PATH_TRANSLATED if( *PATH_INFO ) { BPath pathTrans( pb->webDirectory->Path(), PATH_INFO+1 ); if( pathTrans.Path() ) env.PutEnv( "PATH_TRANSLATED", pathTrans.Path() ); } // QUERY_STRING env.PutEnv( "QUERY_STRING", pb->brURI->query ); // REMOTE_ADDR env.PutEnv( "REMOTE_ADDR", pb->request->GetRemoteHost() ); // REMOTE_HOST // Ya, right... like were going to waste valuable time with a DNS lookup! env.PutEnv( "REMOTE_HOST", "" ); // REMOTE_IDENT // Ha! Perform an Ident lookup... I don't think so. // REQUEST_METHOD env.PutEnv( "REQUEST_METHOD", http_find_method( pb->request->GetMethod() ) ); // SCRIPT_NAME env.PutEnv( "SCRIPT_NAME", SCRIPT_NAME ); // SERVER_NAME env.PutEnv( "SERVER_NAME", pb->brURI->host ); // SERVER_PORT sprintf( fieldValue, "%u", pb->request->GetPort() ); env.PutEnv( "SERVER_PORT", fieldValue ); // SERVER_PROTOCOL env.PutEnv( "SERVER_PROTOCOL", pb->request->GetVersion() ); // SERVER_SOFTWARE env.PutEnv( "SERVER_SOFTWARE", "RobinHood" ); // PWD BPath PWD( absPath ); PWD.GetParent( &PWD ); env.PutEnv( "PWD", PWD.Path() ); // **** // Create pipes // **** pid_t pid; int ipipe[2], opipe[2]; if( pipe(ipipe) < 0 ) { response.SetHTMLMessage( 500, "Pipe creation failed!" ); pb->request->SendReply( &response ); return B_OK; } if( pipe(opipe) < 0 ) { close( ipipe[0] ); close( ipipe[1] ); response.SetHTMLMessage( 500, "Pipe creation failed!" ); pb->request->SendReply( &response ); return B_OK; } // **** // Setup args for execve() // **** // Setup command string; copy CGI path and append params char command[4096]; sPtr = strxcpy( command, absPath.Path(), 4095 ); // Disabled because of security risk /* if( *params && !strpbrk( params, ";&" ) ) { sPtr = strxcpy( (char *)sPtr, " ", command+4095-sPtr ); strxcpy( (char *)sPtr, params, command+4095-sPtr ); // Append params }*/ char *args[4]; args[0] = "/bin/sh"; args[1] = "-c"; args[2] = command; args[3] = NULL; pb->Logprintf( "%ld Exec: %s\n", pb->sn, command ); // **** // Start sub-process using fork() dup2() and exec() // **** pid = fork(); if( pid == (pid_t)0 ) // If we are the child process... { // Make this process the process group leader setpgid( 0, 0 ); fflush(stdout); // sync stdout... // Set pipes to stdin and stdout if( dup2( opipe[0], STDIN_FILENO ) < 0 ) exit( 0 ); if( dup2( ipipe[1], STDOUT_FILENO ) < 0 ) exit( 0 ); // Close unused ends of pipes close( opipe[1] ); close( ipipe[0] ); // Set Current Working Directory to that of script chdir( PWD.Path() ); // Execute CGI in this process by means of /bin/sh execve( args[0], args, env.GetEnvironment() ); exit( 0 ); // If for some reason execve() fails... } else if( pid < (pid_t)0 ) // Something Bad happened! { close( opipe[0] ); close( opipe[1] ); close( ipipe[0] ); close( ipipe[1] ); response.SetHTMLMessage( 500, "Fork failed!" ); pb->request->SendReply( &response ); return true; } // Close unused ends of pipes close( opipe[0] ); close( ipipe[1] ); // **** // Talk to CGI // **** bool persistant = true; // Defined to make code easier to read int inDes = ipipe[0]; // input file descripter int outDes = opipe[1]; // output file descripter // Make a BDataIO wrapper for the in and out pipes DesIO pipeIO( inDes, outDes ); // If the request contains a content body, feed it into stdin of the CGI script if( pb->request->GetContentLength() > 0 ) pb->request->SendBody( &pipeIO ); // Buffer the response body for better performance response.SetBodyBuffering( true ); // Read first line to detect use of Non-Parsed Header Output io_getline( &pipeIO, headBuffer, fieldSize ); // Strip the '\r' character if there is one int32 size; size = strlen( headBuffer )-1; if( headBuffer[size] == '\r' ) headBuffer[size] = 0; // Is NPH Output? if( strncmp( "HTTP/", headBuffer, 5 ) == 0 ) { DataIOPump ioPump; BufferedIO bufio( pb->request->GetReplyIO() ); bufio.DoAllocate(); io_printf( &bufio, "%s\r\n", headBuffer ); ioPump.StartPump( &pipeIO, &bufio, contentLength ); bufio.Flush(); persistant = false; } else // using Parsed Header Output { // Add Date header time_t now; struct tm *brokentime; now = time( NULL ); brTimeLock.Lock(); brokentime = gmtime( &now ); strftime (fieldValue, 256, kHTTP_DATE, brokentime); brTimeLock.Unlock(); response.AddHeader( kHEAD_DATE, fieldValue ); // Add line used to detect NPH as CGI header response.AddHeader( headBuffer ); // Receive the CGI headers response.ReceiveHeaders( &pipeIO ); // If Location header, don't expect any more headers if( (sPtr = response.FindHeader( "Location", fieldValue, fieldSize )) ) { response.SetStatusLine( 302 ); // 302 Moved Temporarily } else { if( (sPtr = response.FindHeader( "Status", fieldValue, fieldSize )) ) { response.RemoveHeader( (char *)sPtr ); // Don't forward to client response.SetStatusLine( fieldValue ); } else response.SetStatusLine( 200 ); } // Don't cache the response if( !response.FindHeader( "Cache-Control", fieldValue, fieldSize ) ) response.AddHeader( "Cache-Control: no-cache" ); if( !response.FindHeader( "Pragma", fieldValue, fieldSize ) ) response.AddHeader( "Pragma: no-cache" ); // Content-Length header? int32 contentLength = 0; if( (sPtr = response.FindHeader( kHEAD_LENGTH, fieldValue, fieldSize )) ) { contentLength = strtol( fieldValue, (char **)&headBuffer, 10 ); response.SetContentLength( contentLength ); } else // No content-length provided; close connection on return { response.AddHeader( "Connection: close" ); persistant = false; } pb->Logprintf( "%ld Status-Line: %s\n", pb->sn, response.GetStatusLine() ); if( pb->request->GetMethod() != METHOD_HEAD ) response.SetMessageBody( &pipeIO ); pb->request->SendReply( &response ); } // Close remaining ends of pipes close( ipipe[0] ); close( opipe[1] ); pb->closeConnection = !persistant; return B_OK; }