]> git.saurik.com Git - apple/security.git/blobdiff - Keychain/ExecCLITool.cpp
Security-222.tar.gz
[apple/security.git] / Keychain / ExecCLITool.cpp
diff --git a/Keychain/ExecCLITool.cpp b/Keychain/ExecCLITool.cpp
deleted file mode 100644 (file)
index b2e94ec..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-
-#include <sys/wait.h>
-#include "ExecCLITool.h"
-#include <Security/utilities.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-#pragma mark -------------------- ExecCLITool implementation --------------------
-
-ExecCLITool::ExecCLITool() : dataRead(NULL),dataLength(0),dataToWrite(NULL),dataToWriteLength(0)
-{
-       stdinpipe[0]=0, stdinpipe[1]=0;
-    stdoutpipe [0]=0, stdoutpipe [1]=0;
-}
-
-ExecCLITool::~ExecCLITool()
-{
-       if (dataRead)
-        free(dataRead);
-    reset();
-}
-
-int ExecCLITool::run(const char *toolPath, const char *toolEnvVar, ...)
-{
-    try
-    {
-        reset();
-        initialize();
-        
-        // try to run the tool
-        switch (pid_t pid = fork())
-        {
-        case 0:                // child
-            {
-                VAArgList arglist;
-                va_list params;
-                va_start(params, toolEnvVar);
-                arglist.set(toolPath,params);
-                va_end(params);
-                child(toolPath,toolEnvVar,arglist);
-            }
-            break;
-        case -1:       // error (in parent)
-            UnixError::throwMe();
-            break;
-        default:       // parent
-            parent(pid);
-            break;
-        }
-    }
-    catch (...)
-    {
-        closeAllPipes();
-        return errno;
-    }
-    
-       closeAllPipes();
-    return 0;
-}
-
-void ExecCLITool::reset()
-{
-       closeAllPipes();
-#if 0
-    if (dataToWrite)
-    {
-        free(dataToWrite);
-        dataToWrite = NULL;
-    }
-    dataToWriteLength = 0;
-#endif
-}
-
-void ExecCLITool::input(const char *data,unsigned int length)
-{
-    if (dataToWrite)
-    {
-        ::free(dataToWrite);
-        dataToWrite = NULL;
-    }
-    dataToWriteLength=length;
-    if (!data)
-        return;
-
-    dataToWrite=reinterpret_cast<char *>(malloc(length));
-    ::memmove(dataToWrite, data, dataToWriteLength);
-}
-
-void ExecCLITool::input(CFStringRef theString, bool appendNULL)
-{
-       // Used mainly for preserving UTF-8 passwords
-    // hdiutil et al require the NULL to be sent as part of the password string from STDIN
-    Boolean isExternalRepresentation = false;
-    CFStringEncoding encoding = kCFStringEncodingUTF8;
-    CFIndex usedBufLen = 0;
-    UInt8 lossByte = 0;
-
-    if (!theString)
-        MacOSError::throwMe(paramErr);
-
-    CFRange stringRange = CFRangeMake(0,CFStringGetLength(theString));
-    // Call once first just to get length
-    CFIndex length = CFStringGetBytes(theString, stringRange, encoding, lossByte,
-        isExternalRepresentation, NULL, 0, &usedBufLen);
-        
-    if (dataToWrite)
-        ::free(dataToWrite);
-    dataToWriteLength=usedBufLen;
-    if (appendNULL)
-    {
-        dataToWriteLength++;
-        dataToWriteLength++;
-}
-
-    dataToWrite=reinterpret_cast<char *>(malloc(dataToWriteLength));
-    length = CFStringGetBytes(theString, stringRange, encoding, lossByte, isExternalRepresentation, 
-        reinterpret_cast<UInt8 *>(dataToWrite), dataToWriteLength, &usedBufLen);
-
-    if (appendNULL)
-    {
-        dataToWrite[dataToWriteLength-1]=0;
-        dataToWrite[dataToWriteLength]='\n';
-    }
-}
-
-void ExecCLITool::initialize()
-{
-    dataLength = 0;                                                            // ignore any previous output on new run
-   
-    if (!dataRead)                                                             // Allocate buffer for child's STDOUT return
-    {
-        dataRead = (char *)malloc(256);
-        if (!dataRead)
-            UnixError::throwMe();
-    }
-
-    // Create pipe to catch tool output
-    if (pipe(stdoutpipe))                                              // for reading data from child into parent
-        UnixError::throwMe();
-
-    if (pipe(stdinpipe))                                               // for writing data from parent to child
-        UnixError::throwMe();
-}
-        
-void ExecCLITool::child(const char *toolPath, const char *toolEnvVar, VAArgList& arglist)
-{
-    // construct path to tool
-    try
-    {
-        char toolExecutable[PATH_MAX + 1];
-        const char *path = toolEnvVar ? getenv(toolEnvVar) : NULL;
-        if (!path)
-            path = toolPath;
-        snprintf(toolExecutable, sizeof(toolExecutable), "%s", toolPath);
-    
-        close(stdoutpipe[0]);                  // parent read
-        close(STDOUT_FILENO);
-        if (dup2(stdoutpipe[1], STDOUT_FILENO) < 0)
-            UnixError::throwMe();
-        close(stdoutpipe[1]);
-
-        close(stdinpipe[1]);                   // parent write
-        close(STDIN_FILENO);
-        if (dup2(stdinpipe[0], STDIN_FILENO) < 0)
-            UnixError::throwMe();
-        close(stdinpipe[0]);
-
-    //  std::cerr << "execl(\"" << toolExecutable << "\")" << std::endl;
-        execv(toolPath, const_cast<char * const *>(arglist.get()));
-    //  std::cerr << "execl of " << toolExecutable << " failed, errno=" << errno << std::endl;
-    }
-    catch (...)
-    {
-        int err = errno;
-//             closeAllPipes();
-        _exit(err);
-    }
-    
-    // Unconditional suicide follows.
-    _exit(1);
-}
-
-void ExecCLITool::parent(pid_t pid)
-{
-       static const int timeout = 300;
-       static const bool dontNeedToWait = false;
-
-    close(stdinpipe[0]);                       // child read
-    close(stdoutpipe[1]);                      // child write
-
-       parentWriteInput();
-
-    parentReadOutput();
-    
-    struct timespec rqtp = {0,};
-    rqtp.tv_nsec = 100000000;          // 10^8 nanoseconds = 1/10th of a second
-    for (int nn = timeout; nn > 0; nanosleep(&rqtp, NULL), nn--)
-    {
-        if (dontNeedToWait)
-            break;
-        int status;
-        switch (waitpid(pid, &status, WNOHANG))
-        {
-        case 0:                                // child still running
-            break;
-        case -1:                       // error
-            switch (errno)
-            {
-            case EINTR:
-            case EAGAIN:       // transient
-                continue;
-            case ECHILD:       // no such child (dead; already reaped elsewhere)
-                CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
-            default:
-                UnixError::throwMe();
-            }
-        default:
-        //  std::cerr << "waitpid succeeded, pid=" << rc << std::endl;
-            return;
-        }
-    }
-}
-
-void ExecCLITool::parentReadOutput()
-{
-    // parent - resulting blob comes in on stdoutpipe[0]
-       unsigned int totalRead = 0;
-       char buffer[kReadBufSize];
-       
-       for (;;)
-    {
-               int thisRead = read(stdoutpipe[0], buffer, kReadBufSize);
-               if (thisRead < 0)
-        {
-                       if (errno==EINTR)                       // try some more
-                continue;
-//                     std::cerr << "abnormal read end:" << errno << std::endl;
-            break;
-               }
-               if (thisRead == 0)                              // normal termination
-        {
-                       dataLength = totalRead;
-//                     std::cerr << "Normal read end" << std::endl;
-                       break;
-               }
-
-               // Resize dataRead if necessary
-        if (kReadBufSize < (totalRead + (unsigned int)thisRead))
-        {
-                       uint32 newLen = dataLength + kReadBufSize;
-                       dataRead = (char *)realloc(dataRead, newLen);
-                       dataLength = newLen;
-               }
-
-               // Append the data to dataRead
-        memmove(dataRead + totalRead, buffer, thisRead);
-               totalRead += thisRead;
-       }
-    close(stdoutpipe[0]);
-
-}
-
-void ExecCLITool::parentWriteInput()
-{
-       if (dataToWriteLength>0)
-    {
-        int bytesWritten = write(stdinpipe[1],dataToWrite,dataToWriteLength);
-        if (bytesWritten < 0)
-            UnixError::throwMe();
-    }
-    close(stdinpipe[1]);
-}
-
-void ExecCLITool::closeAllPipes()
-{
-    for (int ix=0;ix<2;ix++)
-        if (stdoutpipe[ix])
-        {
-            close(stdoutpipe[ix]);
-            stdoutpipe[ix]=0;
-        }
-
-    for (int ix=0;ix<2;ix++)
-        if (stdinpipe[ix])
-        {
-            close(stdinpipe[ix]);
-            stdinpipe[ix]=0;
-        }
-}
-
-#pragma mark -------------------- VAArgList implementation --------------------
-
-int VAArgList::set(const char *path,va_list params)
-{
-    va_list params2;
-    va_copy(params2, params);
-
-       // Count up the number of arguments
-    int nn = 1;
-       while (va_arg(params,const char *) != NULL)
-        nn++;
-    argn = nn;
-    argv = (ArgvArgPtr *)malloc((nn + 1) * sizeof(*argv));
-    if (argv == NULL)
-        return 0;
-
-    nn = 1;
-       argv[0]=path;
-    while ((argv[nn]=va_arg(params2,const char *)) != NULL)
-       nn++;
-    mSet = true;
-    return 0;
-}
-