コード例 #1
0
ファイル: http.c プロジェクト: gamman/appweb-3
static int writeBody(MprHttp *http, MprList *fields, MprList *files)
{
    MprFile     *file;
    char        buf[MPR_HTTP_BUFSIZE], *path, *pair;
    int         bytes, next, count, rc, len;

    rc = 0;

    mprSetSocketBlockingMode(http->sock, 1);
    if (upload) {
        if (mprWriteHttpUploadData(http, files, fields) < 0) {
            mprError(http, "Can't write upload data %s", mprGetHttpError(http));
            mprSetSocketBlockingMode(http->sock, 0);
            return MPR_ERR_CANT_WRITE;
        }
    } else {
        if (fields) {
            count = mprGetListCount(fields);
            for (next = 0; !rc && (pair = mprGetNextItem(fields, &next)) != 0; ) {
                len = (int) strlen(pair);
                if (next < count) {
                    len = (int) strlen(pair);
                    if (mprWriteSocket(http->sock, pair, len) != len || mprWriteSocket(http->sock, "&", 1) != 1) {
                        return MPR_ERR_CANT_WRITE;
                    }
                } else {
                    if (mprWriteSocket(http->sock, pair, len) != len) {
                        return MPR_ERR_CANT_WRITE;
                    }
                }
            }
        }
        if (files) {
            mprAssert(mprGetListCount(files) == 1);
            for (rc = next = 0; !rc && (path = mprGetNextItem(files, &next)) != 0; ) {
                file = mprOpen(http, path, O_RDONLY | O_BINARY, 0);
                if (file == 0) {
                    mprError(http, "Can't open \"%s\"", path);
                    return MPR_ERR_CANT_OPEN;
                }
                if (verbose && upload) {
                    mprPrintf(http, "uploading: %s\n", path);
                }
                while ((bytes = mprRead(file, buf, sizeof(buf))) > 0) {
                    if (mprWriteHttp(http, buf, bytes) != bytes) {
                        mprFree(file);
                        return MPR_ERR_CANT_WRITE;
                    }
                }
                mprFree(file);
            }
        }
        if (mprFinalizeHttpWriting(http) < 0) {
            return MPR_ERR_CANT_WRITE;
        }
    }
    mprSetSocketBlockingMode(http->sock, 0);
    return rc;
}
コード例 #2
0
ファイル: http.c プロジェクト: gamman/appweb-3
static int setContentLength(MprHttp *http, MprList *fields, MprList *files)
{
    MprPath     info;
    char        *path, *pair;
    int64       len;
    int         next;

    len = 0;
    if (upload) {
        /*  Easier to use chunking than to calculate the full multipart-mime upload content */
        mprSetHttpChunked(http, 1);
        mprEnableHttpUpload(http);
        return 0;
    } else {
        for (next = 0; (path = mprGetNextItem(files, &next)) != 0; ) {
            if (mprGetPathInfo(http, path, &info) < 0) {
                mprError(http, "Can't access file %s", path);
                return MPR_ERR_CANT_ACCESS;
            }
            len += info.size;
        }
        if (fields) {
            for (next = 0; (pair = mprGetNextItem(fields, &next)) != 0; ) {
                len += strlen(pair);
            }
            len += mprGetListCount(fields) - 1;
        }
    }
    if (len > (16 * MPR_HTTP_BUFSIZE)) {
        mprSetHttpChunked(http, 1);
    } else {
        mprSetHttpBody(http, NULL, (int) len);
    }
    return 0;
}
コード例 #3
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
static int reapJoins(Ejs *ejs, EjsVar *workers)
{
    EjsWorker   *worker;
    EjsArray    *set;
    int         i, completed;

    lock(ejs);
    if (workers == 0 || workers == ejs->nullValue) {
        completed = 0;
        for (i = 0; i < mprGetListCount(ejs->workers); i++) {
            worker = mprGetItem(ejs->workers, i);
            if (worker->state >= EJS_WORKER_COMPLETE) {
                completed++;
            }
        }
        if (completed == mprGetListCount(ejs->workers)) {
            unlock(ejs);
            return 1;
        }
    } else if (ejsIsArray(workers)) {
        set = (EjsArray*) workers;
        for (i = 0; i < set->length; i++) {
            worker = (EjsWorker*) set->data[i];
            if (worker->state < EJS_WORKER_COMPLETE) {
                break;
            }
        }
        if (i >= set->length) {
            unlock(ejs);
            return 1;
        }
    } else if (workers->type == ejs->workerType) {
        worker = (EjsWorker*) workers;
        if (worker->state >= EJS_WORKER_COMPLETE) {
            unlock(ejs);
            return 1;
        }
    }
    unlock(ejs);
    return 0;
}
コード例 #4
0
ファイル: mpr.c プロジェクト: embedthis/mpr-3
/*
    Just the Mpr services are idle. Use mprIsIdle to determine if the entire process is idle
 */
bool mprServicesAreIdle(MprCtx ctx)
{
    Mpr     *mpr;
    int     idle;
    
    mpr = mprGetMpr(ctx);
    idle = 1;
#if BLD_FEATURE_CMD
    if (mprGetListCount(mpr->cmdService->cmds)) {
        idle = 0;
    }
#endif
#if BLD_FEATURE_MULTITHREAD
    if (mprGetListCount(mpr->workerService->busyThreads)) {
       idle = 0;
    }
#endif
    if (mpr->dispatcher->flags & MPR_DISPATCHER_DO_EVENT) {
        idle = 0;
    }
    return idle;
}
コード例 #5
0
ファイル: host.c プロジェクト: jsjohnst/appweb
void maAddConn(MaHost *host, MaConn *conn)
{
    lock(host);
    mprAddItem(host->connections, conn);
    conn->started = mprGetTime(conn);

    if ((host->whenCurrentDate + MPR_TICKS_PER_SEC) < conn->started) {
        updateCurrentDate(host);
    }
    if (mprGetListCount(host->connections) == 1) {
        startTimer(host);
    }
    unlock(host);
}
コード例 #6
0
ファイル: ejs.c プロジェクト: embedthis/appweb-3
    MAIN(ejsMain, int argc, char **argv)
#endif
{
    Mpr             *mpr;
    EcCompiler      *cp;
    EjsService      *vmService;
    Ejs             *ejs;
    MprList         *useModules, *files;
    cchar           *cmd, *className, *methodName;
    char            *argp, *searchPath, *modules, *name, *tok, *extraFiles, *spec;
    int             nextArg, err, ecFlags, run, merge, bind, noout, debug, optimizeLevel, warnLevel;
    int             compilerMode, lang;

    /*
     *  Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler
     */
    mpr = mprCreate(argc, argv, ejsMemoryFailure);
    mprSetAppName(mpr, argv[0], 0, 0);
    setupSignals();

    if (mprStart(mpr, MPR_START_EVENTS_THREAD) < 0) {
        mprError(mpr, "Can't start mpr services");
        return EJS_ERR;
    }

    err = 0;
    className = 0;
    cmd = 0;
    methodName = 0;
    searchPath = 0;
    run = 1;
    merge = 0;
    bind = 1;
    noout = 1;
    debug = 1;
    warnLevel = 1;
    optimizeLevel = 9;
    compilerMode = PRAGMA_MODE_STANDARD;
    lang = BLD_FEATURE_EJS_LANG;

    useModules = mprCreateList(mpr);
    files = mprCreateList(mpr);

    for (nextArg = 1; nextArg < argc; nextArg++) {
        argp = argv[nextArg];
        if (*argp != '-') {
            break;
        }

        if (strcmp(argp, "--bind") == 0) {
            bind = 1;

        } else if (strcmp(argp, "--class") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                className = argv[++nextArg];
            }

        } else if (strcmp(argp, "--cmd") == 0 || strcmp(argp, "-c") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                cmd = argv[++nextArg];
            }

        } else if (strcmp(argp, "--debug") == 0) {
            debug = 1;

        } else if (strcmp(argp, "--lang") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                spec = argv[++nextArg];
                if (mprStrcmpAnyCase(spec, "ecma") == 0) {
                    lang = EJS_SPEC_ECMA;
                } else if (mprStrcmpAnyCase(spec, "plus") == 0) {
                    lang = EJS_SPEC_PLUS;
                } else if (mprStrcmpAnyCase(spec, "fixed") == 0) {
                    lang = EJS_SPEC_FIXED;
                }
            }

        } else if (strcmp(argp, "--files") == 0 || strcmp(argp, "-f") == 0) {
            /* Compatibility with mozilla shell */
            if (nextArg >= argc) {
                err++;
            } else {
                extraFiles = mprStrdup(mpr, argv[++nextArg]);
                name = mprStrTok(extraFiles, " \t", &tok);
                while (name != NULL) {
                    mprAddItem(files, name);
                    name = mprStrTok(NULL, " \t", &tok);
                }
            }

        } else if (strcmp(argp, "--log") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                ejsStartLogging(mpr, argv[++nextArg]);
            }

        } else if (strcmp(argp, "--method") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                methodName = argv[++nextArg];
            }

        } else if (strcmp(argp, "--nobind") == 0) {
            bind = 0;

        } else if (strcmp(argp, "--nodebug") == 0) {
            debug = 0;

        } else if (strcmp(argp, "--optimize") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                optimizeLevel = atoi(argv[++nextArg]);
            }

        } else if (strcmp(argp, "-s") == 0) {
            /* Compatibility with mozilla shell. Just ignore */

        } else if (strcmp(argp, "--search") == 0 || strcmp(argp, "--searchpath") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                searchPath = argv[++nextArg];
            }

        } else if (strcmp(argp, "--standard") == 0) {
            compilerMode = PRAGMA_MODE_STANDARD;

        } else if (strcmp(argp, "--strict") == 0) {
            compilerMode = PRAGMA_MODE_STRICT;

        } else if (strcmp(argp, "--use") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                modules = mprStrdup(mpr, argv[++nextArg]);
                name = mprStrTok(modules, " \t", &tok);
                while (name != NULL) {
                    mprAddItem(useModules, name);
                    name = mprStrTok(NULL, " \t", &tok);
                }
            }

        } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) {
            mprPrintfError(mpr, "%s %s-%s\n", BLD_NAME, BLD_VERSION, BLD_NUMBER);
            return 0;

        } else if (strcmp(argp, "--warn") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                warnLevel = atoi(argv[++nextArg]);
            }

        } else {
            err++;
            break;
        }
    }

    if (err) {
        /*
         *  If --method or --class is specified, then the named class.method will be run (method defaults to "main", class
         *  defaults to first class with a "main").
         *
         *  Examples:
         *      ejs
         *      ejs script.es arg1 arg2 arg3
         *      ejs --class "Customer" --method "start" --files "script1.es script2.es" main.es
         */
        mprPrintfError(mpr,
            "Usage: %s [options] script.es [arguments] ...\n"
            "  Ejscript shell program options:\n"
            "  --class className        # Name of class containing method to run\n"
            "  --cmd ejscriptCode       # Literal ejscript statements to execute\n"
            "  --debug                  # Use symbolic debugging information (default)\n"
            "  --files \"files..\"        # Extra source to compile\n"
            "  --lang                   # Language compliance (ecma|plus|fixed)\n"
            "  --log logSpec            # Internal compiler diagnostics logging\n"
            "  --method methodName      # Name of method to run. Defaults to main\n"
            "  --nodebug                # Omit symbolic debugging information\n"
            "  --optimize level         # Set the optimization level (0-9 default is 9)\n"
            "  --search ejsPath         # Module search path\n"
            "  --standard               # Default compilation mode to standard (default)\n"
            "  --strict                 # Default compilation mode to strict\n"
            "  --use 'module, ...'      # List of modules to pre-load\n"
            "  --version                # Emit the compiler version information\n"
            "  --warn level             # Set the warning message level (0-9 default is 0)\n\n",
            mpr->name);
        return -1;
    }

    vmService = ejsCreateService(mpr);
    if (vmService == 0) {
        return MPR_ERR_NO_MEMORY;
    }
    ecInitCompiler(vmService);

    ejs = ejsCreate(vmService, NULL, searchPath, 0);
    if (ejs == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ecFlags = 0;
    ecFlags |= (run) ? EC_FLAGS_RUN: 0;
    ecFlags |= (merge) ? EC_FLAGS_MERGE: 0;
    ecFlags |= (bind) ? EC_FLAGS_BIND: 0;
    ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0;
    ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0;

    cp = ecCreateCompiler(ejs, ecFlags, lang);
    if (cp == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ecSetOptimizeLevel(cp, optimizeLevel);
    ecSetWarnLevel(cp, warnLevel);
    ecSetDefaultMode(cp, compilerMode);

    if (preloadModules(cp, useModules) < 0) {
        return EJS_ERR;
    }
    if (nextArg < argc) {
        mprAddItem(files, argv[nextArg]);
    }

    if (cmd) {
        if (interpretCommands(cp, cmd) < 0) {
            err++;
        }
    } else if (mprGetListCount(files) > 0) {
        if (interpretFiles(cp, files, argc - nextArg, &argv[nextArg], className, methodName, lang) < 0) {
            err++;
        }
    } else {
        /*
         *  No args - run as an interactive shell
         */
        if (interpretCommands(cp, NULL) < 0) {
            err++;
        }
    }
#if VXWORKS
    mprFree(cp);
    mprFree(ejs);
    if (mprStop(mpr)) {
        mprFree(mpr);
    }
#endif
    return err;
}
コード例 #7
0
ファイル: dirHandler.c プロジェクト: doghell/appweb-3
static void sortList(MaConn *conn, MprList *list)
{
    MaRequest       *req;
    MaResponse      *resp;
    MprDirEntry     *tmp, **items;
    Dir             *dir;
    int             count, i, j, rc;

    req = conn->request;
    resp = conn->response;
    dir = resp->handler->stageData;
    
    if (dir->sortField == 0) {
        return;
    }

    count = mprGetListCount(list);
    items = (MprDirEntry**) list->items;
    if (mprStrcmpAnyCase(dir->sortField, "Name") == 0) {
        for (i = 1; i < count; i++) {
            for (j = 0; j < i; j++) {
                rc = strcmp(items[i]->name, items[j]->name);
                if (dir->foldersFirst) {
                    if (items[i]->isDir && !items[j]->isDir) {
                        rc = -dir->sortOrder;
                    } else if (items[j]->isDir && !items[i]->isDir) {
                        rc = dir->sortOrder;
                    } 
                }
                rc *= dir->sortOrder;
                if (rc < 0) {
                    tmp = items[i];
                    items[i] = items[j];
                    items[j] = tmp;
                }
            }
        }

    } else if (mprStrcmpAnyCase(dir->sortField, "Size") == 0) {
        for (i = 1; i < count; i++) {
            for (j = 0; j < i; j++) {
                rc = (items[i]->size < items[j]->size) ? -1 : 1;
                if (dir->foldersFirst) {
                    if (items[i]->isDir && !items[j]->isDir) {
                        rc = -dir->sortOrder;
                    } else if (items[j]->isDir && !items[i]->isDir) {
                        rc = dir->sortOrder;
                    }
                }
                rc *= dir->sortOrder;
                if (rc < 0) {
                    tmp = items[i];
                    items[i] = items[j];
                    items[j] = tmp;
                }
            }
        }

    } else if (mprStrcmpAnyCase(dir->sortField, "Date") == 0) {
        for (i = 1; i < count; i++) {
            for (j = 0; j < i; j++) {
                rc = (items[i]->lastModified < items[j]->lastModified) ? -1: 1;
                if (dir->foldersFirst) {
                    if (items[i]->isDir && !items[j]->isDir) {
                        rc = -dir->sortOrder;
                    } else if (items[j]->isDir && !items[i]->isDir) {
                        rc = dir->sortOrder;
                    }
                }
                rc *= dir->sortOrder;
                if (rc < 0) {
                    tmp = items[i];
                    items[i] = items[j];
                    items[j] = tmp;
                }
            }
        }
    }
}
コード例 #8
0
ファイル: host.c プロジェクト: doghell/appweb-3
/*
 *  The host timer does maintenance activities and will fire per second while there is active requests.
 *  When multi-threaded, the host timer runs as an event off the service thread. Because we lock the host here,
 *  connections cannot be deleted while we are modifying the list.
 */
static void hostTimer(MaHost *host, MprEvent *event)
{
    Mpr         *mpr;
    MaStage     *stage;
    MaConn      *conn;
    MprModule   *module;
    MaHttp      *http;
    int         next, count;

    mprAssert(event);
    http = host->server->http;

    /*
     *  Locking ensures connections won't be deleted
     */
    lock(host);
    updateCurrentDate(host);
    mprLog(host, 8, "hostTimer: %d active connections", mprGetListCount(host->connections));

    /*
     *  Check for any expired connections
     */
    for (count = 0, next = 0; (conn = mprGetNextItem(host->connections, &next)) != 0; count++) {
        /*
         *  Workaround for a GCC bug when comparing two 64bit numerics directly. Need a temporary.
         */
        int64 diff = conn->expire - host->now;
        if (diff < 0 && !mprGetDebugMode(host)) {
            conn->keepAliveCount = 0;
            if (!conn->disconnected) {
                if (conn->request) {
                    mprLog(host, 6, "Open request timed out due to inactivity: %s", conn->request->url);
                } else {
                    mprLog(host, 6, "Idle connection timed out");
                }
                conn->disconnected = 1;
                mprDisconnectSocket(conn->sock);
            }
        }
    }
    /*
        Check for unloadable modules - must be idle
     */
    mpr = mprGetMpr(http);
    if (mprGetListCount(host->connections) == 0) {
        for (next = 0; (module = mprGetNextItem(mpr->moduleService->modules, &next)) != 0; ) {
            if (module->timeout) {
                if (module->lastActivity + module->timeout < host->now) {
                    if ((stage = maLookupStage(http, module->name)) != 0) {
                        mprLog(host, 2, "Unloading inactive module %s", module->name);
                        if (stage->match) {
                            mprError(conn, "Can't unload modules with match routines");
                            module->timeout = 0;
                        } else {
                            maUnloadModule(http, module->name);
                            stage->flags |= MA_STAGE_UNLOADED;
                        }
                    } else {
                        maUnloadModule(http, module->name);
                    }
                } else {
                    count++;
                }
            }
        }
    }
    if (count == 0) {
        mprFree(event);
        host->timer = 0;
    }
    unlock(host);
}
コード例 #9
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
/*
 *  function Worker(script: String = null, options: Object = null)
 *
 *  Script is optional. If supplied, the script is run immediately by a worker thread. This call
 *  does not block. Options are: search and name.
 */
static EjsVar *workerConstructor(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    Ejs             *wejs;
    EjsVar          *options, *value;
    EjsName         qname;
    EjsWorker       *self;
    cchar           *search, *name;

    worker->ejs = ejs;
    worker->state = EJS_WORKER_BEGIN;

    options = (argc == 2) ? (EjsVar*) argv[1]: NULL;
    name = 0;

    search = ejs->ejsPath;
    if (options) {
        value = ejsGetPropertyByName(ejs, options, ejsName(&qname, "", "search"));
        if (ejsIsString(value)) {
            search = ejsGetString(value);
        }
        value = ejsGetPropertyByName(ejs, options, ejsName(&qname, "", "name"));
        if (ejsIsString(value)) {
            name = ejsGetString(value);
        }
    }

    if (name) {
        worker->name = mprStrdup(worker, name);
    } else {
        worker->name = mprAsprintf(worker, -1, "worker-%d", mprGetListCount(ejs->workers));
    }

    /*
     *  Create a new interpreter and an "inside" worker object and pair it with the current "outside" worker.
     */
    wejs = ejsCreate(ejs->service, NULL, search, 0);
    if (wejs == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    worker->pair = self = ejsCreateWorker(wejs);
    self->state = EJS_WORKER_BEGIN;
    self->ejs = wejs;
    self->inside = 1;
    self->pair = worker;
    self->name = mprStrcat(self, -1, "inside-", worker->name, NULL);

    ejsSetProperty(ejs,  (EjsVar*) worker, ES_ejs_sys_Worker_name, (EjsVar*) ejsCreateString(ejs, self->name));
    ejsSetProperty(wejs, (EjsVar*) self,   ES_ejs_sys_Worker_name, (EjsVar*) ejsCreateString(wejs, self->name));
    ejsSetProperty(wejs, wejs->global, ES_ejs_sys_worker_self, (EjsVar*) self);

    /*
     *  Workers have a dedicated namespace to enable viewing of the worker globals (self, onmessage, postMessage...)
     */
    ejsDefineReservedNamespace(wejs, wejs->globalBlock, 0, EJS_WORKER_NAMESPACE);

    /*
     *  Make the inside worker permanent so we don't need to worry about whether worker->pair->ejs is valid
     */
    self->obj.var.permanent = 1;
    
    if (argc > 0 && ejsIsPath(argv[0])) {
        addWorker(ejs, worker);
        worker->scriptFile = mprStrdup(worker, ((EjsPath*) argv[0])->path);
        worker->state = EJS_WORKER_STARTED;
        worker->obj.var.permanent = 1;
        if (mprStartWorker(ejs, (MprWorkerProc) workerMain, (void*) worker, MPR_NORMAL_PRIORITY) < 0) {
            ejsThrowStateError(ejs, "Can't start worker");
            worker->obj.var.permanent = 0;
            return 0;
        }
    }
    return (EjsVar*) worker;
}