Ejemplo n.º 1
0
Lock*
Lock_init(Lock *self, Folder *folder, const CharBuf *name,
          const CharBuf *host, int32_t timeout, int32_t interval) {
    // Validate.
    if (interval <= 0) {
        DECREF(self);
        THROW(ERR, "Invalid value for 'interval': %i32", interval);
    }
    ZombieCharBuf *scratch = ZCB_WRAP(name);
    uint32_t code_point;
    while (0 != (code_point = ZCB_Nip_One(scratch))) {
        if (isalnum(code_point)
            || code_point == '.'
            || code_point == '-'
            || code_point == '_'
           ) {
            continue;
        }
        DECREF(self);
        THROW(ERR, "Lock name contains disallowed characters: '%o'", name);
    }

    // Assign.
    self->folder       = (Folder*)INCREF(folder);
    self->timeout      = timeout;
    self->name         = CB_Clone(name);
    self->host         = CB_Clone(host);
    self->interval     = interval;

    // Derive.
    self->lock_path = CB_newf("locks/%o.lock", name);

    return self;
}
Ejemplo n.º 2
0
bool_t
LFLock_maybe_delete_file(LockFileLock *self, const CharBuf *path,
                         bool_t delete_mine, bool_t delete_other) {
    Folder *folder  = self->folder;
    bool_t  success = false;
    ZombieCharBuf *scratch = ZCB_WRAP(path);

    // Only delete locks that start with our lock name.
    CharBuf *lock_dir_name = (CharBuf*)ZCB_WRAP_STR("locks", 5);
    if (!ZCB_Starts_With(scratch, lock_dir_name)) {
        return false;
    }
    ZCB_Nip(scratch, CB_Get_Size(lock_dir_name) + 1);
    if (!ZCB_Starts_With(scratch, self->name)) {
        return false;
    }

    // Attempt to delete dead lock file.
    if (Folder_Exists(folder, path)) {
        Hash *hash = (Hash*)Json_slurp_json(folder, path);
        if (hash != NULL && Obj_Is_A((Obj*)hash, HASH)) {
            CharBuf *pid_buf = (CharBuf*)Hash_Fetch_Str(hash, "pid", 3);
            CharBuf *host    = (CharBuf*)Hash_Fetch_Str(hash, "host", 4);
            CharBuf *name
                = (CharBuf*)Hash_Fetch_Str(hash, "name", 4);

            // Match hostname and lock name.
            if (host != NULL
                && CB_Equals(host, (Obj*)self->host)
                && name != NULL
                && CB_Equals(name, (Obj*)self->name)
                && pid_buf != NULL
               ) {
                // Verify that pid is either mine or dead.
                int pid = (int)CB_To_I64(pid_buf);
                if ((delete_mine && pid == PID_getpid())  // This process.
                    || (delete_other && !PID_active(pid)) // Dead pid.
                   ) {
                    if (Folder_Delete(folder, path)) {
                        success = true;
                    }
                    else {
                        CharBuf *mess
                            = MAKE_MESS("Can't delete '%o'", path);
                        DECREF(hash);
                        Err_throw_mess(ERR, mess);
                    }
                }
            }
        }
        DECREF(hash);
    }

    return success;
}
Ejemplo n.º 3
0
static Folder*
S_enclosing_folder(Folder *self, ZombieCharBuf *path) {
    size_t path_component_len = 0;
    uint32_t code_point;

    // Strip trailing slash.
    if (ZCB_Code_Point_From(path, 0) == '/') {
        ZCB_Chop(path, 1);
    }

    // Find first component of the file path.
    ZombieCharBuf *scratch        = ZCB_WRAP((CharBuf*)path);
    ZombieCharBuf *path_component = ZCB_WRAP((CharBuf*)path);
    while (0 != (code_point = ZCB_Nip_One(scratch))) {
        if (code_point == '/') {
            ZCB_Truncate(path_component, path_component_len);
            ZCB_Nip(path, path_component_len + 1);
            break;
        }
        path_component_len++;
    }

    // If we've eaten up the entire filepath, self is enclosing folder.
    if (ZCB_Get_Size(scratch) == 0) {
        return self;
    }

    Folder *local_folder
        = Folder_Local_Find_Folder(self, (CharBuf*)path_component);
    if (!local_folder) {
        /* This element of the filepath doesn't exist, or it's not a
         * directory.  However, there are filepath characters left over,
         * implying that this component ought to be a directory -- so the
         * original file path is invalid. */
        return NULL;
    }

    // This file path component is a folder.  Recurse into it.
    return S_enclosing_folder(local_folder, path);
}
Ejemplo n.º 4
0
bool_t
Seg_valid_seg_name(const CharBuf *name) {
    if (CB_Starts_With_Str(name, "seg_", 4)) {
        ZombieCharBuf *scratch = ZCB_WRAP(name);
        ZCB_Nip(scratch, 4);
        uint32_t code_point;
        while (0 != (code_point = ZCB_Nip_One(scratch))) {
            if (!isalnum(code_point)) { return false; }
        }
        if (ZCB_Get_Size(scratch) == 0) { return true; } // Success!
    }
    return false;
}
Ejemplo n.º 5
0
int32_t
CB_hash_sum(CharBuf *self) {
    uint32_t hashvalue = 5381;
    ZombieCharBuf *iterator = ZCB_WRAP(self);

    const CB_Nip_One_t nip_one = METHOD_PTR(iterator->vtable, Lucy_CB_Nip_One);
    while (iterator->size) {
        uint32_t code_point = (uint32_t)nip_one((CharBuf*)iterator);
        hashvalue = ((hashvalue << 5) + hashvalue) ^ code_point;
    }

    return (int32_t) hashvalue;
}
Ejemplo n.º 6
0
static void
test_To_String(TestBatch *batch) {
    Obj *testobj = S_new_testobj();
    CharBuf *string = Obj_To_String(testobj);
    ZombieCharBuf *temp = ZCB_WRAP(string);
    while (ZCB_Get_Size(temp)) {
        if (ZCB_Starts_With_Str(temp, "TestObj", 7)) {
            break;
        }
        ZCB_Nip_One(temp);
    }
    TEST_TRUE(batch, ZCB_Starts_With_Str(temp, "TestObj", 7), "To_String");
    DECREF(string);
    DECREF(testobj);
}
Ejemplo n.º 7
0
Archivo: Folder.c Proyecto: theory/lucy
Folder*
Folder_find_folder(Folder *self, const CharBuf *path) {
    if (!path || !CB_Get_Size(path)) {
        return self;
    }
    else {
        ZombieCharBuf *scratch = ZCB_WRAP(path);
        Folder *enclosing_folder = S_enclosing_folder(self, scratch);
        if (!enclosing_folder) {
            return NULL;
        }
        else {
            return Folder_Local_Find_Folder(enclosing_folder,
                                            (CharBuf*)scratch);
        }
    }
}
Ejemplo n.º 8
0
Lock*
IxManager_make_snapshot_read_lock(IndexManager *self, const CharBuf *filename)
{
    ZombieCharBuf *lock_name = ZCB_WRAP(filename);
    LockFactory *lock_factory = S_obtain_lock_factory(self);
    
    if (   !CB_Starts_With_Str(filename, "snapshot_", 9)
        || !CB_Ends_With_Str(filename, ".json", 5)
    ) {
        THROW(ERR, "Not a snapshot filename: %o", filename);
    }
        
    // Truncate ".json" from end of snapshot file name. 
    ZCB_Chop(lock_name, sizeof(".json") - 1);

    return LockFact_Make_Shared_Lock(lock_factory, (CharBuf*)lock_name, 1000, 100);
}
Ejemplo n.º 9
0
Archivo: Folder.c Proyecto: theory/lucy
Folder*
Folder_enclosing_folder(Folder *self, const CharBuf *path) {
    ZombieCharBuf *scratch = ZCB_WRAP(path);
    return S_enclosing_folder(self, scratch);
}
Ejemplo n.º 10
0
static void
S_append_json_string(Obj *dump, CharBuf *json) {
    // Append opening quote.
    CB_Cat_Trusted_Str(json, "\"", 1);

    // Process string data.
    ZombieCharBuf *iterator = ZCB_WRAP((CharBuf*)dump);
    while (ZCB_Get_Size(iterator)) {
        uint32_t code_point = ZCB_Nip_One(iterator);
        if (code_point > 127) {
            // There is no need to escape any high characters, including those
            // above the BMP, as we assume that the destination channel can
            // handle arbitrary UTF-8 data.
            CB_Cat_Char(json, code_point);
        }
        else {
            char buffer[7];
            size_t len;
            switch (code_point & 127) {
                    // Perform all mandatory escapes enumerated in the JSON spec.
                    // Note that the spec makes escaping forward slash optional;
                    // we choose not to.
                case 0x00: case 0x01: case 0x02: case 0x03:
                case 0x04: case 0x05: case 0x06: case 0x07:
                case 0x0b: case 0x0e: case 0x0f:
                case 0x10: case 0x11: case 0x12: case 0x13:
                case 0x14: case 0x15: case 0x16: case 0x17:
                case 0x18: case 0x19: case 0x1a: case 0x1b:
                case 0x1c: case 0x1d: case 0x1e: case 0x1f: {
                        sprintf(buffer, "\\u%04x", (unsigned)code_point);
                        len = 6;
                        break;
                    }
                case '\b':
                    memcpy(buffer, "\\b", 2);
                    len = 2;
                    break;
                case '\t':
                    memcpy(buffer, "\\t", 2);
                    len = 2;
                    break;
                case '\n':
                    memcpy(buffer, "\\n", 2);
                    len = 2;
                    break;
                case '\f':
                    memcpy(buffer, "\\f", 2);
                    len = 2;
                    break;
                case '\r':
                    memcpy(buffer, "\\r", 2);
                    len = 2;
                    break;
                case '\\':
                    memcpy(buffer, "\\\\", 2);
                    len = 2;
                    break;
                case '\"':
                    memcpy(buffer, "\\\"", 2);
                    len = 2;
                    break;

                    // Ordinary printable ASCII.
                default:
                    buffer[0] = (char)code_point;
                    len = 1;
            }
            CB_Cat_Trusted_Str(json, buffer, len);
        }
    }

    // Append closing quote.
    CB_Cat_Trusted_Str(json, "\"", 1);
}