static bool
SpawnIOChild(char* const* aArgs, PRProcess** aPID,
             PRFileDesc** aFromChildFD, PRFileDesc** aToChildFD)
{
    PRFileDesc* toChildPipeRead;
    PRFileDesc* toChildPipeWrite;
    if (PR_CreatePipe(&toChildPipeRead, &toChildPipeWrite) != PR_SUCCESS)
        return false;
    PR_SetFDInheritable(toChildPipeRead, true);
    PR_SetFDInheritable(toChildPipeWrite, false);

    PRFileDesc* fromChildPipeRead;
    PRFileDesc* fromChildPipeWrite;
    if (PR_CreatePipe(&fromChildPipeRead, &fromChildPipeWrite) != PR_SUCCESS) {
        PR_Close(toChildPipeRead);
        PR_Close(toChildPipeWrite);
        return false;
    }
    PR_SetFDInheritable(fromChildPipeRead, false);
    PR_SetFDInheritable(fromChildPipeWrite, true);

    PRProcessAttr* attr = PR_NewProcessAttr();
    if (!attr) {
        PR_Close(fromChildPipeRead);
        PR_Close(fromChildPipeWrite);
        PR_Close(toChildPipeRead);
        PR_Close(toChildPipeWrite);
        return false;
    }

    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, toChildPipeRead);
    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, fromChildPipeWrite);   

    PRProcess* process = PR_CreateProcess(aArgs[0], aArgs, nullptr, attr);
    PR_DestroyProcessAttr(attr);
    PR_Close(fromChildPipeWrite);
    PR_Close(toChildPipeRead);
    if (!process) {
        LOG(("ntlm_auth exec failure [%d]", PR_GetError()));
        PR_Close(fromChildPipeRead);
        PR_Close(toChildPipeWrite);
        return false;        
    }

    *aPID = process;
    *aFromChildFD = fromChildPipeRead;
    *aToChildFD = toChildPipeWrite;
    return true;
}
示例#2
0
static void
ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsILocalFile *statusFile,
            nsIFile *appDir, int appArgc, char **appArgv)
{
    nsresult rv;

    // Steps:
    //  - mark update as 'applying'
    //  - copy updater into update dir
    //  - run updater w/ appDir as the current working dir

    nsCOMPtr<nsIFile> updater;
    if (!CopyUpdaterIntoUpdateDir(greDir, appDir, updateDir, updater)) {
        LOG(("failed copying updater\n"));
        return;
    }

    // We need to use the value returned from XRE_GetBinaryPath when attempting
    // to restart the running application.
    nsCOMPtr<nsILocalFile> appFile;

#if defined(XP_MACOSX)
    // On OS X we need to pass the location of the xulrunner-stub executable
    // rather than xulrunner-bin. See bug 349737.
    GetXULRunnerStubPath(appArgv[0], getter_AddRefs(appFile));
#else
    XRE_GetBinaryPath(appArgv[0], getter_AddRefs(appFile));
#endif

    if (!appFile)
        return;

#ifdef XP_WIN
    nsAutoString appFilePathW;
    rv = appFile->GetPath(appFilePathW);
    if (NS_FAILED(rv))
        return;
    NS_ConvertUTF16toUTF8 appFilePath(appFilePathW);

    nsAutoString updaterPathW;
    rv = updater->GetPath(updaterPathW);
    if (NS_FAILED(rv))
        return;

    NS_ConvertUTF16toUTF8 updaterPath(updaterPathW);

#else
    nsCAutoString appFilePath;
    rv = appFile->GetNativePath(appFilePath);
    if (NS_FAILED(rv))
        return;

    nsCAutoString updaterPath;
    rv = updater->GetNativePath(updaterPath);
    if (NS_FAILED(rv))
        return;

#endif

    // Get the directory to which the update will be applied. On Mac OSX we need
    // to apply the update to the Foo.app directory which is the parent of the
    // parent of the appDir. On other platforms we will just apply to the appDir.
#if defined(XP_MACOSX)
    nsCAutoString applyToDir;
    {
        nsCOMPtr<nsIFile> parentDir1, parentDir2;
        rv = appDir->GetParent(getter_AddRefs(parentDir1));
        if (NS_FAILED(rv))
            return;
        rv = parentDir1->GetParent(getter_AddRefs(parentDir2));
        if (NS_FAILED(rv))
            return;
        rv = parentDir2->GetNativePath(applyToDir);
    }
#elif defined(XP_WIN)
    nsAutoString applyToDir;
    rv = appDir->GetPath(applyToDir);
#else
    nsCAutoString applyToDir;
    rv = appDir->GetNativePath(applyToDir);
#endif
    if (NS_FAILED(rv))
        return;

#if defined(XP_WIN)
    nsAutoString updateDirPathW;
    rv = updateDir->GetPath(updateDirPathW);

    NS_ConvertUTF16toUTF8 updateDirPath(updateDirPathW);
#else
    nsCAutoString updateDirPath;
    rv = updateDir->GetNativePath(updateDirPath);
#endif

    if (NS_FAILED(rv))
        return;

    // Get the current working directory.
    char workingDirPath[MAXPATHLEN];
    rv = GetCurrentWorkingDir(workingDirPath, sizeof(workingDirPath));
    if (NS_FAILED(rv))
        return;

    if (!SetStatus(statusFile, "applying")) {
        LOG(("failed setting status to 'applying'\n"));
        return;
    }

    // Construct the PID argument for this process.  If we are using execv, then
    // we pass "0" which is then ignored by the updater.
#if defined(USE_EXECV)
    NS_NAMED_LITERAL_CSTRING(pid, "0");
#else
    nsCAutoString pid;
    pid.AppendInt((PRInt32) getpid());
#endif

    int argc = appArgc + 4;
    char **argv = new char*[argc + 1];
    if (!argv)
        return;
    argv[0] = (char*) updaterPath.get();
    argv[1] = (char*) updateDirPath.get();
    argv[2] = (char*) pid.get();
    if (appArgc) {
        argv[3] = workingDirPath;
        argv[4] = (char*) appFilePath.get();
        for (int i = 1; i < appArgc; ++i)
            argv[4 + i] = appArgv[i];
        argv[4 + appArgc] = nsnull;
    } else {
        argv[3] = nsnull;
        argc = 3;
    }

    LOG(("spawning updater process [%s]\n", updaterPath.get()));

#if defined(USE_EXECV)
    chdir(applyToDir.get());
    execv(updaterPath.get(), argv);
#elif defined(XP_WIN)
    _wchdir(applyToDir.get());

    if (!WinLaunchChild(updaterPathW.get(), appArgc + 4, argv))
        return;
    _exit(0);
#else
    PRStatus status;
    PRProcessAttr *attr;

    attr = PR_NewProcessAttr();
    if (!attr)
        goto end;

    status = PR_ProcessAttrSetCurrentDirectory(attr, applyToDir.get());
    if (status != PR_SUCCESS)
        goto end;

#ifdef XP_MACOSX
    CommandLineServiceMac::SetupMacCommandLine(argc, argv, PR_TRUE);
#endif

    PR_CreateProcessDetached(updaterPath.get(), argv, nsnull, attr);
    exit(0);

end:
    PR_DestroyProcessAttr(attr);
    delete[] argv;
#endif
}
示例#3
0
/*
/////////////////////////////////////////////////////////////////////////
// actually run the installation, copying files to and fro
*/
static Pk11Install_Error
DoInstall(JAR *jar, const char *installDir, const char *tempDir,
          Pk11Install_Platform *platform, PRFileDesc *feedback, PRBool noverify)
{
    Pk11Install_File *file;
    Pk11Install_Error ret;
    char *reldir;
    char *dest;
    char *modDest;
    char *cp;
    int i;
    int status;
    char *tempname, *temp;
    StringList executables;
    StringNode *execNode;
    PRProcessAttr *attr;
    PRProcess *proc;
    char *argv[2];
    char *envp[1];
    int errcode;

    ret = PK11_INSTALL_UNSPECIFIED;
    reldir = NULL;
    dest = NULL;
    modDest = NULL;
    tempname = NULL;

    StringList_new(&executables);
    /*
    // Create Temporary directory
    */
    tempname = PR_smprintf("%s/%s", tempDir, TEMPORARY_DIRECTORY_NAME);
    if (PR_Access(tempname, PR_ACCESS_EXISTS) == PR_SUCCESS) {
        /* Left over from previous run?  Delete it. */
        rm_dash_r(tempname);
    }
    if (PR_MkDir(tempname, 0700) != PR_SUCCESS) {
        error(PK11_INSTALL_CREATE_DIR, tempname);
        ret = PK11_INSTALL_CREATE_DIR;
        goto loser;
    }

    /*
    // Install all the files
    */
    for (i = 0; i < platform->numFiles; i++) {
        file = &platform->files[i];

        if (file->relativePath) {
            PRBool foundMarker = PR_FALSE;
            reldir = PR_Strdup(file->relativePath);

            /* Replace all the markers with the directories for which they stand */
            while (1) {
                if ((cp = PL_strcasestr(reldir, ROOT_MARKER))) {
                    /* Has a %root% marker  */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, installDir,
                                       cp + strlen(ROOT_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else if ((cp = PL_strcasestr(reldir, TEMP_MARKER))) {
                    /* Has a %temp% marker */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, tempname,
                                       cp + strlen(TEMP_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else {
                    break;
                }
            }
            if (!foundMarker) {
                /* Has no markers...this isn't really a relative directory */
                error(PK11_INSTALL_BOGUS_REL_DIR, file->relativePath);
                ret = PK11_INSTALL_BOGUS_REL_DIR;
                goto loser;
            }
            dest = reldir;
            reldir = NULL;
        } else if (file->absolutePath) {
            dest = PR_Strdup(file->absolutePath);
        }

        /* Remember if this is the module file, we'll need to add it later */
        if (i == platform->modFile) {
            modDest = PR_Strdup(dest);
        }

        /* Remember is this is an executable, we'll need to run it later */
        if (file->executable) {
            StringList_Append(&executables, dest);
            /*executables.Append(dest);*/
        }

        /* Make sure the directory we are targetting exists */
        if (make_dirs(dest, file->permissions)) {
            ret = PK11_INSTALL_CREATE_DIR;
            goto loser;
        }

        /* Actually extract the file onto the filesystem */
        if (noverify) {
            status = JAR_extract(jar, (char *)file->jarPath, dest);
        } else {
            status = JAR_verified_extract(jar, (char *)file->jarPath, dest);
        }
        if (status) {
            if (status >= JAR_BASE && status <= JAR_BASE_END) {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      JAR_get_error(status));
            } else {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      mySECU_ErrorString(PORT_GetError()));
            }
            ret = PK11_INSTALL_JAR_EXTRACT;
            goto loser;
        }
        if (feedback) {
            PR_fprintf(feedback, msgStrings[INSTALLED_FILE_MSG],
                       file->jarPath, dest);
        }

/* no NSPR command to change permissions? */
#ifdef XP_UNIX
        chmod(dest, file->permissions);
#endif

        /* Memory clean-up tasks */
        if (reldir) {
            PR_Free(reldir);
            reldir = NULL;
        }
        if (dest) {
            PR_Free(dest);
            dest = NULL;
        }
    }
    /* Make sure we found the module file */
    if (!modDest) {
        /* Internal problem here, since every platform is supposed to have
           a module file */
        error(PK11_INSTALL_NO_MOD_FILE, platform->moduleName);
        ret = PK11_INSTALL_NO_MOD_FILE;
        goto loser;
    }

    /*
    // Execute any executable files
    */
    {
        argv[1] = NULL;
        envp[0] = NULL;
        for (execNode = executables.head; execNode; execNode = execNode->next) {
            attr = PR_NewProcessAttr();
            argv[0] = PR_Strdup(execNode->str);

            /* Announce our intentions */
            if (feedback) {
                PR_fprintf(feedback, msgStrings[EXEC_FILE_MSG], execNode->str);
            }

            /* start the process */
            if (!(proc = PR_CreateProcess(execNode->str, argv, envp, attr))) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_EXEC_FILE, execNode->str);
                ret = PK11_INSTALL_EXEC_FILE;
                goto loser;
            }

            /* wait for it to finish */
            if (PR_WaitProcess(proc, &errcode) != PR_SUCCESS) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_WAIT_PROCESS, execNode->str);
                ret = PK11_INSTALL_WAIT_PROCESS;
                goto loser;
            }

            /* What happened? */
            if (errcode) {
                /* process returned an error */
                error(PK11_INSTALL_PROC_ERROR, execNode->str, errcode);
            } else if (feedback) {
                /* process ran successfully */
                PR_fprintf(feedback, msgStrings[EXEC_SUCCESS], execNode->str);
            }

            PR_Free(argv[0]);
            PR_DestroyProcessAttr(attr);
        }
    }

    /*
    // Add the module
    */
    status = Pk11Install_AddNewModule((char *)platform->moduleName,
                                      (char *)modDest, platform->mechFlags, platform->cipherFlags);

    if (status != SECSuccess) {
        error(PK11_INSTALL_ADD_MODULE, platform->moduleName);
        ret = PK11_INSTALL_ADD_MODULE;
        goto loser;
    }
    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLED_MODULE_MSG],
                   platform->moduleName);
    }

    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLATION_COMPLETE_MSG]);
    }

    ret = PK11_INSTALL_SUCCESS;

loser:
    if (reldir) {
        PR_Free(reldir);
    }
    if (dest) {
        PR_Free(dest);
    }
    if (modDest) {
        PR_Free(modDest);
    }
    if (tempname) {
        PRFileInfo info;
        if (PR_GetFileInfo(tempname, &info) == PR_SUCCESS) {
            if (info.type == PR_FILE_DIRECTORY) {
                /* Recursively remove temporary directory */
                if (rm_dash_r(tempname)) {
                    error(PK11_INSTALL_REMOVE_DIR,
                          tempname);
                    ret = PK11_INSTALL_REMOVE_DIR;
                }
            }
        }
        PR_Free(tempname);
    }
    StringList_delete(&executables);
    return ret;
}
示例#4
0
int main(int argc, char **argv)
{
    PRFileDesc *sock[2];
    PRStatus status;
    PRProcess *process;
    PRProcessAttr *attr;
    char buf[1024];
    PRInt32 nBytes;
    PRInt32 exitCode;
    int idx;

    status = PR_NewTCPSocketPair(sock);
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_NewTCPSocketPair failed\n");
        exit(1);
    }

    status = PR_SetFDInheritable(sock[0], PR_FALSE);
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n",
                PR_GetError(), PR_GetOSError());
        exit(1);
    }
    status = PR_SetFDInheritable(sock[1], PR_TRUE);
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n",
                PR_GetError(), PR_GetOSError());
        exit(1);
    }

    attr = PR_NewProcessAttr();
    if (attr == NULL) {
        fprintf(stderr, "PR_NewProcessAttr failed\n");
        exit(1);
    }

    status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET");
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
        exit(1);
    }

    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
    if (process == NULL) {
        fprintf(stderr, "PR_CreateProcess failed\n");
        exit(1);
    }
    PR_DestroyProcessAttr(attr);
    status = PR_Close(sock[1]);
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }

    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
        strcpy(buf, "ping");
        printf("ping process: sending \"%s\"\n", buf);
        nBytes = PR_Write(sock[0], buf, 5);
        if (nBytes == -1) {
            fprintf(stderr, "PR_Write failed: (%d, %d)\n",
                    PR_GetError(), PR_GetOSError());
            exit(1);
        }
        memset(buf, 0, sizeof(buf));
        nBytes = PR_Read(sock[0], buf, sizeof(buf));
        if (nBytes == -1) {
            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
                    PR_GetError(), PR_GetOSError());
            exit(1);
        }
        printf("ping process: received \"%s\"\n", buf);
        if (nBytes != 5) {
            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
                    nBytes);
            exit(1);
        }
        if (strcmp(buf, "pong") != 0) {
            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
                    buf);
            exit(1);
        }
    }

    status = PR_Close(sock[0]);
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    status = PR_WaitProcess(process, &exitCode);
    if (status == PR_FAILURE) {
        fprintf(stderr, "PR_WaitProcess failed\n");
        exit(1);
    }
    if (exitCode == 0) {
        printf("PASS\n");
        return 0;
    } else {
        printf("FAIL\n");
        return 1;
    }
}
示例#5
0
static nsresult vboxsvcSpawnDaemon(void)
{
    PRFileDesc *readable = nsnull, *writable = nsnull;
    PRProcessAttr *attr = nsnull;
    nsresult rv = NS_ERROR_FAILURE;
    PRFileDesc *devNull;
    // The ugly casts are necessary because the PR_CreateProcessDetached has
    // a const array of writable strings as a parameter. It won't write. */
    char * const args[] = { (char *)VBoxSVCPath, (char *)"--auto-shutdown", 0 };

    // Use a pipe to determine when the daemon process is in the position
    // to actually process requests. The daemon will write "READY" to the pipe.
    if (PR_CreatePipe(&readable, &writable) != PR_SUCCESS)
        goto end;
    PR_SetFDInheritable(writable, PR_TRUE);

    attr = PR_NewProcessAttr();
    if (!attr)
        goto end;

    if (PR_ProcessAttrSetInheritableFD(attr, writable, VBOXSVC_STARTUP_PIPE_NAME) != PR_SUCCESS)
        goto end;

    devNull = PR_Open("/dev/null", PR_RDWR, 0);
    if (!devNull)
        goto end;

    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, devNull);
    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, devNull);
    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardError, devNull);

    if (PR_CreateProcessDetached(VBoxSVCPath, args, nsnull, attr) != PR_SUCCESS)
        goto end;

    // Close /dev/null
    PR_Close(devNull);
    // Close the child end of the pipe to make it the only owner of the
    // file descriptor, so that unexpected closing can be detected.
    PR_Close(writable);
    writable = nsnull;

    char msg[10];
    RT_ZERO(msg);
    if (   PR_Read(readable, msg, sizeof(msg)-1) != 5
        || strcmp(msg, "READY"))
    {
        /* If several clients start VBoxSVC simultaneously only one can
         * succeed. So treat this as success as well. */
        rv = NS_OK;
        goto end;
    }

    rv = NS_OK;

end:
    if (readable)
        PR_Close(readable);
    if (writable)
        PR_Close(writable);
    if (attr)
        PR_DestroyProcessAttr(attr);
    return rv;
}
示例#6
0
int
main(int argc, char* argv[])
{
  PRStatus status;

  // launch daemon
  printf("### launch daemon...\n");

  PRProcessAttr *attributes = PR_NewProcessAttr();
  if (attributes == nsnull) {
    printf("PR_NewProcessAttr() failed.\n");
    return -1;
  }

  PRProcess *daemon = PR_CreateProcess("nsDnsAsyncLookup", nsnull, nsnull, attributes);
  if (daemon == nsnull) {
    printf("PR_CreateProcess failed.\n");
  } else {
    //    status = PR_DetachProcess(daemon);
    //if (status != 0)
    //  printf("PR_DetachProcess returned %d\n", status);
    //daemon = nsnull;
  }

  PR_DestroyProcessAttr(attributes);

  // create socket and connect to daemon
  int socket_fd = 0;


  bool notDone = true;
  char buf[1024];

  while(notDone) {
    int status = 0;
    fd_set fdset;

    FD_ZERO(&fdset);
    FD_SET(fileno(stdin), &fdset);
    if (socket_fd > 0)
      FD_SET(socket_fd, &fdset);
	   
    status = select(getdtablehi(), &fdset, 0, 0, 0);
    if (status <= 0)
      {
	fprintf(stderr, "%s: select() returned %d\n", argv[0], status);
	exit(-1);
      }

    // which fd is set?

    if (FD_ISSET(fileno(stdin), &fdset))
      {
	char *line = fgets(buf, sizeof(buf)-1, stdin);
	line = string_trim(line);
	
	if(!strcmp(line, "quit") || !strcmp(line, "exit"))
	  {
	    fprintf(stderr, "bye now.\n");
	    notDone = false;
	  }
	else if (!strncmp(line, "abort ", 6))
	  {
	    // abort id
	  }
	else if (strchr(line, ' ') || strchr(line, '\t'))
	  {
	    fprintf(stderr, "%s: unrecognized command %s.\n", argv[0], line);
	  }
	else
	  {
	    fprintf(stderr, "%s: looking up %s...\n", argv[0], line);
	    // initiate dns lookup
	    socket_fd = async_dns_lookup(line);
	  }
      }

    if (socket_fd && FD_ISSET(socket_fd, &fdset))
      {
	// read from socket, parse results
	int size = read(socket_fd, buf, 1024);
	if (size > 0)
	  {
	    // parse buffer into hostent
	    char *p = buf;
	    fprintf(stderr, "bytes read: %d\n", size);
	    fprintf(stderr, "response code: %d\n", *(int *)p);
	    p += sizeof(int);

	    for (int i=0; i < size; i++) {
	      if (!(i%8))
		fprintf(stderr, "\n");
	      fprintf(stderr, "%2.2x ",(unsigned char)buf[i]);
	    }
	    fprintf(stderr, "\n");
	    hostent *h;
	    h = bytesToHostent(p);
	  }
	close(socket_fd);
	socket_fd = 0;
      }
  }

  return 0;
}