Example #1
0
/* GetObjModDate
 *  extract mod date from a path
 */
rc_t KDBGetObjModDate ( const KDirectory *dir, KTime_t *mtime )
{
    /* HACK ALERT - there needs to be a proper way to record modification times */
    
    /* this only tells the last time the table was locked,
       which may be close to the last time it was modified */
    rc_t rc = KDirectoryDate ( dir, mtime, "lock" );
    if ( rc == 0 )
        return 0;

    if ( GetRCState ( rc ) == rcNotFound )
    {
        rc = KDirectoryDate ( dir, mtime, "sealed" );
        if ( rc == 0 )
            return 0;
    }

    /* get directory timestamp */
    rc = KDirectoryDate ( dir, mtime, "." );
    if ( rc == 0 )
        return 0;

    * mtime = 0;
    return rc;
}
Example #2
0
static
rc_t TarNode_Touch(const TarNode* cself)
{
    rc_t rc = 0;

    if( cself->xml_path != NULL ) {
        KDirectory* dir = NULL;
        if( (rc = KDirectoryNativeDir(&dir)) == 0 ) {
            KTime_t dt;
            if( (rc = KDirectoryDate(dir, &dt, "%s", cself->xml_path)) == 0 ) {
                if( dt != cself->mtime ) {
                    const KFile* kfile = NULL;
                    DEBUG_MSG(8, ("%s: updating tar %s\n", __func__, cself->xml_path));
                    if( (rc = KDirectoryOpenFileRead(dir, &kfile, "%s", cself->xml_path)) == 0 ) {
                        const KXMLMgr* xmlmgr;
                        if( (rc = XML_MgrGet(&xmlmgr)) == 0 ) {
                            const KXMLDoc* xmldoc = NULL;
                            if( (rc = KXMLMgrMakeDocRead(xmlmgr, &xmldoc, kfile)) == 0 ) {
                                const KXMLNodeset* ns = NULL;
                                if( (rc = KXMLDocOpenNodesetRead(xmldoc, &ns, "/TAR")) == 0 ) {
                                    uint32_t count = 0;
                                    if( (rc = KXMLNodesetCount(ns, &count)) == 0 ) {
                                        if( count != 1 ) {
                                            rc = RC(rcExe, rcDoc, rcValidating, rcData, rcInvalid);
                                        } else {
                                            const KXMLNode* n = NULL;
                                            if( (rc = KXMLNodesetGetNodeRead(ns, &n, 0)) == 0 ) {
                                                char errmsg[4096];
                                                const TarFileList* new_files;
                                                if( (rc = TarNode_MakeFileList(n, &new_files, errmsg, cself->rel_path, cself->node.name)) != 0 ) {
                                                    LOGERR(klogErr, rc, errmsg);
                                                } else {
                                                    TarFileList_Release(cself->files);
                                                    ((TarNode*)cself)->files = new_files;
                                                    ((TarNode*)cself)->mtime = dt;
                                                }
                                                ReleaseComplain(KXMLNodeRelease, n);
                                            }
                                        }
                                    }
                                    ReleaseComplain(KXMLNodesetRelease, ns);
                                }
                                ReleaseComplain(KXMLDocRelease, xmldoc);
                            }
                        }
                        ReleaseComplain(KFileRelease, kfile);
                    }
                }
            }
            ReleaseComplain(KDirectoryRelease, dir);
        }
    }
    return rc;
}
Example #3
0
/* ModDate
 *  get modification date
 */
LIB_EXPORT rc_t CC KTableModDate ( const KTable *self, KTime_t *mtime )
{
    rc_t rc;

    if ( mtime == NULL )
        rc = RC ( rcDB, rcTable, rcAccessing, rcParam, rcNull );
    else
    {
        if ( self == NULL )
            rc = RC ( rcDB, rcTable, rcAccessing, rcSelf, rcNull );
        else
        {
            /* HACK ALERT - there needs to be a proper way to record modification times */
            const KDirectory *dir = self -> dir;

            /* this only tells the last time the table was locked,
               which may be close to the last time it was modified */
            rc = KDirectoryDate ( dir, mtime, "lock" );
            if ( rc == 0 )
                return 0;

            if ( GetRCState ( rc ) == rcNotFound )
            {
                rc = KDirectoryDate ( dir, mtime, "sealed" );
                if ( rc == 0 )
                    return 0;
            }

            /* get directory timestamp */
            rc = KDirectoryDate ( dir, mtime, "." );
            if ( rc == 0 )
                return 0;
        }

        * mtime = 0;
    }

    return rc;
}
Example #4
0
static
rc_t XMLThread( const KThread *self, void *data )
{
    KDirectory *dir = NULL;

    PLOGMSG(klogInfo, (klogInfo, "XML sync thread started with $(s) sec", PLOG_U32(s), g_xml_sync));
    do {
        rc_t rc = 0;
        KTime_t dt = 0;

        DEBUG_MSG(8, ("XML sync thread checking %s\n", g_xml_path));
        if( (rc = KDirectoryNativeDir(&dir)) == 0 ) {
            rc = KDirectoryDate(dir, &dt, "%s", g_xml_path);
            ReleaseComplain(KDirectoryRelease, dir);
        }
        if( rc == 0 ) {
            if( dt != g_xml_mtime ) {
                const FSNode* new_root = NULL;
                PLOGMSG(klogInfo, (klogInfo, "File $(f) changed ($(m) <> $(d)), updating...",
                    PLOG_3(PLOG_S(f),PLOG_I64(m),PLOG_I64(d)), g_xml_path, g_xml_mtime, dt));
                if( XML_Open(g_xml_path, &new_root) == 0 ) {
                    if( (rc = XMLLock(true)) == 0 ) {
                        const FSNode* old_root = g_root;
                        g_root = new_root;
                        g_xml_mtime = dt;
                        XMLUnlock();
                        FSNode_Release(old_root);
                        PLOGMSG(klogInfo, (klogInfo, "Data from $(f) updated successfully", PLOG_S(f), g_xml_path));
                    }
                }
            } else {
                DEBUG_MSG(8, ("XML sync thread up-to-date %s\n", g_xml_path));
            }
        } else {
            LOGERR(klogErr, rc, g_xml_path);
        }
        SRAList_PostRefresh();
        sleep(g_xml_sync);
    } while( g_xml_sync > 0 );
    LOGMSG(klogInfo, "XML sync thread ended");
    return 0;
}
Example #5
0
static rc_t VDBDependenciesReportDepend1(const VDBDependencies *self,
    const ReportFuncs *f,
    uint32_t count, uint32_t indent, bool toreport, uint32_t *missing)
{
    KDirectory *dir = NULL;
    rc_t rc = 0;
    uint32_t i = ~0;

    assert(missing);

    *missing = 0;

    for (i = 0; i < count; ++i) {
        bool isMissing = false;
        bool local = false;
        const char* seq_id = "";
        const char* path = NULL;
        rc = VDBDependenciesSeqId(self, &seq_id, i);
        if (rc != 0 && toreport)
            reportErrorStrInt(indent, rc, "VDBDependenciesSeqId",
                "origin", "VDatabaseListDependencies", "idx", i);
        if (rc == 0) {
            rc = VDBDependenciesLocal(self, &local, i);
            if (rc != 0 && toreport) {
                reportErrorStrInt(indent, rc,
                    "VDBDependenciesLocal",
                    "origin", "VDatabaseListDependencies", "idx", i);
            }
        }
        if (rc == 0) {
            rc = VDBDependenciesPath(self, &path, i);
            if (rc != 0 && toreport) {
                reportErrorStrInt(indent, rc, "VDBDependenciesPath",
                    "origin", "VDatabaseListDependencies", "idx", i);
            }
        }
        if (rc == 0) {
            if (!local && (path == NULL || path[0] == '\0')) {
                isMissing = true;
                ++*missing;
            }
            if (toreport) {
                bool reported = false;
                if (!isMissing && !local)  {
                    rc_t rc = 0;
                    bool readable = false;
                    uint64_t size = ~0;
                    KTime_t date = 0;
                    bool ready = false;
                    if (dir == NULL)
                    {   rc = KDirectoryNativeDir(&dir); }
                    assert(!local && path && path[0]);
                    if (dir != NULL) {
                        rc = KDirectoryFileSize(dir, &size, "%s", path);
                        if (rc == 0)
                        {   rc = KDirectoryDate(dir, &date, "%s", path); }
                        if (rc == 0) {
                            const KFile* f = NULL;
                            rc = KDirectoryOpenFileRead(dir, &f, "%s", path);
                            if (rc == 0) {
                                char buffer[1024];
                                size_t num_read = 0;
                                size_t bsize =
                                    size > sizeof buffer ? sizeof buffer : size;
                                rc = KFileReadAll(f,
                                    0, buffer, bsize, &num_read);
                                if (rc == 0 && num_read != bsize) {
                                    rc = RC(rcVDB, rcFile, rcReading,
                                        rcBuffer, rcExcessive);
                                }
                                if (rc == 0)
                                {   readable = true; }
                            }
                            KFileRelease(f);
                        }
                        if (rc == 0)
                        {   ready = true; }
                    }
                    if (ready) {
                        KTime kt;
                        memset(&kt, 0, sizeof kt);
                        KTimeLocal(&kt, date);
                        report(indent, "Dependency", 7,
                            "index", 'd', i,
                            "seq_id", 's', seq_id,
                            "local", 's', local ? "true" : "false",
                            "path", 's', path,
                            "size", 'u', size,
                            "date", 'T', &kt,
                            "readable", 's', readable ? "true" : "false");
                        reported = true;
                    }
                    else {
                        report(indent, "Dependency", 5,
                            "index", 'd', i,
                            "seq_id", 's', seq_id,
                            "local", 's', local ? "true" : "false",
                            "path", 's', path,
                            "error", 'R', rc);
                        reported = true;
                    }
                }
                if (!reported) {
                    report(indent, "Dependency", 4,
                        "index", 'd', i,
                        "seq_id", 's', seq_id,
                        "local", 's', local ? "true" : "false",
                        "path", 's', path == NULL ? "" : path);
                }
            }
        }
        if (rc != 0 && !toreport)
        {   break; }
    }

    RELEASE(KDirectory, dir);

    return rc;
}
Example #6
0
static
rc_t FileToFile (const KDirectory * sd, const char * source,
                 KDirectory *dd, const char * dest_, bool try_rename,
                 char * base)
{
    const KFile * infile;
    rc_t rc;
    uint32_t access;
    KTime_t date;
    bool is_tmp;
    char dest [MY_MAX_PATH + sizeof EncExt];

    strcpy (dest, dest_);
    if (try_rename)
        NameFixUp (dest);

    if ((sd == dd) && (strcmp (source, dest) == 0))
        return FileInPlace (dd, dest, try_rename);

    if (base == NULL)
        STSMSG (1, ("%scrypting file %s to %s", De, source, dest));
    else
        STSMSG (1, ("%scrypting file %s to %s/%s", De, source, base, dest));

    /*
     * A Hack to make stdin/stout work within KFS
     */
    if (UseStdin)
    {
        const KFile * iinfile;
        rc = KFileMakeStdIn (&iinfile);
        if (rc == 0)
        {
            rc = KBufReadFileMakeRead (&infile, iinfile, 64 * 1024);
            KFileRelease (iinfile);
            if (rc == 0)
            {
                access = 0640;
                date = 0;
                goto stdin_shortcut;
            }
            LOGERR (klogErr, rc, "error wrapping stdin");
            return rc;
        }
    }
    rc = 0;
    is_tmp = IsTmpFile (source);

    if (is_tmp)
    {
        TmpFoundFlag = true;
        if (ForceFlag)
            ; /* LOG OVERWRITE */
        else
            ; /* LOG TMP */
    }
    if (!is_tmp || ForceFlag)
    {
        rc = KDirectoryAccess (sd, &access, "%s", source);
        if (rc)
            LOGERR (klogErr, rc, "Error check permission of source");

        else
        {
            rc = KDirectoryDate (sd, &date, "%s", source);
            if (rc)
                LOGERR (klogErr, rc, "Error check date of source");

            else
            {
                rc = KDirectoryOpenFileRead (sd, &infile, "%s", source);
                if (rc)
                    PLOGERR (klogErr, (klogErr, rc,
                                       "Error opening source file '$(S)'",
                                       "S=%s", source));
                else
                {
                    EncScheme scheme;

stdin_shortcut:
                    rc = EncryptionTypeCheck (infile, source, &scheme);
                    if (rc == 0)
                    {
                        KFile * outfile;
                        uint32_t kcm;

                        /*
                         * Hack to support stdout before VFS is complete enough to use here
                         */
                        if (UseStdout)
                        {
                            rc = KFileMakeStdOut (&outfile);
                            if (rc)
                                LOGERR (klogErr, rc, "error wrapping stdout");
                        }
                        else
                        {
                            kcm = ForceFlag ? kcmInit|kcmParents : kcmCreate|kcmParents;

                            rc = KDirectoryCreateFile (dd, &outfile, false, 0600, kcm, "%s", dest);
                            if (rc)
                                PLOGERR (klogErr,(klogErr, rc, "error opening output '$(O)'",
                                                  "O=%s", dest));
                        }
                        if (rc == 0)
                        {
                            const KFile * Infile;
                            KFile * Outfile;

                            rc = CryptFile (infile, &Infile, outfile, &Outfile, scheme);
                            if (rc == 0)
                            {
                                rc = CopyFile (Infile, Outfile, source, dest);
                                if (rc == 0)
                                {
                                    if (UseStdin || UseStdout)
                                        ;
                                    else
                                    {
                                        rc = KDirectorySetAccess (dd, false, access, 0777,
                                                                  "%s", dest);

                                        if (rc == 0 && date != 0)
                                            rc = KDirectorySetDate (dd, false, date, "%s", dest);
                                    }
                                }
                                KFileRelease (Infile);
                                KFileRelease (Outfile);
                            }
                            KFileRelease (outfile);
                        }
                    }
                    KFileRelease (infile);
                }
            }
        }
    }
    return rc;
}
Example #7
0
static
rc_t FileInPlace (KDirectory * cwd, const char * leaf, bool try_rename)
{
    rc_t rc;
    bool is_tmp;

    STSMSG (1, ("%scrypting file in place %s",De,leaf));

    rc = 0;
    is_tmp = IsTmpFile (leaf);

    if (is_tmp)
    {
        STSMSG (1, ("%s is a vdb-decrypt/vdb-encrypt temporary file and will "
                    "be ignored", leaf));
        TmpFoundFlag = true;
        if (ForceFlag)
            ; /* LOG OVERWRITE */
        else
            ; /* LOG TMP */
    }
    if (!is_tmp || ForceFlag)
    {
        char temp [MY_MAX_PATH];


        rc = KDirectoryResolvePath (cwd, false, temp, sizeof temp, ".%s%s",
                                    leaf, TmpExt);

        if (rc)
            PLOGERR (klogErr, (klogErr, rc, "unable to resolve '.$(S)$(E)'",
                               "S=%s,E=%s",leaf,TmpExt));
        else
        {
            KPathType kpt;
            uint32_t kcm;

            kcm = kcmCreate|kcmParents;
            kpt = KDirectoryPathType (cwd, temp);
            if (kpt != kptNotFound)
            {
                /* log busy */
                if (ForceFlag)
                {
                    kcm = kcmInit|kcmParents;
                    /* log force */
                    kpt = kptNotFound;
                }
            }

            if (kpt == kptNotFound)
            {
                const KFile * infile;

                rc = KDirectoryOpenFileRead (cwd, &infile, "%s", leaf);
                if (rc)
                    PLOGERR (klogErr, (klogErr, rc, "Unable to resolve '$(F)'",
                                       "F=%s",leaf));
                else
                {
                    EncScheme scheme;

                    rc = EncryptionTypeCheck (infile, leaf, &scheme);
                    if (rc == 0)
                    {
                        ArcScheme ascheme;
                        bool changed;
                        bool do_this_file;
                        char new_name [MY_MAX_PATH + sizeof EncExt];

                        do_this_file = DoThisFile (infile, scheme, &ascheme);
                        strcpy (new_name, leaf);
                        if (try_rename)
                            changed = NameFixUp (new_name);
                        else
                            changed = false;
                        /*                         KOutMsg ("### %d \n", changed); */

                        if (!do_this_file)
                        {
                            if (changed)
                            {
                                STSMSG (1, ("renaming %s to %s", leaf, new_name));
                                rc = KDirectoryRename (cwd, false, leaf, new_name);
                            }
                            else
                                STSMSG (1, ("skipping %s",leaf));
                        }
                        else
                        {
                            KFile * outfile;

                            rc = KDirectoryCreateExclusiveAccessFile (cwd, &outfile,
                                    false, 0600, kcm,
                                    temp);
                            if (rc)
                                ;
                            else
                            {
                                const KFile * Infile;
                                KFile * Outfile;

                                rc = CryptFile (infile, &Infile, outfile, &Outfile, scheme);

                                if (rc == 0)
                                {
                                    STSMSG (1, ("copying %s to %s", leaf, temp));

                                    rc = CopyFile (Infile, Outfile, leaf, temp);

                                    if (rc == 0)
                                    {
                                        uint32_t access;
                                        KTime_t date;

                                        rc = KDirectoryAccess (cwd, &access, "%s", leaf);
                                        if (rc == 0)
                                            rc = KDirectoryDate (cwd, &date, "%s", leaf);

                                        KFileRelease (infile);
                                        KFileRelease (outfile);
                                        KFileRelease (Infile);
                                        KFileRelease (Outfile);

                                        if (rc == 0)
                                        {
                                            STSMSG (1, ("renaming %s to %s", temp, new_name));

                                            rc = KDirectoryRename (cwd, true, temp, new_name);
                                            if (rc)
                                                LOGERR (klogErr, rc, "error renaming");
                                            else
                                            {
                                                if (changed)
                                                    KDirectoryRemove (cwd, false, "%s", leaf);

                                                /*rc =*/
                                                KDirectorySetAccess (cwd, false, access,
                                                                     0777, "%s", new_name);
                                                KDirectorySetDate (cwd, false, date, "%s", new_name);
                                                /* gonna ignore an error here I think */
                                                return rc;
                                            }
                                        }
                                    }
                                }
                                KFileRelease (outfile);
                            }
                        }
                    }
                    KFileRelease (infile);
                }
            }
        }
    }
    return rc;
}
Example #8
0
rc_t run_ascp(const char *path, const char *key,
              const char *src, const char *dest, const AscpOptions *opt)
{
    const char *host = NULL;
    const char *user = NULL;
    const char *maxRate = NULL;
    bool cache_key = false;
    uint64_t heartbeat = 0;
    const char *acc = NULL;
    uint64_t srcSz = 0;
    uint64_t id = 0;
    TProgress *callback = NULL;
    TQuitting *quitting = NULL;
    rc_t rc = 0;
    pid_t nPid = 0;
    int pipeto[2];      /* pipe to feed the exec'ed program input */
    int pipefrom[2];    /* pipe to get the exec'ed program output */
#define ARGV_SZ 64
    char *argv[ARGV_SZ];
    char extraOptions[4096] = "";

    int i = 0;
    int ret = 0;
    i = 0;

    if (opt != NULL) {
        acc = opt->name;
        cache_key = opt->cache_key;
        callback = opt->callback;
        heartbeat = opt->heartbeat;
        host = opt->host;
        id = opt->id;
        quitting = opt->quitting;
        srcSz = opt->src_size;
        user = opt->user;

        if (opt->ascp_options != NULL) {
            size_t s = string_size(opt->ascp_options);
            if (s >= sizeof extraOptions) {
                LOGERR(klogErr,
                       RC(rcExe, rcProcess, rcCreating, rcBuffer, rcInsufficient),
                       "extra ascp options are ignored");

                maxRate = opt->target_rate;
            }
            else {
                string_copy
                (extraOptions, sizeof extraOptions, opt->ascp_options, s);
            }
        }
        else {
            maxRate = opt->target_rate;
        }
    }

    if (acc == NULL) {
        acc = dest;
    }

    if (heartbeat > 0) {
        heartbeat /= 1000;
        if (heartbeat == 0) {
            heartbeat = 1;
        }
    }

    if (pipe(pipeto) != 0) {
        perror("pipe() to");
        rc = RC(rcExe, rcFileDesc, rcCreating, rcFileDesc, rcFailed);
        LOGERR(klogErr, rc, "while pipe");
        return rc;
    }
    if (pipe(pipefrom) != 0) {
        perror("pipe() from");
        rc = RC(rcExe, rcFileDesc, rcCreating, rcFileDesc, rcFailed);
        LOGERR(klogErr, rc, "while pipe");
        return rc;
    }

    argv[i++] = (char*)path;
    argv[i++] = "-i";
    argv[i++] = (char*)key;
    argv[i++] = "-pQTk1";
    if (maxRate != NULL && maxRate[0] != '\0') {
        argv[i++] = "-l";
        argv[i++] = (char*)maxRate;
    }
    if (user != NULL) {
        argv[i++] = "--user";
        argv[i++] = (char*)user;
    }
    if (host != NULL) {
        argv[i++] = "--host";
        argv[i++] = (char*)user;
    }

    if (extraOptions[0] != '\0') {
        bool done = false;
        char *c = extraOptions;
        while (!done) {
            while (true) {
                if (*c == '\0') {
                    break;
                }
                else if (isspace(*c)) {
                    ++c;
                }
                else {
                    break;
                }
            }
            if (*c == '\0') {
                break;
            }
            else {
                argv[i++] = c;
            }
            while (true) {
                if (*c == '\0') {
                    done = true;
                    break;
                }
                else if (isspace(*c)) {
                    *(c++) = '\0';
                    break;
                }
                ++c;
            }
            if (i > ARGV_SZ - 4) {
                LOGERR(klogErr,
                       RC(rcExe, rcProcess, rcCreating, rcBuffer, rcInsufficient),
                       "too mary extra ascp options - some of them are ignored");
                break;
            }
        }
    }

    argv[i++] = (char*)src;
    argv[i++] = (char*)dest;
    argv[i++] = NULL;

    logevp(path, argv);

    if (quitting) {
        rc = quitting();
    }
    if (rc != 0) {
        return rc;
    }

    nPid = fork();
    if (nPid < 0 ) {
        perror("fork() 1");
        rc = RC(rcExe, rcProcess, rcCreating, rcProcess, rcFailed);
        LOGERR(klogErr, rc, "after fork");
        return rc;
    }
    else if (nPid == 0) {
        /* dup pipe read/write to stdin/stdout */
        dup2(pipeto  [0], STDIN_FILENO);
        dup2(pipefrom[1], STDOUT_FILENO);
        dup2(pipefrom[1], STDERR_FILENO);
        close(pipeto[1]);
        ret = execvp(path, argv);
        STSMSG(STS_DBG, ("CHILD: Done %s %s %s = %d", path, src, dest, ret));
        exit(EXIT_FAILURE);
    }
    else {
        bool progressing = false;
        bool writeFailed = false;
        EAscpState state = eStart;
        const char y[] = "y\n";
        const char n[] = "n\n";
        int status = 0;
        int w = 0;
        int fd = pipefrom[0];
        const char *answer = n;
        String line;
        StringInit(&line, NULL, 0, 0);
        if (cache_key) {
            answer = y;
        }

        {
            int flags = fcntl(fd, F_GETFL, 0);
            fcntl(fd, F_SETFL, flags | O_NONBLOCK);
        }

        close(pipeto[0]);
        close(pipefrom[1]);
        assert(sizeof y == sizeof n);

        {
            int hang = 0;
            uint64_t prev = 0;
            KTime_t tPrev = 0;
            char sfSrc = 'B';
            uint64_t hSrc = humanize(srcSz, &sfSrc, NULL);
            int sig = 0;
            uint64_t i = 0;
            KDirectory *dir = NULL;
            rc_t rc = KDirectoryNativeDir(&dir);
            DISP_RC(rc, "KDirectoryNativeDir");
            if (rc != 0) {
                return rc;
            }
            while (w == 0) {
                bool quit = false;
                w = waitpid(nPid, &status, WNOHANG);
                if (w == 0) {
                    bool got = false;
                    rc_t rc = 0;
                    if (quitting) {
                        rc = quitting();
                    }
                    if (rc != 0 || quit) {
                        if (sig == 0) {
                            sig = SIGINT;
                        }
                        else if (sig >= SIGKILL) {
                            break;
                        }
                        else {
                            ++sig;
                        }
                        if (progressing) {
                            OUTMSG(("\n"));
                        }
                        PLOGMSG(klogInfo, (klogInfo, "^C pressed: "
                                           "Senging $(sgn) to ascp", "sgn=%s", sig));
                        kill(nPid, sig);
                    }
                    while (true) {
                        char buf[4096];
                        int s = read(fd, buf, sizeof buf);
                        if (s == 0) {
                            break;
                        }
                        else if (s < 0) {
                            if (errno != EAGAIN) {
                                if (progressing) {
                                    OUTMSG(("\n"));
                                }
                                perror("read(child)");
                            }
                            break;
                        }
                        ascpParse(buf, s, dest, &state, &line);
                        switch (state) {
                        case eKeyEnd:
                            write(pipeto[1], answer, sizeof y - 1);
                            break;
                        case eWriteFailed:
                            writeFailed = true;
                            break;
                        default:
                            break;
                        }
                        got = true;
                    }
                    if (!got) {
                        sleep(1);
                        ++i;
                        if ((heartbeat > 0 && i >= heartbeat) || (i > 99)) {
                            uint64_t size = 0;
                            rc_t rc = KDirectoryFileSize(dir, &size, "%s", dest);
                            if (rc != 0) {
                                size = 0;
                            }
                            else {
                                if (size != prev) {
                                    prev = size;
                                    tPrev = 0;
                                    hang = 0;
                                }
                                else {
                                    KTime_t date = 0;
                                    rc_t rc = KDirectoryDate(dir, &date, "%s", dest);
                                    if (rc == 0) {
                                        tPrev = date;
                                        if ((KTimeStamp() - date) > 60 * 99) {
                                            /* no file update during 99' */
                                            if (hang == 0) {
                                                write(pipeto[1],
                                                      answer, sizeof y - 1);
                                                ++hang;
                                            }
                                            else if (hang < 9) {
                                                ++hang;
                                                sig = 0;
                                            }
                                            else {
                                                if (sig == 0) {
                                                    sig = SIGINT;
                                                }
                                                else {
                                                    ++sig;
                                                }
                                                if (progressing) {
                                                    OUTMSG(("\n"));
                                                }
                                                if (sig > SIGKILL) {
                                                    rc = RC(rcExe,
                                                            rcProcess, rcExecuting,
                                                            rcProcess,rcDetached);
                                                    return rc;
                                                }

                                                PLOGMSG(klogInfo, (klogInfo,
                                                                   "Senging $(sgn) to ascp",
                                                                   "sgn=%s", sig));
                                                kill(nPid, sig);
                                            }
                                        }
                                    }
                                }
                            }
                            if (heartbeat > 0) {
                                if (callback) {
                                    quit = !callback(id,
                                                     eAscpStateRunning, size, 0);
                                }
                                else {
                                    progress(acc, size, srcSz, hSrc, sfSrc,
                                             tPrev);
                                }
                                progressing = true;
                            }
                            i = 0;
                        }
                    }
                }
            }
            RELEASE(KDirectory, dir);
        }

        if (progressing) {
            OUTMSG(("\n"));
        }

        while (1) {
            char buf[4096];
            int s = read(fd, buf, sizeof buf);
            if (s == 0) {
                break;
            }
            else if (s < 0) {
                if (errno != EAGAIN) {
                    perror("read(child)");
                    break;
                }
                continue;
            }
            ascpParse(buf, s, dest, &state, &line);
            if (state == eWriteFailed) {
                writeFailed = true;
            }
        }
        STSMSG(    STS_DBG, ("ascp exited with pid=%d status=%d", w, status));
        if (WIFEXITED(status)) {
            STSMSG(STS_DBG, ("ascp exited with exit status %d",
                             WEXITSTATUS(status)));
        }
        else {
            STSMSG(STS_DBG, ("ascp has not terminated correctly"));
        }
        if (w == -1) {
            perror("waitpid");
            rc = RC(rcExe, rcProcess, rcWaiting, rcProcess, rcFailed);
            LOGERR(klogErr, rc, "after waitpid");
            exit(EXIT_FAILURE);
        }
        if (WIFEXITED(status)) {
            if (WEXITSTATUS(status) == 0) {
                STSMSG(STS_DBG, ("ascp succeed"));
                if (callback) {
                    callback(id, eAscpStateExitSuccess, 0, 0);
                }
            } else if (writeFailed) {
                rc = RC(rcExe, rcProcess, rcExecuting, rcMemory, rcExhausted);
                if (callback) {
                    callback(id, eAscpStateExitWriteFailure, 0, 0);
                }
            }
            else {
                if (rc == 0) {
                    rc = RC(rcExe, rcProcess, rcWaiting, rcProcess, rcFailed);
                }
                PLOGERR(klogErr, (klogErr, rc,
                                  "ascp failed with $(ret)", "ret=%d", WEXITSTATUS(status)));
                if (callback) {
                    callback(id, eAscpStateExitFailure, 0, 0);
                }
            }
        } else if (WIFSIGNALED(status)) {
            if (rc == 0) {
                if (quitting) {
                    rc = quitting();
                    if (rc == 0) {
                        rc = RC(rcExe,
                                rcProcess, rcWaiting, rcProcess, rcFailed);
                    }
                }
            }
            if (rc != SILENT_RC(rcExe, rcProcess, rcExecuting,
                                rcProcess, rcCanceled))
            {
                PLOGERR(klogErr, (klogErr, rc, "ascp killed by signal $(sig)",
                                  "sig=%d", WTERMSIG(status)));
                if (callback) {
                    callback(id, eAscpStateExitFailure, 0, 0);
                }
            }
        }
    }
    return rc;
}
Example #9
0
static
rc_t CC list_action (const KDirectory * dir, const char * path, void * _adata)
{
    rc_t           rc;
    list_adata *   data;
    list_item *    item;
    KPathType      type;
    uint32_t       access;
    uint64_t       size;
    uint64_t       loc;
    KTime_t        mtime;
    size_t         pathlen;
    size_t         linklen;
    char           link		[2 * 4096]; /* we'll truncate? */

    rc = 0;
    data = _adata;

    loc = size = 0;
    pathlen = strlen (path);
    type = KDirectoryPathType (dir, path);

    if (type & kptAlias)
    {
        rc = KDirectoryVResolveAlias (dir, false, link, sizeof (link),
                                      path, NULL);
        if (rc == 0)
            linklen = strlen (link);
    }
    else
    {
        linklen = 0;
        switch (type & ~kptAlias)
        {
        case kptNotFound:
            rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcNotFound);
            break;
        case kptBadPath:
            rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcInvalid);
            break;
        case kptZombieFile:
            if ( ! long_list )
                return 0;
            data->has_zombies = true;
        case kptFile:
            rc = KDirectoryFileSize (dir, &size, path);
            if (rc == 0)
            {
                if (size > data->max_size)
                    data->max_size = size;
                rc = KDirectoryFileLocator (dir, &loc, path);
                if ((rc == 0) && (loc > data->max_loc))
                    data->max_loc = loc;
            }
            break;
        case kptDir:
            break;
        case kptCharDev:
        case kptBlockDev:
        case kptFIFO:
            /* shouldn't get here */
            return 0;
        }
    }
    if (rc == 0)
    {
        rc = KDirectoryAccess (dir, &access, "%s", path);
        if (rc == 0)
        {
            rc = KDirectoryDate (dir, &mtime, "%s", path);

            if (rc == 0)
            {
                item = malloc (sizeof (*item) + pathlen + linklen + 2); /* usually one too many */
                if (item == NULL)
                {
                    rc = RC (rcExe, rcNoTarg, rcAllocating, rcMemory, rcExhausted);
                }
                else
                {
                    item->type = type;
                    item->access = access;
                    item->size = size;
                    item->loc = loc;
                    item->mtime = mtime;
                    item->path = (char *)(item+1);
                    strcpy (item->path, path);
                    if (type & kptAlias)
                    {
                        item->link = item->path + pathlen + 1;
                        strcpy (item->link, link);
                    }
                    else
                        item->link = NULL;
                    DLListPushHead (&data->list, &item->dad);

                    if (type == kptDir)
                        rc = step_through_dir (dir, path, data->filter, data->fdata, 
                                               list_action, data);


                }
            }
        }
    }
    return rc;
}
Example #10
0
static
rc_t list_action (const KDirectory * dir, const char * path, void * _adata)
{
    rc_t           rc = 0;
    list_adata *   data = _adata;
    list_item *    item = NULL;
    KPathType      type  = KDirectoryPathType (dir, "%s", path);
    size_t         pathlen = strlen (path);
    size_t         linklen = 0;
    char           link [2 * 4096]; /* we'll truncate? */

    if (type & kptAlias)
    {
        rc = KDirectoryVResolveAlias (dir, false, link, sizeof (link),
                                      path, NULL);
        if (rc == 0)
            linklen = strlen (link);
    }

    if (rc == 0)
    {
        item = calloc (sizeof (*item) + pathlen + linklen + 2, 1); /* usually one too many */
        if (item == NULL)
        {
            rc = RC (rcExe, rcNoTarg, rcAllocating, rcMemory, rcExhausted);
        }
        else
        {
            do
            {
                item->path = (char *)(item+1);
                strcpy (item->path, path);
                item->type = type;
                rc = KDirectoryAccess (dir, &item->access, "%s", path);
                if (rc) break;

                rc = KDirectoryDate (dir, &item->mtime, "%s", path);
                if (rc) break;

                if (type & kptAlias)
                {
                    item->link = item->path + pathlen + 1;
                    strcpy (item->link, link);
                }
                else switch (type & ~kptAlias)
                {
                case kptNotFound:
                    rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcNotFound);
                    break;
                case kptBadPath:
                    rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcInvalid);
                    break;
                case kptZombieFile:
                    data->has_zombies = true;
                case kptFile:
                    rc = KDirectoryFileSize (dir, &item->size, "%s", path);
                    if (rc == 0)
                        rc = KDirectoryFileLocator (dir, &item->loc, "%s", path);
                    DBGMSG (DBG_APP, 1, ("%s: found file %s size %lu at %lu\n",
                                         __func__, item->path, item->size, item->loc));
                    break;
                case kptDir:
                    DBGMSG (DBG_APP, 1, ("%s: found directory %s\n",
                                         __func__, item->path));
                    break;
                default:
                    DBGMSG (DBG_APP, 1, ("%s: found unknown %s\n",
                                         __func__, item->path));
                    break;
                }
            } while (0);
        }
    }
    if (rc == 0)
    {
        VectorAppend (&data->list, NULL, item);
        VectorInsert (&data->sort, item, NULL, list_item_cmp);

        if (type == kptDir)
            rc = step_through_dir (dir, path, list_action, data);
    }
    return rc;
}