예제 #1
0
파일: develop.c 프로젝트: BPotato/fluffos
void f_destructed_objects (void)
{
    int i;
    array_t *ret;
    object_t *ob;

    ret = allocate_empty_array(tot_dangling_object);
    ob = obj_list_dangling;

    for (i = 0;  i < tot_dangling_object;  i++) {
        ret->item[i].type = T_ARRAY;
        ret->item[i].u.arr = allocate_empty_array(2);
        ret->item[i].u.arr->item[0].type = T_STRING;
        ret->item[i].u.arr->item[0].subtype = STRING_SHARED;
        ret->item[i].u.arr->item[0].u.string = make_shared_string(ob->obname);
        ret->item[i].u.arr->item[1].type = T_NUMBER;
        ret->item[i].u.arr->item[1].u.number = ob->ref;

        ob = ob->next_all;
    }

    push_refed_array(ret);
}
예제 #2
0
파일: db.c 프로젝트: BPotato/fluffos
void f_db_exec (void)
{
	int ret = 0;
	db_t *db;
	array_t *info;
	info = allocate_empty_array(1);
	info->item[0].type = T_STRING;
	info->item[0].subtype = STRING_MALLOC;
	info->item[0].u.string = string_copy(sp->u.string, "f_db_exec");
	valid_database("exec", info);

	db = find_db_conn((sp-1)->u.number);
	if (!db) {
		error("Attempt to exec on an invalid database handle\n");
	}

#ifdef PACKAGE_ASYNC
	if(!db_mut){
		db_mut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
		pthread_mutex_init(db_mut, NULL);
	}
	pthread_mutex_lock(db_mut);
#endif
	if (db->type->cleanup) {
		db->type->cleanup(&(db->c));
	}

	if (db->type->execute) {
		ret = db->type->execute(&(db->c), sp->u.string);
	}

	pop_stack();
	if (ret == -1) {
		if (db->type->error) {
			char *errormsg;

			errormsg = db->type->error(&(db->c));
			put_malloced_string(errormsg);
		} else {
			put_constant_string("Unknown error");
		}
	} else {
		sp->u.number = ret;
	}
#ifdef PACKAGE_ASYNC
	pthread_mutex_unlock(db_mut);
#endif
}
예제 #3
0
void f_named_livings() {
    int i;
    int nob;
#ifdef F_SET_HIDE
    int apply_valid_hide, display_hidden = 0;
#endif
    object_t *ob, **obtab;
    array_t *vec;

    nob = 0;
#ifdef F_SET_HIDE
    apply_valid_hide = 1;
#endif

    obtab = CALLOCATE(max_array_size, object_t *, TAG_TEMPORARY, "named_livings");

    for (i = 0; i < CFG_LIVING_HASH_SIZE; i++) {
	for (ob = hashed_living[i]; ob; ob = ob->next_hashed_living) {
	    if (!(ob->flags & O_ENABLE_COMMANDS))
		continue;
#ifdef F_SET_HIDE
	    if (ob->flags & O_HIDDEN) {
		if (apply_valid_hide) {
		    apply_valid_hide = 0;
		    display_hidden = valid_hide(current_object);
		}
		if (!display_hidden)
		    continue;
	    }
#endif
	    if (nob == max_array_size)
		break;
	    obtab[nob++] = ob;
	}
    }

    vec = allocate_empty_array(nob);
    while (--nob >= 0) {
	vec->item[nob].type = T_OBJECT;
	vec->item[nob].u.ob = obtab[nob];
	add_ref(obtab[nob], "livings");
    }

    FREE(obtab);

    push_refed_array(vec);
}    
예제 #4
0
파일: file.c 프로젝트: Elohim/FGmud
static void encode_stat (svalue_t * vp, int flags, char * str, struct stat * st)
{
    if (flags == -1) {
        array_t *v = allocate_empty_array(3);

        v->item[0].type = T_STRING;
        v->item[0].subtype = STRING_MALLOC;
        v->item[0].u.string = string_copy(str, "encode_stat");
        v->item[1].type = T_NUMBER;
        v->item[1].u.number =
            ((st->st_mode & S_IFDIR) ? -2 : st->st_size);
        v->item[2].type = T_NUMBER;
        v->item[2].u.number = st->st_mtime;
        vp->type = T_ARRAY;
        vp->u.arr = v;
    } else {
        vp->type = T_STRING;
        vp->subtype = STRING_MALLOC;
        vp->u.string = string_copy(str, "encode_stat");
    }
}
예제 #5
0
/*
 * check permission
 */
int check_valid_socket (const char * const what, int fd, object_t * owner,
        const char * const addr, int port)
{
    array_t *info;
    svalue_t *mret;

    info = allocate_empty_array(4);
    info->item[0].type = T_NUMBER;
    info->item[0].u.number = fd;
    assign_socket_owner(&info->item[1], owner);
    info->item[2].type = T_STRING;
    info->item[2].subtype = STRING_SHARED;
    info->item[2].u.string = make_shared_string(addr);
    info->item[3].type = T_NUMBER;
    info->item[3].u.number = port;

    push_object(current_object);
    push_constant_string(what);
    push_refed_array(info);

    mret = apply_master_ob(APPLY_VALID_SOCKET, 3);
    return MASTER_APPROVED(mret);
}
예제 #6
0
파일: sockets.c 프로젝트: Yuffster/fluffOS
void
f_socket_status (void)
{
     array_t *info;
     int i;
     
     if (st_num_arg) {
	 info = socket_status(sp->u.number);
	 
	 if (!info) {
	     sp->u.number = 0;
	 } else {
	     sp->type = T_ARRAY;
	     sp->u.arr = info;
	 }
     } else {
	 info = allocate_empty_array(max_lpc_socks);
	 for (i = 0; i < max_lpc_socks; i++) {
	     info->item[i].type = T_ARRAY;
	     info->item[i].u.arr = socket_status(i);
	 }
	 push_refed_array(info);
     }
}
예제 #7
0
파일: pcre.c 프로젝트: BPotato/fluffos
static array_t *pcre_match(array_t *v, svalue_t *pattern, int flag)
{
	pcre_t *run;
	array_t *ret;
	svalue_t *sv1, *sv2;
	char *res;
	int num_match, size, match = !(flag & 2);

	if (!(size = v->size))
		return &the_null_array;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_match : run");
	run->ovector = NULL;
	run->ovecsize = 0;
	assign_svalue_no_free(&run->pattern, pattern);

	run->re = pcre_get_cached_pattern(&pcre_cache, &run->pattern);

	if (run->re == NULL)
	{
		if (pcre_local_compile(run) == NULL)
		{
			const char *rerror = run->error;
			int offset = run->erroffset;

			pcre_free_memory(run);
			error("PCRE compilation failed at offset %d: %s\n", offset, rerror);
		}
		else
			pcre_cache_pattern(&pcre_cache, run->re, &run->pattern);
	}

	res       = (char*)DMALLOC(size, TAG_TEMPORARY, "prcre_match: res");
	sv1       = v->item + size;
	num_match = 0;

	while (size--)
	{
		if ((--sv1)->type != T_STRING)
		{
			res[size] = 0;
			continue;
		}

		run->subject  = sv1->u.string;
		run->s_length = SVALUE_STRLEN(sv1);

		pcre_local_exec(run);

		if (pcre_query_match(run) != match) //was not checking for match! (woom)
		{
			res[size] = 0;
			continue;
		}

		res[size] = 1;
		num_match++;
	}

	flag &= 1;
	ret  = allocate_empty_array(num_match << flag);
	sv2  = ret->item + (num_match << flag);
	size = v->size;

	while (size--)
	{
		if (res[size])
		{
			if (flag)
			{
				(--sv2)->type = T_NUMBER;
				sv2->u.number = size + 1;
			}

			(--sv2)->type = T_STRING;

			sv1  = v->item + size;
			*sv2 = *sv1;

			if (sv1->subtype & STRING_COUNTED)
			{
				INC_COUNTED_REF(sv1->u.string);
				ADD_STRING(MSTR_SIZE(sv1->u.string));
			}

			if (!--num_match)
				break;
		}
	}
	FREE(res);
	pcre_free_memory(run);

	return ret;
}
예제 #8
0
파일: file.c 프로젝트: Elohim/FGmud
array_t *get_dir (const char * path, int flags)
{
    array_t *v;
    int i, count = 0;
#ifndef WIN32
    DIR *dirp;
#endif
    int namelen, do_match = 0;

#ifndef WIN32
#ifdef USE_STRUCT_DIRENT
    struct dirent *de;
#else
    struct direct *de;
#endif
#endif
    struct stat st;
    char *endtemp;
    char temppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 2];
    char regexppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 2];
    char *p;

#ifdef WIN32
    struct _finddata_t FindBuffer;
    long FileHandle, FileCount;
#endif

    if (!path)
        return 0;

    path = check_valid_path(path, current_object, "stat", 0);

    if (path == 0)
        return 0;

    if (strlen(path) < 2) {
        temppath[0] = path[0] ? path[0] : '.';
        temppath[1] = '\000';
        p = temppath;
    } else {
        strncpy(temppath, path, MAX_FNAME_SIZE + MAX_PATH_LEN + 1);
        temppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 1] = '\0';

        /*
         * If path ends with '/' or "/." remove it
         */
        if ((p = strrchr(temppath, '/')) == 0)
            p = temppath;
        if (p[0] == '/' && ((p[1] == '.' && p[2] == '\0') || p[1] == '\0'))
            *p = '\0';
    }

    if (stat(temppath, &st) < 0) {
        if (*p == '\0')
            return 0;
        if (p != temppath) {
            strcpy(regexppath, p + 1);
            *p = '\0';
        } else {
            strcpy(regexppath, p);
            strcpy(temppath, ".");
        }
        do_match = 1;
    } else if (*p != '\0' && strcmp(temppath, ".")) {
        if (*p == '/' && *(p + 1) != '\0')
            p++;
        v = allocate_empty_array(1);
        encode_stat(&v->item[0], flags, p, &st);
        return v;
    }
#ifdef WIN32
    FileHandle = -1;
    FileCount = 1;
/*    strcat(temppath, "\\*"); */
    strcat(temppath, "/*");
    if ((FileHandle = _findfirst(temppath, &FindBuffer)) == -1) return 0;
#else
    if ((dirp = opendir(temppath)) == 0)
        return 0;
#endif

    /*
     * Count files
     */
#ifdef WIN32
    do {
        if (!do_match && (!strcmp(FindBuffer.name, ".") ||
                          !strcmp(FindBuffer.name, ".."))) {
            continue;
        }
        if (do_match && !match_string(regexppath, FindBuffer.name)) {
            continue;
        }
        count++;
        if (count >= max_array_size) {
            break;
        }
    } while (!_findnext(FileHandle, &FindBuffer));
    _findclose(FileHandle);
#else
    for (de = readdir(dirp); de; de = readdir(dirp)) {
#ifdef USE_STRUCT_DIRENT
        namelen = strlen(de->d_name);
#else
        namelen = de->d_namlen;
#endif
        if (!do_match && (strcmp(de->d_name, ".") == 0 ||
                          strcmp(de->d_name, "..") == 0))
            continue;
        if (do_match && !match_string(regexppath, de->d_name))
            continue;
        count++;
        if (count >= max_array_size)
            break;
    }
#endif

    /*
     * Make array and put files on it.
     */
    v = allocate_empty_array(count);
    if (count == 0) {
        /* This is the easy case :-) */
#ifndef WIN32
        closedir(dirp);
#endif
        return v;
    }
#ifdef WIN32
    FileHandle = -1;
    if ((FileHandle = _findfirst(temppath, &FindBuffer)) == -1) return 0;
    endtemp = temppath + strlen(temppath) - 2;
    *endtemp = 0;
/*    strcat(endtemp++, "\\"); */
    strcat(endtemp++, "/");
    i = 0;
    do {
        if (!do_match && (!strcmp(FindBuffer.name, ".") ||
                          !strcmp(FindBuffer.name, ".."))) continue;
        if (do_match && !match_string(regexppath, FindBuffer.name)) continue;
        if (flags == -1) {
            strcpy(endtemp, FindBuffer.name);
            stat(temppath, &st);
        }
        encode_stat(&v->item[i], flags, FindBuffer.name, &st);
        i++;
    } while (!_findnext(FileHandle, &FindBuffer));
    _findclose(FileHandle);
#else                           /* WIN32 */
    rewinddir(dirp);
    endtemp = temppath + strlen(temppath);

    strcat(endtemp++, "/");

    for (i = 0, de = readdir(dirp); i < count; de = readdir(dirp)) {
#ifdef USE_STRUCT_DIRENT
        namelen = strlen(de->d_name);
#else
        namelen = de->d_namlen;
#endif
        if (!do_match && (strcmp(de->d_name, ".") == 0 ||
                          strcmp(de->d_name, "..") == 0))
            continue;
        if (do_match && !match_string(regexppath, de->d_name))
            continue;
        de->d_name[namelen] = '\0';
        if (flags == -1) {
            /*
             * We'll have to .... sigh.... stat() the file to get some add'tl
             * info.
             */
            strcpy(endtemp, de->d_name);
            stat(temppath, &st);/* We assume it works. */
        }
        encode_stat(&v->item[i], flags, de->d_name, &st);
        i++;
    }
    closedir(dirp);
#endif                          /* OS2 */

    /* Sort the names. */
    qsort((void *) v->item, count, sizeof v->item[0],
          (flags == -1) ? parrcmp : pstrcmp);
    return v;
}
예제 #9
0
파일: db.c 프로젝트: BPotato/fluffos
static array_t *msql_fetch (dbconn_t * c, int row)
{
	int i, num_fields;
	m_row this_row;
	array_t *v;

	if (!c->msql.result_set) {
		return &the_null_array;
	}
	if (row < 1 || row > msqlNumRows(c->msql.result_set)) {
		return &the_null_array;
	}

	num_fields = msqlNumFields(c->msql.result_set);
	if (num_fields < 1) {
		return &the_null_array;
	}

	msqlDataSeek(c->msql.result_set, row - 1);
	this_row = msqlFetchRow(c->msql.result_set);
	if (!this_row) {
		return &the_null_array;
	}

	v = allocate_empty_array(num_fields);
	for (i = 0;  i < num_fields;  i++) {
		m_field *field;

		field = msqlFetchField(c->msql.result_set);
		if (!field || !this_row[i]) {
			v->item[i] = const0u;
		} else {
			switch (field->type) {
			case INT_TYPE:
			case UINT_TYPE:
				v->item[i].type = T_NUMBER;
				v->item[i].u.number = atoi(this_row[i]);
				break;

			case REAL_TYPE:
			case MONEY_TYPE:
				v->item[i].type = T_REAL;
				v->item[i].u.real = atof(this_row[i]);
				break;

			case CHAR_TYPE:
			case TEXT_TYPE:
			case DATE_TYPE:
			case TIME_TYPE:
				v->item[i].type = T_STRING;
				v->item[i].subtype = STRING_MALLOC;
				v->item[i].u.string = string_copy(this_row[i], "msql_fetch");
				break;

			default:
				v->item[i] = const0u;
				break;
			}
		}
	}

	msqlFieldSeek(c->msql.result_set, 0);
	return v;
}
예제 #10
0
파일: pcre.c 프로젝트: BPotato/fluffos
/* This is mostly copy/paste from reg_assoc, some parts are changed
 * TODO: rewrite with new logic
 */
static array_t *pcre_assoc(svalue_t *str, array_t *pat, array_t *tok, svalue_t *def)
{
	int i, size;
	const char *tmp;
	array_t *ret;

	if ((size = pat->size) != tok->size)
		error("Pattern and token array size must be identical.\n");

	for (i = 0; i < size; i++)
		if (pat->item[i].type != T_STRING)
			error("Non-string found in pattern array.\n");

	ret = allocate_empty_array(2);

	if (size)
	{
		pcre_t **rgpp;
		struct reg_match {
			int tok_i;
			const char *begin, *end;
			struct reg_match *next;
		} *rmp = (struct reg_match *) 0, *rmph = (struct reg_match *) 0;
		int num_match = 0, length;
		svalue_t *sv1, *sv2, *sv;
		int regindex;
		pcre_t *tmpreg;
		int laststart;

		rgpp = CALLOCATE(size, pcre_t *, TAG_TEMPORARY, "pcre_assoc : rgpp");

		for (i = 0; i < size; i++)
		{
			rgpp[i] = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_assoc : rgpp[i]");
			rgpp[i]->ovector = NULL;
			rgpp[i]->ovecsize = 0;
			assign_svalue_no_free(&rgpp[i]->pattern, &pat->item[i]);
			rgpp[i]->re = pcre_get_cached_pattern(&pcre_cache, &rgpp[i]->pattern);

			if (rgpp[i]->re == NULL)
			{
				if (pcre_local_compile(rgpp[i]) == NULL)
				{
					const char *rerror = rgpp[i]->error;
					int offset = rgpp[i]->erroffset;

					while (i--)
						pcre_free_memory(rgpp[i]);

					FREE(rgpp);
					free_empty_array(ret);
					error("PCRE compilation failed at offset %d: %s\n", offset, rerror);
				}
				else
					pcre_cache_pattern(&pcre_cache, rgpp[i]->re, &rgpp[i]->pattern);
			}
		}


		tmp = str->u.string;
		int totalsize = SVALUE_STRLEN(str);
		int used = 0;
		while (*tmp)
		{
			laststart =  0;
			regindex  = -1;

			for (i = 0; i < size; i++)
			{

				rgpp[i]->subject = tmp;
				rgpp[i]->s_length = totalsize-used;

				pcre_local_exec(tmpreg = rgpp[i]);

				if (pcre_query_match(tmpreg))
				{
					char *curr_temp;
					size_t curr_temp_sz;

					curr_temp_sz = totalsize - used - tmpreg->ovector[0];
					if(!tmpreg->ovector[0]){
					  regindex = i;
					  break;
					}
					if (laststart < curr_temp_sz)
					{
						laststart = curr_temp_sz;
						regindex = i;
					}
				}
			}

			if (regindex >= 0)
			{
				const char *rmpb_tmp, *rmpe_tmp;
				size_t rmpb_tmp_sz, rmpe_tmp_sz;
				num_match++;

				if (rmp)
				{
					rmp->next = ALLOCATE(struct reg_match,
							TAG_TEMPORARY, "pcre_assoc : rmp->next");
					rmp = rmp->next;
				}
				else
					rmph = rmp = ALLOCATE(struct reg_match,
							TAG_TEMPORARY, "pcre_assoc : rmp");

				tmpreg = rgpp[regindex];

				rmpb_tmp = tmp + tmpreg->ovector[0];
				rmpe_tmp = tmp + tmpreg->ovector[1];

				rmp->begin = rmpb_tmp;
				rmp->end = tmp = rmpe_tmp;
				used+=tmpreg->ovector[1];
				rmp->tok_i = regindex;
				rmp->next = (struct reg_match *) 0;
			}
			else
				break;

			if (rmp->begin == tmp && (!*++tmp))
				break;
		}
예제 #11
0
 0., 0., 1., 0.,
 0., 0., 0., 1.};

static void print_matrix PROT((Matrix, char *));
static void print_array PROT((Vector *, char *));
static Vector *normalize_array PROT((Vector *));
static Vector *cross_product PROT((Vector *, Vector *, Vector *));
static Vector *points_to_array PROT((Vector *, Vector *, Vector *));

#ifdef F_ID_MATRIX
void f_id_matrix PROT((void))
{
    array_t *matrix;
    int i;

    matrix = allocate_empty_array(16);
    for (i = 0; i < 16; i++) {
        matrix->item[i].type = T_REAL;
        matrix->item[i].u.real = identity[i];
    }
    (++sp)->u.arr = matrix;
    sp->type = T_ARRAY;
}
#endif

#ifdef F_TRANSLATE
void f_translate PROT((void))
{
    array_t *matrix;
    double x, y, z;
    Matrix current_matrix;
예제 #12
0
파일: db.c 프로젝트: BPotato/fluffos
static array_t *MySQL_fetch (dbconn_t * c, int row)
{
	array_t *v;
	MYSQL_ROW target_row;
	unsigned int i, num_fields;

	if (!c->mysql.results) {
		return &the_null_array;
	}
	if (row < 0 || row > mysql_num_rows(c->mysql.results)) {
		return &the_null_array;
	}

	num_fields = mysql_num_fields(c->mysql.results);
	if (num_fields < 1) {
		return &the_null_array;
	}

	if(row>0){
		mysql_data_seek(c->mysql.results, row - 1);
		target_row = mysql_fetch_row(c->mysql.results);
		if (!target_row) {
			return &the_null_array;
		}
	}

	v = allocate_empty_array(num_fields);
	for (i = 0;  i < num_fields;  i++) {
		MYSQL_FIELD *field;

		field = mysql_fetch_field(c->mysql.results);

		if (row == 0) {
			if (field == (MYSQL_FIELD *)NULL) {
				v->item[i] = const0u;
			} else {
				v->item[i].type = T_STRING;
				v->item[i].subtype = STRING_MALLOC;
				v->item[i].u.string = string_copy(field->name, "f_db_fetch");
			}
			continue;
		}

		if (!field || !target_row[i]) {
			v->item[i] = const0u;
		} else {
			switch (field->type) {
			case FIELD_TYPE_TINY:
			case FIELD_TYPE_SHORT:
			case FIELD_TYPE_DECIMAL:
			case FIELD_TYPE_LONG:
			case FIELD_TYPE_INT24:
			case FIELD_TYPE_LONGLONG:
				v->item[i].type = T_NUMBER;
				v->item[i].subtype = 0;
				v->item[i].u.number = atoi(target_row[i]);
				break;

			case FIELD_TYPE_FLOAT:
			case FIELD_TYPE_DOUBLE:
				v->item[i].type = T_REAL;
				v->item[i].u.real = atof(target_row[i]);
				break;

			case FIELD_TYPE_TINY_BLOB:
			case FIELD_TYPE_MEDIUM_BLOB:
			case FIELD_TYPE_LONG_BLOB:
			case FIELD_TYPE_BLOB:
			case FIELD_TYPE_STRING:
			case FIELD_TYPE_VAR_STRING:
				if (field->flags & BINARY_FLAG) {
#ifndef NO_BUFFER_TYPE
					v->item[i].type = T_BUFFER;
					v->item[i].u.buf = allocate_buffer(field->max_length);
					write_buffer(v->item[i].u.buf, 0, target_row[i], field->max_length);
#else
					v->item[i] = const0u;
#endif
				} else {
					v->item[i].type = T_STRING;
					if (target_row[i]) {
						v->item[i].subtype = STRING_MALLOC;
						v->item[i].u.string = string_copy(target_row[i], "MySQL_fetch");
					} else {
						v->item[i].subtype = STRING_CONSTANT;
						v->item[i].u.string = "";
					}
				}
				break;

			default:
				v->item[i] = const0u;
				break;
			}
		}
	}

	mysql_field_seek(c->mysql.results, 0);
	return v;
}
예제 #13
0
파일: db.c 프로젝트: BPotato/fluffos
static array_t *SQLite3_fetch (dbconn_t * c, int row)
{
	int cols, last_row, length, i, r;
	array_t *v;

	if (!c->SQLite3.results) {
		return &the_null_array;
	}

	if (c->SQLite3.step_res && c->SQLite3.step_res != SQLITE_ROW) {
		return &the_null_array;
	}

	if (row < 0 || row > c->SQLite3.nrows) {
		return &the_null_array;
	}

	cols = sqlite3_column_count(c->SQLite3.results);
	if (cols < 1) {
		return &the_null_array;
	}

	/* If the fetch is for row 0 then we don't return a row from the prepared
	 * statement, instead we return an array containing the column names. This
	 * ability is useful in a number of circumstances when the column names are
	 * not known in advance for a query. We do not step the statement nor do we
	 * adjust the last_row index since sqlite provides a method to obtain the
	 * column names at any time.
	 */
	if (row == 0) {
		v = allocate_empty_array(cols);
		for (i = 0; i< cols; i++) {
			v->item[i].type = T_STRING;
			v->item[i].subtype = STRING_MALLOC;
			v->item[i].u.string = string_copy((char *)sqlite3_column_name(c->SQLite3.results, i), "SQLite3_fetch");
		}

		return v;
	}

	/* There is no quick entry to a row in the prepared statement. Thus we have
	 * too loop through till we reach the desired row, but only if the last row
	 * that we fetched is not the previous row... confused? join the club.
	 */
	last_row = c->SQLite3.last_row;

	/* If the requested row is before the last row that was accessed then we
	 * reset the compiled statement before continuing. This is because we can't
	 * just select a row at will using sqlite and we can't rewind a step either.
	 * We could just reset the result statement at the end of this function like
	 * the msql and mysql versions, but that gets expensive next time it's called
	 * if we need to walk through everything again... sigh
	 */
	if (row < last_row) {
		sqlite3_reset(c->SQLite3.results);
		c->SQLite3.last_row = 0;
		c->SQLite3.step_res = 0;
		last_row = 0;
	}

	/* If the requested row is the same as the last one, ie: it's been requested
	 * again! we do not need to step forward, so we miss the row location loop
	 * and get straight to the nitty gritty of building the result array. If not
	 * we loop through from the last_row requested to the one requested this time
	 * using sqlite3_step(). As long as the result is SQLITE_ROW we move on, if
	 * not then either an error occured or there are no more rows so we return a
	 * null array. The result is stored in the sqlite structure for later checks
	 * so if fetch is called again on a completed or errornous statement we can
	 * fail out sooner saving time.
	 */
	if ((row != last_row) && (last_row < row)) {
		for (i = last_row; i < row; i++) {
			c->SQLite3.step_res = sqlite3_step(c->SQLite3.results);

			if (c->SQLite3.step_res == SQLITE_ROW)
				break;
			else
				return &the_null_array;
		}
	}

	v = allocate_empty_array(cols);
	for (i = 0; i < cols; i++) {
		switch (sqlite3_column_type(c->SQLite3.results, i)) {
		case SQLITE_INTEGER:
			v->item[i].type = T_NUMBER;
			v->item[i].u.number = sqlite3_column_int(c->SQLite3.results, i);
			break;

		case SQLITE_FLOAT:
			v->item[i].type = T_REAL;
			v->item[i].u.real = (double)sqlite3_column_double(c->SQLite3.results, i);
			break;

		case SQLITE3_TEXT:
			v->item[i].type = T_STRING;
			v->item[i].subtype = STRING_MALLOC;
			v->item[i].u.string = string_copy((char *)sqlite3_column_text(c->SQLite3.results, i), "SQLite3_fetch");
			break;

		case SQLITE_BLOB:
#ifndef NO_BUFFER_TYPE
length = sqlite3_column_bytes(c->SQLite3.results, i);
v->item[i].type = T_BUFFER;
v->item[i].u.buf = allocate_buffer(length);
write_buffer(v->item[i].u.buf, 0, (char *)sqlite3_column_blob(c->SQLite3.results, i), length);
#else
	v->item[i] = const0u;
#endif
	break;

		default:
			v->item[i] = const0u;
			break;
		}
	}

	c->SQLite3.last_row = row;
	return v;
}
예제 #14
0
파일: db.c 프로젝트: BPotato/fluffos
void f_db_connect (void)
{
	char *errormsg = 0;
	const char *user = "", *database, *host;
	db_t *db;
	array_t *info;
	svalue_t *mret;
	int handle, ret = 0, args = 0, type;

#ifdef DEFAULT_DB
	type = DEFAULT_DB;
#else
	type = 0;
#endif

	switch (st_num_arg) {
	case 4: type     = (sp - (args++))->u.number;
	case 3: user     = (sp - (args++))->u.string;
	case 2: database = (sp - (args++))->u.string;
	case 1: host     = (sp - (args++))->u.string;
	}

	info = allocate_empty_array(3);
	info->item[0].type = info->item[1].type = info->item[2].type = T_STRING;
	info->item[0].subtype = info->item[1].subtype = info->item[2].subtype = STRING_MALLOC;
	info->item[0].u.string = string_copy(database, "f_db_connect:1");
	if (*host)
		info->item[1].u.string = string_copy(host, "f_db_connect:2");
	else
		info->item[1] = const0;
	info->item[2].u.string = string_copy(user, "f_db_connect:3");

	mret = valid_database("connect", info);

	handle = create_db_conn();
	if (!handle) {
		pop_n_elems(args);
		push_number(0);
		return;
	}
	db = find_db_conn(handle);

	switch (type) {
	default:
		/* fallthrough */
#ifdef USE_MSQL
#if USE_MSQL - 0
	case USE_MSQL:
#endif
		db->type = &msql;
		break;
#endif
#ifdef USE_MYSQL
#if USE_MYSQL - 0
	case USE_MYSQL:
#endif
		db->type = &mysql;
		break;
#endif
#ifdef USE_SQLITE2
#if USE_SQLITE2 - 0
	case USE_SQLITE2:
#endif
		db->type = &SQLite2;
		break;
#endif
#ifdef USE_SQLITE3
#if USE_SQLITE3 - 0
	case USE_SQLITE3:
#endif
		db->type = &SQLite3;
		break;
#endif
#ifdef USE_POSTGRES
#if USE_POSTGRES - 0
	case USE_POSTGRES:
#endif
		db->type = &postgres;
		break;
#endif
	}

	if (db->type->connect) {
		ret = db->type->connect(&(db->c), host, database, user,
				(mret != (svalue_t *)-1 && mret->type == T_STRING ? mret->u.string : 0));
	}

	pop_n_elems(args);

	if (!ret) {
		if (db->type->error) {
			errormsg = db->type->error(&(db->c));
			push_malloced_string(errormsg);
		} else {
			push_number(0);
		}
		free_db_conn(db);
	} else {
		push_number(handle);
	}
}
예제 #15
0
파일: db.c 프로젝트: BPotato/fluffos
static array_t *SQLite2_fetch (dbconn_t * c, int row)
{
	int last_row, length, i, l, r;
	char *p_end;
	const char *tail;
	double d;
	array_t *v;

	if (!c->SQLite2.vm) {
		/* We don't have a vm yet because the sql has not been compiled.
		 * This is down to db_exec using sqlite_get_table to execute the sql in the
		 * first instance.  This is the reason we saved the sql into the SQLite
		 * structure, compile it now and create a vm.  We return a null array only
		 * if the compile fails.
		 */
		r = sqlite_compile(c->SQLite2.handle, c->SQLite2.sql, NULL, &c->SQLite2.vm, &c->SQLite2.errormsg);
		if (r != SQLITE_OK || !c->SQLite2.vm)
			return &the_null_array;
	}

	if (c->SQLite2.step_res && c->SQLite2.step_res != SQLITE_ROW) {
		return &the_null_array;
	}

	if (row < 0 || row > c->SQLite2.nrows) {
		return &the_null_array;
	}

	if (c->SQLite2.ncolumns < 1) {
		return &the_null_array;
	}

	/* If the fetch is for row 0 then we don't return a row containing data values
	 * instead we return the column names. This has proven quite useful in a number
	 * of circumstances when they are unknown ahead of the query. Unlike SQLite3 we
	 * have no means of obtaining them without stepping the virtual machine so we
	 * have no choice. We will have to check the last_row and step_rc later to make
	 * sure we use the values here before we step again.
	 */
	if (row == 0) {
		c->SQLite2.step_res = sqlite_step(c->SQLite2.vm, NULL, &c->SQLite2.values, &c->SQLite2.col_names);
		if (c->SQLite2.step_res == SQLITE_ROW || c->SQLite2.step_res == SQLITE_DONE) {
			v = allocate_empty_array(c->SQLite2.ncolumns);
			for (i = 0; i < c->SQLite2.ncolumns; i++) {
				v->item[i].type = T_STRING;
				v->item[i].subtype = STRING_MALLOC;
				v->item[i].u.string = string_copy((char *)c->SQLite2.col_names[i], "SQLite2_fetch");
			}

			return v;
		}

		return &the_null_array;
	}

	/* There is no quick entry to a row in the prepared statement. Thus we have
	 * too loop through until we reach the desired row, but only if the last row
	 * that we fetched is not the previous row... confused? join the club.
	 */
	last_row = c->SQLite2.last_row;

	/* If the requested row is before the last row that was accessed then we need
	 * to re-compile the sql and recreate the virtual machine. SQLite3 provides a
	 * facility to reset a vm however SQLite2 does not. This is a downfall of
	 * SQLite in general though, we need to restart everything and walk through
	 * all of the results again until we get to the row we want... sigh
	 */
	if (row < last_row) {
		free(c->SQLite2.errormsg);
		sqlite_finalize(c->SQLite2.vm, NULL);

		if (sqlite_compile(c->SQLite2.handle, c->SQLite2.sql, &tail, &c->SQLite2.vm, &c->SQLite2.errormsg) != SQLITE_OK)
			return 0;

		c->SQLite2.last_row = 0;
		c->SQLite2.step_res = 0;
		last_row = 0;
	}

	/* If the requested row is the same as the last one, ie: it's been requested
	 * again! we do not need to step forward, so we miss the row location loop
	 * and get straight to the nitty gritty of building the result array. If not
	 * we loop through from the last_row requested to the one requested this time
	 * using sqlite_step(). As long as the result is SQLITE_ROW we move on, if
	 * not then either an error occured or there are no more rows so we return a
	 * null array. The result is stored in the SQLite structure for later checks
	 * so if fetch is called again on a completed or errornous statement we can
	 * fail out sooner saving time.
	 */
	if ((row != last_row) && (last_row < row)) {
		for (i = last_row; i < row; i++) {
			c->SQLite2.step_res = sqlite_step(c->SQLite2.vm, NULL, &c->SQLite2.values, &c->SQLite2.col_names);
			if (c->SQLite2.step_res == SQLITE_ROW)
				break;
			else
				return &the_null_array;
		}
	}

	/* SQLite v2 does not provide any functions for obtaining the values based on
	 * their datatypes like v3 does.  It is completely typeless and everything is
	 * returned as a (char *).  Thus we need a way of determining if the value is
	 * numeric or a string.  I do make some assumptions here, but all in all it
	 * does work for the vast majority of cases.  There is no support for blobs
	 * to be returned as LPC buffers with v2.  Support for binary data in v2 is
	 * suspect at best and is not recommended anyway, if you need that use v3.
	 *
	 * To determine the datatype, we do the following.  Run the value through
	 * strtoul() if it fails then the value could not be converted to a number
	 * so we assume it's a string and return it as such.  If it works but also
	 * has trailing data, then it might be a real number or a string.  Both
	 * "12.34" and "12 bottles" will cause strtoul() to work returning 12 but
	 * both will also have trailing data.  Thus we try converting it to a real
	 * number using strtod() if this fails then we assume its a string that
	 * starts with a number ie: "12 bottles" and return it as a string.  If it
	 * works then we return it as a real number (float).
	 *
	 * It's by no means perfect, but it does catch pretty much everything I've
	 * thrown at it and is the best solution, bar walking the embedded datatype
	 * description, if one was set, and working it out from that.
	 */
	v = allocate_empty_array(c->SQLite2.ncolumns);
	for (i = 0; i < c->SQLite2.ncolumns; i++) {
		/* If we have a NULL value get out now or we'll segfault */
		if (c->SQLite2.values[i] == NULL) {
			v->item[i] = const0u;
			continue;
		}

		errno = 0;
		l = strtoul(c->SQLite2.values[i], &p_end, 10);
		if (errno != 0 || c->SQLite2.values[i] == p_end) {
			/* The conversion failed so assume it's a string */
			v->item[i].type = T_STRING;
			v->item[i].subtype = STRING_MALLOC;
			v->item[i].u.string = string_copy((char *)c->SQLite2.values[i], "SQLite2_fetch");
		}

		else if (*p_end != 0) {
			/* The conversion left trailing characters behind, see if its a float */
			errno = 0;
			d = strtod(c->SQLite2.values[i], &p_end);
			if (errno != 0 || c->SQLite2.values[i] == p_end || *p_end != 0) {
				/* The conversion to float failed so it must be a string */
				v->item[i].type = T_STRING;
				v->item[i].subtype = STRING_MALLOC;
				v->item[i].u.string = string_copy((char *)c->SQLite2.values[i], "SQLite2_fetch");
			}
			else {
				/* It was a floating point number */
				v->item[i].type = T_REAL;
				v->item[i].u.real = (double)d;
			}
		}

		else if (errno == 0) {
			/* It was an integer */
			v->item[i].type = T_NUMBER;
			v->item[i].u.number = (int)l;
		}

		else {
			/* No idea what it was */
			v->item[i] = const0u;
		}
	}

	c->SQLite2.last_row = row;
	return v;
}
예제 #16
0
파일: pcre.c 프로젝트: BPotato/fluffos
				rmp->begin = rmpb_tmp;
				rmp->end = tmp = rmpe_tmp;
				used+=tmpreg->ovector[1];
				rmp->tok_i = regindex;
				rmp->next = (struct reg_match *) 0;
			}
			else
				break;

			if (rmp->begin == tmp && (!*++tmp))
				break;
		}

		sv       = ret->item;
		sv->type = T_ARRAY;
		sv1      = (sv->u.arr = allocate_empty_array(2*num_match + 1))->item;

		sv++;
		sv->type = T_ARRAY;
		sv2      = (sv->u.arr = allocate_empty_array(2*num_match + 1))->item;

		rmp = rmph;

		tmp = str->u.string;
		
		while (num_match--){
		    char *svtmp;
		    length        = rmp->begin - tmp;
		    
		    sv1->type     = T_STRING;
		    sv1->subtype  = STRING_MALLOC;
예제 #17
0
파일: array.c 프로젝트: quixadhal/discworld
array_t *explode_string P4(char *, str, int, slen, char *, del, int, len)
{
    char *p, *beg, *lastdel = (char *) NULL;
    int num, j, limit;
    array_t *ret;
    char *buff, *tmp;
    short sz;

    if (!slen)
	return null_array();

    /* return an array of length strlen(str) -w- one character per element */
    if (len == 0) {
	sz = 1;

	if (slen > max_array_size) {
	    slen = max_array_size;
	}
	ret = allocate_empty_array(slen);
	for (j = 0; j < slen; j++) {
	    ret->item[j].type = T_STRING;
	    ret->item[j].subtype = STRING_MALLOC;
	    ret->item[j].u.string = tmp = new_string(1, "explode_string: tmp");
	    tmp[0] = str[j];
	    tmp[1] = '\0';
	}
	return ret;
    }
    if (len == 1) {
	char delimeter;

	delimeter = *del;

	/*
	 * Skip leading 'del' strings, if any.
	 */
	while (*str == delimeter) {
	    str++;
	    slen--;
	    if (str[0] == '\0') {
		return null_array();
	    }
#ifdef SANE_EXPLODE_STRING
	    break;
#endif
	}

	/*
	 * Find number of occurences of the delimiter 'del'.
	 */
	for (p = str, num = 0; *p;) {
	    if (*p == delimeter) {
		num++;
		lastdel = p;
	    }
	    p++;
	}

	/*
	 * Compute number of array items. It is either number of delimiters,
	 * or, one more.
	 */
	limit = max_array_size;
	if (lastdel != (str + slen - 1)) {
	    num++;
	    limit--;
	}
	if (num > max_array_size) {
	    num = max_array_size;
	}
	ret = allocate_empty_array(num);
	for (p = str, beg = str, num = 0; *p && (num < limit);) {
	    if (*p == delimeter) {
		DEBUG_CHECK(num >= ret->size, "Index out of bounds in explode!\n");
		sz = p - beg;
		ret->item[num].type = T_STRING;
		ret->item[num].subtype = STRING_MALLOC;
		ret->item[num].u.string = buff = new_string(p - beg, "explode_string: buff");

		strncpy(buff, beg, p - beg);
		buff[p - beg] = '\0';
		num++;
		beg = ++p;
	    } else {
		p++;
	    }
	}

	/* Copy last occurence, if there was not a 'del' at the end. */
	if (*beg != '\0') {
	    ret->item[num].type = T_STRING;
	    ret->item[num].subtype = STRING_MALLOC;
	    ret->item[num].u.string = string_copy(beg, "explode_string: last, len == 1");
	}
	return ret;
    }				/* len == 1 */
    /*
     * Skip leading 'del' strings, if any.
     */
    while (strncmp(str, del, len) == 0) {
	str += len;
	slen -= len;
	if (str[0] == '\0') {
	    return null_array();
	}
#ifdef SANE_EXPLODE_STRING
	break;
#endif
    }

    /*
     * Find number of occurences of the delimiter 'del'.
     */
    for (p = str, num = 0; *p;) {
	if (strncmp(p, del, len) == 0) {
	    num++;
	    lastdel = p;
	    p += len;
	} else {
	    p++;
	}
    }

    /*
     * Compute number of array items. It is either number of delimiters, or,
     * one more.
     */
    if ((slen <= len) || (lastdel != (str + slen - len))) {
	num++;
    }
    if (num > max_array_size) {
	num = max_array_size;
    }
    ret = allocate_empty_array(num);
    limit = max_array_size - 1;	/* extra element can be added after loop */
    for (p = str, beg = str, num = 0; *p && (num < limit);) {
	if (strncmp(p, del, len) == 0) {
	    if (num >= ret->size)
		fatal("Index out of bounds in explode!\n");

	    ret->item[num].type = T_STRING;
	    ret->item[num].subtype = STRING_MALLOC;
	    ret->item[num].u.string = buff = new_string(p - beg, 
						     "explode_string: buff");

	    strncpy(buff, beg, p - beg);
	    buff[p - beg] = '\0';
	    num++;
	    beg = p + len;
	    p = beg;
	} else {
	    p++;
	}
    }

    /* Copy last occurence, if there was not a 'del' at the end. */
    if (*beg != '\0') {
	ret->item[num].type = T_STRING;
	ret->item[num].subtype = STRING_MALLOC;
	ret->item[num].u.string = string_copy(beg, "explode_string: last, len != 1");
    }
    return ret;
}
예제 #18
0
/* FIXME: most of the #ifdefs here should be based on configure checks
   instead.  Same for rusage() */
void
f_localtime (void)
{
    struct tm *tm;
    array_t *vec;
    time_t lt;

#ifdef sequent
    struct timezone tz;
#endif

    lt = sp->u.number;
    tm = localtime(&lt);

    vec = allocate_empty_array(11);
    vec->item[LT_SEC].type = T_NUMBER;
    vec->item[LT_SEC].u.number = tm->tm_sec;
    vec->item[LT_MIN].type = T_NUMBER;
    vec->item[LT_MIN].u.number = tm->tm_min;
    vec->item[LT_HOUR].type = T_NUMBER;
    vec->item[LT_HOUR].u.number = tm->tm_hour;
    vec->item[LT_MDAY].type = T_NUMBER;
    vec->item[LT_MDAY].u.number = tm->tm_mday;
    vec->item[LT_MON].type = T_NUMBER;
    vec->item[LT_MON].u.number = tm->tm_mon;
    vec->item[LT_YEAR].type = T_NUMBER;
    vec->item[LT_YEAR].u.number = tm->tm_year + 1900;
    vec->item[LT_WDAY].type = T_NUMBER;
    vec->item[LT_WDAY].u.number = tm->tm_wday;
    vec->item[LT_YDAY].type = T_NUMBER;
    vec->item[LT_YDAY].u.number = tm->tm_yday;
    vec->item[LT_GMTOFF].type = T_NUMBER;
    vec->item[LT_ZONE].type = T_STRING;
    vec->item[LT_ZONE].subtype = STRING_MALLOC;
    vec->item[LT_ISDST].type = T_NUMBER;
#if defined(BSD42) || defined(apollo) || defined(_AUX_SOURCE) \
        || defined(OLD_ULTRIX)
    /* 4.2 BSD doesn't seem to provide any way to get these last three values */
    vec->item[LT_GMTOFF].u.number = 0;
    vec->item[LT_ZONE].type = T_NUMBER;
    vec->item[LT_ZONE].u.number = 0;
    vec->item[LT_ISDST].u.number = -1;
#else                           /* BSD42 */
    vec->item[LT_ISDST].u.number = tm->tm_isdst;
#if defined(sequent)
    vec->item[LT_GMTOFF].u.number = 0;
    gettimeofday(NULL, &tz);
    vec->item[LT_GMTOFF].u.number = tz.tz_minuteswest;
    vec->item[LT_ZONE].u.string =
        string_copy(timezone(tz.tz_minuteswest, tm->tm_isdst), "f_localtime");
#else                           /* sequent */
#if (defined(hpux) || defined(_SEQUENT_) || defined(_AIX) || defined(SunOS_5) \
        || defined(SVR4) || defined(sgi) || defined(linux) || defined(cray) \
        || defined(LATTICE) || defined(SCO))
    if (!tm->tm_isdst) {
        vec->item[LT_GMTOFF].u.number = timezone;
        vec->item[LT_ZONE].u.string = string_copy(tzname[0], "f_localtime");
    } else {
#if (defined(_AIX) || defined(hpux) || defined(linux) || defined(cray) \
        || defined(LATTICE))
        vec->item[LT_GMTOFF].u.number = timezone;
#else
        vec->item[LT_GMTOFF].u.number = altzone;
#endif
        vec->item[LT_ZONE].u.string = string_copy(tzname[1], "f_localtime");
    }
#else
#ifndef WIN32
    vec->item[LT_GMTOFF].u.number = tm->tm_gmtoff;
    vec->item[LT_ZONE].u.string = string_copy(tm->tm_zone, "f_localtime");
#else
    vec->item[LT_GMTOFF].u.number = _timezone;
    vec->item[LT_ZONE].u.string = string_copy(_tzname[_daylight?1:0],"f_localtime");
#endif
#endif
#endif                          /* sequent */
#endif                          /* BSD42 */
    put_array(vec);
}
예제 #19
0
파일: array.c 프로젝트: quixadhal/discworld
void
filter_array P2(svalue_t *, arg, int, num_arg)
{
    array_t *vec = arg->u.arr, *r;
    int size;

    if ((size = vec->size) < 1) {
	pop_n_elems(num_arg - 1);
	return;
    }
    else {
	funptr_t *fp;
	object_t *ob = 0;
	char *func;

	char *flags = new_string(size, "TEMP: filter: flags");
	svalue_t *extra, *v;
	int res = 0, cnt, numex = 0;

	push_malloced_string(flags);

	if ((arg+1)->type == T_FUNCTION){
	    fp = (arg+1)->u.fp;
	    if (num_arg > 2) extra = arg+2, numex = num_arg - 2;
	} else {    
	    func = (arg+1)->u.string;
	    if (num_arg < 3) ob = current_object;
	    else {
		if ((arg+2)->type == T_OBJECT) ob = (arg+2)->u.ob;
		else if ((arg+2)->type == T_STRING){
		    if ((ob = find_object(arg[2].u.string)) && !object_visible(ob)) ob = 0;
		}
		if (!ob) bad_argument(arg+2, T_STRING | T_OBJECT, 3, F_FILTER);
		if (num_arg > 3) extra = arg + 3, numex = num_arg - 3;
	    }
	}

	for (cnt = 0; cnt < size; cnt++){
	    push_svalue(vec->item + cnt);
	    if (numex) push_some_svalues(extra, numex);
	    v = ob ? apply(func, ob, 1 + numex, ORIGIN_EFUN)
		: call_function_pointer(fp, 1 + numex);
	    if (!IS_ZERO(v)){
		flags[cnt] = 1;
		res++;
	    } else flags[cnt] = 0;
	}
	r = allocate_empty_array(res);
	if (res){
	    while (cnt--) {
		if (flags[cnt])
		    assign_svalue_no_free(&r->item[--res], vec->item+cnt);
	    }
	}

	FREE_MSTR(flags);
	sp--;
	pop_n_elems(num_arg - 1);
	free_array(vec);
	sp->u.arr = r;
    }
}