File: query.c

package info (click to toggle)
vstream-client 1.2.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 548 kB
  • sloc: ansic: 4,307; sh: 92; awk: 59; makefile: 42
file content (124 lines) | stat: -rw-r--r-- 2,693 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
  media-filesystem object query code
  tridge@samba.org, January 2001
  released under the Gnu GPL v2
*/

#include "mfs.h"

static struct {
	int fsid;
	void *buf;
	int size;
} loaded;

static void load_object(int fsid)
{
	if (fsid == loaded.fsid) return;

	if (loaded.buf) free(loaded.buf);

	loaded.size = vstream_mfs_fsid_size(fsid);
	loaded.buf = malloc(loaded.size);
	loaded.fsid = fsid;
	vstream_mfs_fsid_pread(fsid, loaded.buf, 0, loaded.size);
}

static int subobj_g=0;
static char *name_g=NULL;
static int *len_g=NULL;
static void *ret_g=NULL;

static void callback(int fsid, struct mfs_subobj_header *obj,
      struct mfs_attr_header *attr, void *data)
{
	if (!attr) return;
	if (!(obj->flags && subobj_g == -1) && !(obj->id == subobj_g)) return;
	if (strcmp(vstream_schema_attrib(obj->obj_type, attr->attr), name_g)) return;
	*len_g = attr->len;
	ret_g = data;
}

/* return the data portion of a part of an object */
void *vstream_query_part(int fsid, int subobj, char *name, int *len)
{
	if (vstream_mfs_fsid_type(fsid) != MFS_TYPE_OBJ) {
		vstream_error("%d is not an object\n", fsid);
		return NULL;
	}

	load_object(fsid);
	subobj_g = subobj;
	name_g = name;
	len_g = len;
	vstream_parse_object(fsid, loaded.buf, callback);
   
	return ret_g;
}

/* query a subobject path starting at fsid returning the data in the
   tail of the path */
static int vstream_myisdigit( char p )
{
   if ( ( p >= '0' ) && ( p <= '9' ) )
      return( 1 );
   return( 0 );
}

void *vstream_query_path(int fsid, char *path, int *len)
{
	char *tok, *p;
	void *ret=NULL;
	int subobj = -1;
	
	path = strdup(path);
	tok = strtok_r(path,"/", &p);

	while (tok) {
		ret = vstream_query_part(fsid, subobj, tok, len);
		if (!ret) return NULL;
		tok = strtok_r(NULL,"/", &p);
		if (tok && vstream_myisdigit(tok[0])) {
			subobj = atoi(tok);
			tok = strtok_r(NULL,"/", &p);
		} else if (tok) {
			struct mfs_obj_attr *objattr = ret;
			fsid = ntohl(objattr->fsid);
			subobj = ntohl(objattr->subobj);
		}
	}
	free(path);
	return ret;
}

char *vstream_query_string(int fsid, char *path)
{
	int len;
	char *p = vstream_query_path(fsid, path, &len);
	return p;
}

int vstream_query_int(int fsid, char *path)
{
	int len;
	int *p = vstream_query_path(fsid, path, &len);
	if (!p) return -1;
	return ntohl(*p);
}

struct mfs_obj_attr *query_object(int fsid, char *path, int *count)
{
	int len, i;
	struct mfs_obj_attr *ret = NULL;
	struct mfs_obj_attr *p = vstream_query_path(fsid, path, &len);
	if (!p) return ret;
	*count = (len-4)/8;
	ret = calloc(*count, sizeof(*ret));
	for (i=0;i<*count;i++) {
		ret[i] = p[i];
		ret[i].fsid = ntohl(ret[i].fsid);
		ret[i].subobj = ntohl(ret[i].subobj);
	}
	return ret;
}