예제 #1
0
/**
 * copy a directory between branches (includes all contents of the directory)
 */
int copy_directory(const char *path, int branch_ro, int branch_rw) {
	DBG("%s\n", path);

	/* create the directory on the destination branch */
	int res = path_create(path, branch_ro, branch_rw);
	if (res != 0) {
		RETURN(res);
	}

	/* determine path to source directory on read-only branch */
	char from[PATHLEN_MAX];
	if (BUILD_PATH(from, uopt.branches[branch_ro].path, path)) RETURN(1);

	DIR *dp = opendir(from);
	if (dp == NULL) RETURN(1);

	struct dirent *de;
	while ((de = readdir(dp)) != NULL) {
		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;

		char member[PATHLEN_MAX];
		if (BUILD_PATH(member, path, "/", de->d_name)) {
			res = 1;
			break;
		}
		res = cow_cp(member, branch_ro, branch_rw, true);               
		if (res != 0) break;
	}

	closedir(dp);
	struct stat  buf;
	lstat(from, &buf);
	setfile(from, &buf);
	RETURN(res);
}
예제 #2
0
파일: item.c 프로젝트: Ecdosis/calliope
void item_add_path( item *it, char *p )
{
    if ( it->paths == NULL )
        it->paths = path_create(p);
    else
        path_append( it->paths, p );
}
예제 #3
0
/**
 * copy a directory between branches (includes all contents of the directory)
 */
int copy_directory(const char *path, int branch_ro, int branch_rw) {
	DBG_IN();

	/* create the directory on the destination branch */
	int res = path_create(path, branch_ro, branch_rw);
	if (res != 0) {
		return res;
	}

	/* determine path to source directory on read-only branch */
	char from[PATHLEN_MAX];
	if (BUILD_PATH(from, uopt.branches[branch_ro].path, path)) return 1;

	DIR *dp = opendir(from);
	if (dp == NULL) return 1;

	struct dirent *de;
	while ((de = readdir(dp)) != NULL) {
		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;

		char member[PATHLEN_MAX];
		if (BUILD_PATH(member, path, de->d_name)) return 1;
		res = cow_cp(member, branch_ro, branch_rw);
		if (res != 0) return res;
	}

	closedir(dp);
	return 0;
}
예제 #4
0
int tinyroute_main(struct audio_tool_config *config, int argc, char **argv)
{

		// 0. check for filename on cmd line rather than default
		if (argc > 1) {
			printf("Opening Mixer Paths XML %s\n", argv[1]);
			mixer_paths_xml = argv[1];
		} else {
			printf("Opening default file %s\n", MIXER_XML_PATH);
		}

    // 1. allocate audio_route and setup state
    struct audio_route *ar = setup_audio_route(config);
    struct config_parse_state state;
    memset(&state, 0, sizeof(state));
    state.ar = ar;
		// setup top level initial settings path
		state.path = path_create(ar, TOP_LEVEL_XML_SETTINGS);

    // 2. parse XML
    parse_xml(&state);

    // 3. print results
    print_routes(&state);

    return 0;

    // TODO: FREE RESOURCES
}
예제 #5
0
파일: findbranch.c 프로젝트: glk/puffs
/**
 * Find a writable root. If file does not exist, we check for 
 * the parent directory.
 **/
int find_rw_root_cutlast(const char *path) {
	int root = find_rw_root_cow(path);

	if (root < 0 && errno == ENOENT) {
		// So path does not exist, now again, but with dirname only
		char *dname = u_dirname(path);
		int root_rorw = find_rorw_root(dname);
		free(dname);

		// nothing found
		if (root_rorw < 0) return -1;

		// the returned root is writable, good!
		if (uopt.roots[root_rorw].rw) return root_rorw;
		
		// cow is disabled, return whatever was found
		if (!uopt.cow_enabled) return root_rorw;

		int root_rw = find_lowest_rw_root(root_rorw);

		dname = u_dirname(path);
		int res = path_create(dname, root_rorw, root_rw);
		free(dname);

		// creating the path failed
		if (res) return -1;

		return root_rw;
	}

	return root;
}
예제 #6
0
VGPath vgCreatePath(VGint pathFormat,
                    VGPathDatatype datatype,
                    VGfloat scale, VGfloat bias,
                    VGint segmentCapacityHint,
                    VGint coordCapacityHint,
                    VGbitfield capabilities)
{
   struct vg_context *ctx = vg_current_context();

   if (pathFormat != VG_PATH_FORMAT_STANDARD) {
      vg_set_error(ctx, VG_UNSUPPORTED_PATH_FORMAT_ERROR);
      return VG_INVALID_HANDLE;
   }
   if (datatype < VG_PATH_DATATYPE_S_8 ||
       datatype > VG_PATH_DATATYPE_F) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return VG_INVALID_HANDLE;
   }
   if (!scale) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return VG_INVALID_HANDLE;
   }

   return (VGPath)path_create(datatype, scale, bias,
                              segmentCapacityHint, coordCapacityHint,
                              capabilities);
}
예제 #7
0
파일: find-strings.c 프로젝트: bbyk/cwo
/**
 * Find a location of the suffix in the tree.
 * @param j the extension number counting from 0
 * @param i the current phase - 1
 * @return the position (combined node and edge-offset)
 */
static pos *find_beta( int j, int i )
{
    pos *p;
    if ( old_j > 0 && old_j == j )
    {
        p = pos_create();
        p->loc = old_beta.loc;
        p->v = old_beta.v;
    }
    else if ( j>i )  // empty string
    {
        p = pos_create();
        p->loc = 0;
        p->v = root;
    }
    else if ( j==0 )    // entire string
    {
        p = pos_create();
        p->loc = i;
        p->v = f;
    }
    else // walk across tree
    {
        node *v = last.v;
        int len = last.loc-node_start(last.v)+1;
        path *q = path_create( node_start(v), len );
        v = node_parent( v );
        while ( v != root && node_link(v)==NULL )
        {
            path_prepend( q, node_len(v) );
            v = node_parent( v );
        }
        if ( v != root )
        {
            v = node_link( v );
            p = walk_down( v, q );
        }
        else
        {
            path_dispose( q );
            p = walk_down( root, path_create(j,i-j+1) );
        }
    }
    last = *p;
    return p;
}
예제 #8
0
/* pathname -- true/nil error */
int ex_mkdir(lua_State *L)
{
  const char *pathname = luaL_checkstring(L, 1);
  if (!path_create(pathname))
    return push_error(L);
  lua_pushboolean(L, 1);
  return 1;
}
예제 #9
0
/**
 * Find a location of the suffix in the tree.
 * @param st the suffixtree in question
 * @param j the extension number counting from 0
 * @param i the current phase - 1
 * @param log the log to record errors in
 * @return the position (combined node and edge-offset)
 */ 
static pos *find_beta( suffixtree *st, int j, int i, plugin_log *log )
{
    pos *p;
    if ( st->old_j > 0 && st->old_j == j )
    {
        p = pos_create();
        p->loc = st->old_beta.loc;
        p->v = st->old_beta.v;
    }
    else if ( j>i )  // empty string
    {
        p = pos_create();
        p->loc = 0;
        p->v = st->root;
    }
    else if ( j==0 )    // entire string
    {
        p = pos_create();
        p->loc = i;
        p->v = st->f;
    }
    else // walk across tree
    {
        node *v = st->last.v;
        int len = st->last.loc-node_start(st->last.v)+1;
        path *q = path_create( node_start(v), len, log );
        v = node_parent( v );
        while ( v != st->root && node_link(v)==NULL )
        {
            path_prepend( q, node_len(v) );
            v = node_parent( v );
        }
        if ( v != st->root )
        {
            v = node_link( v );
            p = walk_down( st, v, q );
        }
        else
        {
            path_dispose( q );
            p = walk_down( st, st->root, path_create(j,i-j+1,log) );
        }
    }
    st->last = *p;
    return p;
}
예제 #10
0
/**
 * initiate the cow-copy action
 */
int cow_cp(const char *path, int branch_ro, int branch_rw, bool copy_dir) {
	DBG("%s\n", path);

	// create the path to the file
	path_create_cutlast(path, branch_ro, branch_rw);

	char from[PATHLEN_MAX], to[PATHLEN_MAX];
	if (BUILD_PATH(from, uopt.branches[branch_ro].path, path))
	       RETURN(-ENAMETOOLONG);
	if (BUILD_PATH(to, uopt.branches[branch_rw].path, path))
	       RETURN(-ENAMETOOLONG);

	setlocale(LC_ALL, "");

	struct cow cow;

	cow.uid = getuid();

	// Copy the umask for explicit mode setting.
	cow.umask = umask(0);
	umask(cow.umask);

	cow.from_path = from;
	cow.to_path = to;

	struct stat buf;
	lstat(cow.from_path, &buf);
	cow.stat = &buf;

	int res;
	switch (buf.st_mode & S_IFMT) {
	       case S_IFLNK:
		       res = copy_link(&cow);
		       break;
	       case S_IFDIR:
		       if (copy_dir) {
			       res = copy_directory(path, branch_ro, branch_rw);
		       } else {
			      res = path_create(path, branch_ro, branch_rw);
		       }
		       break;
	       case S_IFBLK:
	       case S_IFCHR:
		       res = copy_special(&cow);
		       break;
	       case S_IFIFO:
		       res = copy_fifo(&cow);
		       break;
	       case S_IFSOCK:
		       USYSLOG(LOG_WARNING, "COW of sockets not supported: %s\n", cow.from_path);
		       RETURN(1);
	       default:
		       res = copy_file(&cow);
	}

	RETURN(res);
}
예제 #11
0
파일: rd.c 프로젝트: mduft/tachyon3
static void rd_init() {
    /* find and protect initial ram disc */
    rd = mboot_find_rd();

    if(rd != NULL) {
        debug("rd found at %p, %d files\n", rd, rd->num_files);
        vfs_mount(path_create("/rd", &kheap), rd_ops);
    }
}
예제 #12
0
/* get attributes */
static int tag_getattr(const char *user_path, struct stat *stbuf)
{
    int res;
    print_log(_("getattr '%s'\n"), user_path);
    struct path *path = path_create(user_path, 0);
    res = getattr_intra(path, stbuf);
    print_log(_("getattr returning '%s'\n"), strerror(-res));
    path_delete(path);
    return res;
}
예제 #13
0
/**
 * Same as  path_create(), but ignore the last segment in path,
 * i.e. it might be a filename.
 */
int path_create_cutlast(const char *path, int nbranch_ro, int nbranch_rw) {
	DBG("%s\n", path);

	char *dname = u_dirname(path);
	if (dname == NULL)
		RETURN(-ENOMEM);
	int ret = path_create(dname, nbranch_ro, nbranch_rw);
	free(dname);

	RETURN(ret);
}
예제 #14
0
static int tag_open(
    const char *user_path, struct fuse_file_info *fi, int is_tag)
{
    struct path *path = path_create(user_path, is_tag);
    struct file_descriptor *fd;
    fd = fd_open(path, fi->flags, is_tag);
    if (IS_ERR(fd))
        return PTR_ERR(fd);
    fi->fh = (uint64_t) fd;
    return 0;
}
예제 #15
0
/**
 * Same as  path_create(), but ignore the last segment in path,
 * i.e. it might be a filename.
 */
int path_create_cutlast(const char *path, int nbranch_ro, int nbranch_rw) {
	DBG_IN();

	char *dname = u_dirname(path);
	if (dname == NULL)
		return -ENOMEM;
	int ret = path_create(dname, nbranch_ro, nbranch_rw);
	free(dname);

	return ret;
}
예제 #16
0
파일: path.cpp 프로젝트: Hunsu/fish-shell
/// Cache the data path.
bool path_get_data(wcstring &path) {
    static bool data_path_done = false;
    static wcstring data_path(L"");

    if (!data_path_done) {
        data_path_done = true;
        path_create(data_path, L"XDG_DATA_HOME", L"data", _(L"Your history will not be saved."));
    }

    path = data_path;
    return !data_path.empty();
}
예제 #17
0
파일: path.cpp 프로젝트: Hunsu/fish-shell
/// Cache the config path.
bool path_get_config(wcstring &path) {
    static bool config_path_done = false;
    static wcstring config_path(L"");

    if (!config_path_done) {
        path_create(config_path, L"XDG_CONFIG_HOME", L"config",
                    _(L"Your personal settings will not be saved."));
        config_path_done = true;
    }

    path = config_path;
    return !config_path.empty();
}
예제 #18
0
bool CONFIG::get_path_of_new_resource(POOL_MEM &path, POOL_MEM &extramsg, const char *component,
                                      const char *resourcetype, const char *name,
                                      bool error_if_exists, bool create_directories)
{
   POOL_MEM rel_path(PM_FNAME);
   POOL_MEM directory(PM_FNAME);
   POOL_MEM resourcetype_lowercase(resourcetype);
   resourcetype_lowercase.toLower();

   if (!get_path_of_resource(path, component, resourcetype, name, false)) {
      return false;
   }

   path_get_directory(directory, path);

   if (create_directories) {
      path_create(directory);
   }

   if (!path_exists(directory)) {
      extramsg.bsprintf("Resource config directory \"%s\" does not exist.\n", directory.c_str());
      return false;
   }

   /*
    * Store name for temporary file in extramsg.
    * Can be used, if result is true.
    * Otherwise it contains an error message.
    */
   extramsg.bsprintf("%s.tmp", path.c_str());

   if (!error_if_exists) {
      return true;
   }

   /*
    * File should not exists, as it is going to be created.
    */
   if (path_exists(path)) {
      extramsg.bsprintf("Resource config file \"%s\" already exists.\n", path.c_str());
      return false;
   }

   if (path_exists(extramsg)) {
      extramsg.bsprintf("Temporary resource config file \"%s.tmp\" already exists.\n", path.c_str());
      return false;
   }

   return true;
}
예제 #19
0
kr_adapter_path *kr_adapter_mkpath(kr_adapter *adapter,
 kr_adapter_path_setup *setup) {
  kr_adapter_path *path;
  path = NULL;
  if (adapter == NULL) return NULL;
  if (setup == NULL) return NULL;
  if (adapter->handle.exists == NULL) return NULL;
  if (adapter->info.api != setup->info.api) return NULL;
  if (path_setup_check(setup)) return NULL;
  path = path_alloc(adapter);
  if (path == NULL) return NULL;
  path_create(path, setup);
  return path;
}
예제 #20
0
파일: test.cpp 프로젝트: ben-jose/ben-jose
void
test_creat(int argc, char** argv){
	bj_ostream& os = bj_out;
	if(argc < 2){
		os << "Faltan args" << bj_eol;
		return;
	}

	ch_string pth = argv[1];

	os << "pth=" << pth << bj_eol;
	bool pth_ok = path_create(pth);
	MARK_USED(pth_ok);
	BRAIN_CK(pth_ok);
}
예제 #21
0
int
encode_sample_test(const struct ccn_pkey *signing_key, const struct ccn_pkey *verification_key, 
			const char *algorithm, char *paths[], char *contents[], 
			struct ccn_charbuf *signed_info, char *outname)
{
    int result = 0;
    int fd;
    struct path * cur_path = NULL;
    struct ccn_charbuf *buffer = ccn_charbuf_create();
    struct ccn_skeleton_decoder dd = {0};
    ssize_t res;

    printf("Encoding sample message data length %d\n", (int)strlen(contents[0]));
    cur_path = path_create(paths[0]);
    if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info, signing_key, 
			algorithm)) {
        printf("Failed to encode message!\n");
	result = 1;
    } else {
        printf("Encoded sample message length is %d\n", (int)buffer->length);

        res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length);
        if (!(res == buffer->length && dd.state == 0)) {
            printf("Failed to decode!  Result %d State %d\n", (int)res, dd.state);
            result = 1;
        }
        if (outname != NULL) {
            fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
            if (fd == -1)
                perror(outname);
            res = write(fd, buffer->buf, buffer->length);
            close(fd);
        }
        if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), verification_key) != 0) {
            result = 1;
        }
        printf("Expect signature verification failure: ");
        if (buffer->length >= 20)
            buffer->buf[buffer->length - 20] += 1;
        if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), verification_key) == 0) {
            result = 1;
        }
    }
    path_destroy(&cur_path);
    ccn_charbuf_destroy(&buffer);
    printf("Done with sample message\n");
    return result;
}
예제 #22
0
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_id = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    struct mixer_value mixer_value;

    /* Get name, id and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        if (strcmp(attr[i], "id") == 0)
            attr_id = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            printf("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(ar, state->path, sub_path);
            }
        }
    }
    else if (strcmp(tag_name, "ctl") == 0) {
        mixer_value.name = (char *) attr_name;
        mixer_value.value = (char *) attr_value;
        mixer_value.id = (char *) attr_id;

        path_add_value(ar, state->path, &mixer_value);
    }

    state->level++;
}
예제 #23
0
/* Allocate local fid struct and attach to fid->aux.
 */
Fid *
diod_fidalloc (Npfid *fid, Npstr *ns)
{
    Fid *f = malloc (sizeof (*f));

    NP_ASSERT (fid->aux == NULL);
    if (f) {
        f->flags = 0;
        f->ioctx = NULL;
        f->path = path_create (fid->conn->srv, ns);
        if (!f->path) {
            free (f);
            f = NULL;
        }
    }
    fid->aux = f;
  
    return f;
}
예제 #24
0
int
main (int    argc,
      char **argv)
{
	if (argv[1]) {
		path_head_t path;
		char *str;

		path_create (&path, argv[1]);

		if ((str = path_strdup (&path))) {
			printf ("%s (%zu)\n", str, path_strlen (&path));
			free (str);
		}

		path_destroy (&path);
	}
	return 0;
}
예제 #25
0
void vgPathTransformedBounds(VGPath path,
                             VGfloat * minX,
                             VGfloat * minY,
                             VGfloat * width,
                             VGfloat * height)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;
   VGbitfield caps;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   if (!minX || !minY || !width || !height) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (!is_aligned(minX) || !is_aligned(minY) ||
       !is_aligned(width) || !is_aligned(height)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   p = (struct path*)path;

   caps = path_capabilities(p);
   if (!(caps & VG_PATH_CAPABILITY_PATH_TRANSFORMED_BOUNDS)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }

#if 0
   /* faster, but seems to have precision problems... */
   path_bounding_rect(p, minX, minY, width, height);
   if (*width > 0 && *height > 0) {
      VGfloat pts[] = {*minX,          *minY,
                       *minX + *width, *minY,
                       *minX + *width, *minY + *height,
                       *minX,          *minY + *height};
      struct matrix *matrix = &ctx->state.vg.path_user_to_surface_matrix;
      VGfloat maxX, maxY;
      matrix_map_point(matrix, pts[0], pts[1], pts + 0, pts + 1);
      matrix_map_point(matrix, pts[2], pts[3], pts + 2, pts + 3);
      matrix_map_point(matrix, pts[4], pts[5], pts + 4, pts + 5);
      matrix_map_point(matrix, pts[6], pts[7], pts + 6, pts + 7);
      *minX = MIN2(pts[0], MIN2(pts[2], MIN2(pts[4], pts[6])));
      *minY = MIN2(pts[1], MIN2(pts[3], MIN2(pts[5], pts[7])));
      maxX = MAX2(pts[0], MAX2(pts[2], MAX2(pts[4], pts[6])));
      maxY = MAX2(pts[1], MAX2(pts[3], MAX2(pts[5], pts[7])));
      *width  = maxX - *minX;
      *height = maxY - *minY;
   }
#else
   {
      struct path *dst = path_create(VG_PATH_DATATYPE_F, 1.0, 0,
                                     0, 0, VG_PATH_CAPABILITY_ALL);
      path_transform(dst, p);
      path_bounding_rect(dst, minX, minY, width, height);
      path_destroy(dst);
   }
#endif
}
예제 #26
0
int
main (int argc, char *argv[]) {
    struct ccn_charbuf *buffer = ccn_charbuf_create();
    struct ccn_charbuf *signed_info = ccn_charbuf_create();
    struct ccn_skeleton_decoder dd = {0};
    ssize_t res;
    char *outname = NULL;
    int fd;
    int result = 0;
    char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length:   448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", 
 
			 "Quaer #%2d zjduer  badone",
                         "",
                         NULL};
    char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", 
		       "/d/e/f",
                       "/zero/length/content",
                       NULL};
    struct path * cur_path = NULL;
    struct ccn_keystore *keystore = ccn_keystore_create();
    char *home = getenv("HOME");
    char *keystore_suffix = "/.ccnx/.ccnx_keystore";
    char *keystore_name = NULL;

    int i;

    if (argc == 3 && strcmp(argv[1], "-o") == 0) {
	outname = argv[2];
    } else {
	printf("Usage: %s -o <outfilename>\n", argv[0]);
	exit(1);
    }

    if (home == NULL) {
        printf("Unable to determine home directory for keystore\n");
        exit(1);
    }
    keystore_name = calloc(1, strlen(home) + strlen(keystore_suffix) + 1);
    
    strcat(keystore_name, home);
    strcat(keystore_name, keystore_suffix);

    if (0 != ccn_keystore_init(keystore, keystore_name, "Th1s1sn0t8g00dp8ssw0rd.")) {
        printf("Failed to initialize keystore\n");
        exit(1);
    }

    printf("Creating signed_info\n");
    res = ccn_signed_info_create(signed_info,
                                 /*pubkeyid*/ccn_keystore_public_key_digest(keystore),
                                 /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore),
                                 /*datetime*/NULL,
                                 /*type*/CCN_CONTENT_GONE,
                                 /*freshness*/ 42,
                                 /*finalblockid*/NULL,
                                 /*keylocator*/NULL);
    if (res < 0) {
        printf("Failed to create signed_info!\n");
    }
    
    res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length);
    if (!(res == signed_info->length && dd.state == 0)) {
        printf("Failed to decode signed_info!  Result %d State %d\n", (int)res, dd.state);
        result = 1;
    }
    memset(&dd, 0, sizeof(dd));
    printf("Done with signed_info\n");

    printf("Encoding sample message data length %d\n", (int)strlen(contents[0]));
    cur_path = path_create(paths[0]);
    if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info, ccn_keystore_private_key(keystore))) {
	printf("Failed to encode message!\n");
    } else {
	printf("Encoded sample message length is %d\n", (int)buffer->length);

	res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length);
	if (!(res == buffer->length && dd.state == 0)) {
	    printf("Failed to decode!  Result %d State %d\n", (int)res, dd.state);
	    result = 1;
	}
        if (outname != NULL) {
            fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
            if (fd == -1)
                perror(outname);
            res = write(fd, buffer->buf, buffer->length);
            close(fd);
	}
        if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) != 0) {
	    result = 1;
	}
        printf("Expect signature verification failure: ");
        if (buffer->length >= 20)
            buffer->buf[buffer->length - 20] += 1;
	if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) == 0) {
	    result = 1;
	}
    }
    path_destroy(&cur_path);
    ccn_charbuf_destroy(&buffer);
    printf("Done with sample message\n");
    
    /* Now exercise as unit tests */
    
    for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) {
	printf("Unit test case %d\n", i);
	cur_path = path_create(paths[i]);
	buffer = ccn_charbuf_create();
	if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_private_key(keystore))) {
	    printf("Failed encode\n");
            result = 1;
	} else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) {
	    printf("Failed decode\n");
            result = 1;
	}
	path_destroy(&cur_path);
	ccn_charbuf_destroy(&buffer);
    }
    
    /* Test the uri encode / decode routines */
        
    init_all_chars_percent_encoded();
    const char *uri_tests[] = {
        "_+4", "ccnx:/this/is/a/test",       "",     "ccnx:/this/is/a/test",
        ".+4", "../test2?x=2",              "?x=2", "ccnx:/this/is/a/test2",
        "_-X", "../should/error",           "",     "",
        "_+2", "/missing/scheme",           "",     "ccnx:/missing/scheme",
        ".+0", "../../../../../././#/",     "#/",   "ccnx:/",
        ".+1", all_chars_percent_encoded,   "",     all_chars_percent_encoded_canon,
        "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon,
        ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....",
        "_-X", "/%3G?bad-pecent-encode",    "",     "",
        "_-X", "/%3?bad-percent-encode",    "",     "",
        "_-X", "/%#bad-percent-encode",    "",     "",
        "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri",
        NULL, NULL, NULL, NULL
    };
    const char **u;
    struct ccn_charbuf *uri_out = ccn_charbuf_create();
    buffer = ccn_charbuf_create();
    for (u = uri_tests; *u != NULL; u += 4, i++) {
        printf("Unit test case %d\n", i);
        if (u[0][0] != '.')
            buffer->length = 0;
        res = ccn_name_from_uri(buffer, u[1]);
        if (!expected_res(res, u[0][1])) {
            printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res);
            result = 1;
        }
        if (res >= 0) {
            if (res > strlen(u[1])) {
                printf("Failed: ccn_name_from_uri long res %d\n", (int)res);
                result = 1;
            }
            else if (0 != strcmp(u[1] + res, u[2])) {
                printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res);
                result = 1;
            }
            uri_out->length = 0;
            res = ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
            if (!expected_res(res, u[0][2])) {
                printf("Failed: ccn_uri_append wrong res %d\n", (int)res);
                result = 1;
            }
            if (res >= 0) {
                if (uri_out->length != strlen(u[3])) {
                    printf("Failed: ccn_uri_append produced wrong number of characters\n");
                    result = 1;
                }
                ccn_charbuf_reserve(uri_out, 1)[0] = 0;
                if (0 != strcmp((const char *)uri_out->buf, u[3])) {
                    printf("Failed: ccn_uri_append produced wrong output\n");
                    printf("Expected: %s\n", u[3]);
                    printf("  Actual: %s\n", (const char *)uri_out->buf);
                    result = 1;
                }
            }
        }
    }
    ccn_charbuf_destroy(&buffer);
    ccn_charbuf_destroy(&uri_out);
    printf("Name marker tests\n");
    do {
        const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81";
        const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE";
        const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF";
        const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00";

        printf("Unit test case %d\n", i++);
        buffer = ccn_charbuf_create();
        uri_out = ccn_charbuf_create();
        res = ccn_name_init(buffer);
        res |= ccn_name_append_str(buffer, "example.com");
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1);
        res |= ccn_name_append_numeric(buffer, 0xFE, 0);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129);
        res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (res < 0) {
            printf("Failed: name marker tests had negative res\n");
            result = 1;
        }
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) {
            printf("Failed: name marker tests produced wrong output\n");
            printf("Expected: %s\n", expected_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        res = ccn_name_chop(buffer, NULL, 100);
        if (res != -1) {
            printf("Failed: ccn_name_chop did not produce error \n");
            result = 1;
        }
        res = ccn_name_chop(buffer, NULL, 4);
        if (res != 4) {
            printf("Failed: ccn_name_chop got wrong length\n");
            result = 1;
        }
        uri_out->length = 0;
        ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) {
            printf("Failed: ccn_name_chop botch\n");
            printf("Expected: %s\n", expected_chopped_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        res = ccn_name_next_sibling(buffer);
        if (res != 4) {
            printf("Failed: ccn_name_next_sibling got wrong length\n");
            result = 1;
        }
        uri_out->length = 0;
        ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) {
            printf("Failed: ccn_name_next_sibling botch\n");
            printf("Expected: %s\n", expected_bumped_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        ccn_name_next_sibling(buffer);
        uri_out->length = 0;
        ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) {
            printf("Failed: ccn_name_next_sibling botch\n");
            printf("Expected: %s\n", expected_bumped2_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        ccn_charbuf_destroy(&buffer);
        ccn_charbuf_destroy(&uri_out);
    } while (0);
    printf("Message digest tests\n");
    do {
        printf("Unit test case %d\n", i++);
        struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256);
        if (dg == NULL) {
            printf("Failed: ccn_digest_create returned NULL\n");
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        const unsigned char expected_digest[] = {
            0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0
        };
        unsigned char actual_digest[sizeof(expected_digest)] = {0};
        const char *data = "Content-centric";
        if (ccn_digest_size(dg) != sizeof(expected_digest)) {
            printf("Failed: wrong digest size\n");
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        ccn_digest_init(dg);
        res = ccn_digest_update(dg, data, strlen(data));
        if (res != 0)
            printf("Warning: check res %d\n", (int)res);
        printf("Unit test case %d\n", i++);
        res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest));
        if (res != 0)
            printf("Warning: check res %d\n", (int)res);
        if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) {
            printf("Failed: wrong digest\n");
            result = 1;
            break;
        }
    } while (0);
    printf("Really basic PRNG test\n");
    do {
        unsigned char r1[42];
        unsigned char r2[42];
        printf("Unit test case %d\n", i++);
        ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */
        ccn_random_bytes(r1, sizeof(r1));
        memcpy(r2, r1, sizeof(r2));
        ccn_random_bytes(r2, sizeof(r2));
        if (0 == memcmp(r1, r2, sizeof(r2))) {
            printf("Failed: badly broken PRNG\n");
            result = 1;
            break;
        }
    } while (0);
    printf("Bloom filter tests\n");
    do {
        unsigned char seed1[4] = "1492";
        const char *a[13] = {
            "one", "two", "three", "four",
            "five", "six", "seven", "eight",
            "nine", "ten", "eleven", "twelve",
            "thirteen"
        };
        struct ccn_bloom *b1 = NULL;
        struct ccn_bloom *b2 = NULL;
        int j, k, t1, t2;
        unsigned short us;
        
        printf("Unit test case %d\n", i++);
        b1 = ccn_bloom_create(13, seed1);
        
        for (j = 0; j < 13; j++)
            if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break;
        if (j < 13) {
            printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]);
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        for (j = 0; j < 13; j++)
            ccn_bloom_insert(b1, a[j], strlen(a[j]));
        for (j = 0; j < 13; j++)
            if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break;
        if (j < 13) {
            printf("Failed: \"%s\" not found when it should have been\n", a[j]);
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        for (j = 0, k = 0; j < 13; j++)
            if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1)))
                k++;
        if (k > 0) {
            printf("Mmm, found %d false positives\n", k);
            if (k > 2) {
                result = 1;
                break;
            }
        }
        unsigned char seed2[5] = "aqfb\0";
        for (; seed2[3] <= 'f'; seed2[3]++) {
            printf("Unit test case %d (%4s)    ", i++, seed2);
            b2 = ccn_bloom_create(13, seed2);
            for (j = 0; j < 13; j++)
                ccn_bloom_insert(b2, a[j], strlen(a[j]));
            for (j = 0, k = 0, us = ~0; us > 0; us--) {
                t1 = ccn_bloom_match(b1, &us, sizeof(us));
                t2 = ccn_bloom_match(b2, &us, sizeof(us));
                j += (t1 | t2);
                k += (t1 & t2);
            }
            printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1));
            if (k > 12) {
                printf("Failed: Bloom seeding may not be effective\n");
                result = 1;
            }
            ccn_bloom_destroy(&b2);
        }
        ccn_bloom_destroy(&b1);
    } while (0);
    printf("ccn_sign_content() tests\n");
    do {
        struct ccn *h = ccn_create();
        struct ccn_charbuf *co = ccn_charbuf_create();
        struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT;
        struct ccn_parsed_ContentObject pco = {0};
        struct ccn_charbuf *name = ccn_charbuf_create();
        
        printf("Unit test case %d\n", i++);
        ccn_name_from_uri(name, "ccnx:/test/data/%00%42");
        res = ccn_sign_content(h, co, name, NULL, "DATA", 4);
        if (res != 0) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
        sparm.template_ccnb = ccn_charbuf_create();
        res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL);
        if (res != 0) {
            printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res);
            result = 1;
            break;
        }
        ccn_charbuf_append(sparm.template_ccnb,
            co->buf + pco.offset[CCN_PCO_B_SignedInfo],
            pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]);
        sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP;
        printf("Unit test case %d\n", i++);
        res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
        if (res != 0) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
        printf("Unit test case %d\n", i++);
        sparm.sp_flags = -1;
        res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
        if (res != -1) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
        ccn_charbuf_destroy(&name);
        ccn_charbuf_destroy(&sparm.template_ccnb);
        ccn_charbuf_destroy(&co);
        ccn_destroy(&h);
    } while (0);
    printf("link tests\n");
    do {
        struct ccn_charbuf *l = ccn_charbuf_create();
        struct ccn_charbuf *name = ccn_charbuf_create();
        struct ccn_parsed_Link pl = {0};
        struct ccn_buf_decoder decoder;
        struct ccn_buf_decoder *d;
        struct ccn_indexbuf *comps = ccn_indexbuf_create();
        printf("Unit test case %d\n", i++);
        ccn_name_from_uri(name, "ccnx:/test/link/name");
        ccnb_append_Link(l, name, "label", NULL);
        d = ccn_buf_decoder_start(&decoder, l->buf, l->length);
        res = ccn_parse_Link(d, &pl, comps);
        if (res != 3 /* components in name */) {
            printf("Failed: ccn_parse_Link res == %d\n", (int)res);
            result = 1;
        }        
    } while (0);
    
    exit(result);
}
예제 #27
0
int main() {
	int i,j;
	
	// Test range parser:
	long long start, end;
	int r;
	for (i = 0; i < 10; i++) {
		r = parse_range_req(test1[i], &start, &end);
		printf("%d %lld %lld\n", r, start, end);
	}

	// Test path creation
	for (i = 0; i < 10; i++) {
		char temp[4096];
		path_create(test2_1[i], test2_2[i], temp);
		printf("%s\n", temp);
	}
	
	// Test urldecode
	for (i = 0; i < 10; i++) {
		char temp[4096];
		urldecode (temp, test3[i]);
		printf("%s\n", temp);
	}
	
	// Fuzz test!
	for (i = 0; i < 1000000; i++) {
		char temp[4096], temp2[4096], temp4[4096*2];;
		for (j = 0; j < 4096; j++) {
			temp[j]  = rand();
			temp2[j] = rand();
		}
		temp[4095]  = 0;
		temp2[4095] = 0;
		parse_range_req(temp, &start, &end);
		path_create(temp, temp2, temp4);
		urldecode(temp4, temp);
		
		if (i%100000 == 0)
			printf("Progress: %d %%\n", i / 10000);
	}

	// ASCII targeted fuzz test!
	const char dict[] = "1234567890-/ACBDEFGabcdefg%!\"·$/()=.";
	int tt = strlen(dict);
	for (i = 0; i < 1000000; i++) {
		char temp[4096], temp2[4096], temp4[4096*2];;
		for (j = 0; j < 4096; j++) {
			temp[j]  = dict[rand() % tt];
			temp2[j] = dict[rand() % tt];
		}
		temp[4095]  = 0;
		temp2[4095] = 0;
		parse_range_req(temp, &start, &end);
		path_create(temp, temp2, temp4);
		urldecode(temp4, temp);
		
		if (i%100000 == 0)
			printf("Progress: %d %%\n", i / 10000);
	}

}
예제 #28
0
/*
 * extract the given (expanded) URL "url" to the given directory "dir"
 * return -1 on error, 0 else;
 */
int
unpackURL(const char *url, const char *dir)
{
    char *pkg;
    int rc;
    char base[MaxPathSize];
    char pkg_path[MaxPathSize];

    {
        /* Verify if the URL is really ok */
        char expnd[MaxPathSize];

        rc=expandURL(expnd, url);
        if (rc == -1) {
            warnx("unpackURL: verification expandURL failed");
            return -1;
        }
        if (strcmp(expnd, url) != 0) {
            warnx("unpackURL: verification expandURL failed, '%s'!='%s'",
                  expnd, url);
            return -1;
        }
    }

    pkg=strrchr(url, '/');
    if (pkg == NULL) {
        warnx("unpackURL: no '/' in URL %s?!", url);
        return -1;
    }
    (void) snprintf(base, sizeof(base), "%.*s/", (int)(pkg-url), url);
    (void) snprintf(pkg_path, sizeof(pkg_path), "%.*s",
                    (int)(pkg-url), url); /* no trailing '/' */
    pkg++;

    /* Leave a hint for any depending pkgs that may need it */
    if (getenv("PKG_PATH") == NULL) {
        setenv("PKG_PATH", pkg_path, 1);
#if 0
        path_create(pkg_path); /* XXX */
#endif
        if (Verbose)
            printf("setenv PKG_PATH='%s'\n", pkg_path);
    }

    if (strncmp(url, "http://", 7) == 0)
        return http_fetch(url, dir);

    rc = ftp_start(base);
    if (rc == -1) {
        warnx("ftp_start() failed");
        return -1; /* error */
    }

    {
        char cmd[1024];
        const char *decompress_cmd = NULL;
        const char *suf;

        if (Verbose)
            printf("unpackURL '%s' to '%s'\n", url, dir);

        suf = suffix_of(pkg);
        if (!strcmp(suf, "tbz") || !strcmp(suf, "bz2"))
            decompress_cmd = BZIP2_CMD;
        else if (!strcmp(suf, "tgz") || !strcmp(suf, "gz"))
            decompress_cmd = GZIP_CMD;
        else if (!strcmp(suf, "tar"))
            ; /* do nothing */
        else
            errx(EXIT_FAILURE, "don't know how to decompress %s, sorry", pkg);

        /* yes, this is gross, but needed for borken ftp(1) */
        (void) snprintf(cmd, sizeof(cmd), "get %s \"| ( cd %s; " TAR_CMD " %s %s -vvxp -f - | tee %s )\"\n",
                        pkg, dir,
                        decompress_cmd != NULL ? "--use-compress-program" : "",
                        decompress_cmd != NULL ? decompress_cmd : "",
                        Verbose ? "/dev/stderr" : "/dev/null");

        rc = ftp_cmd(cmd, "\n(226|550).*\n");
        if (rc != 226) {
            warnx("Cannot fetch file (%d!=226)!", rc);
            return -1;
        }
    }

    return 0;
}
예제 #29
0
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_value = NULL;
    const XML_Char *attr_ignore = NULL;
	char *sub_attr_value;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int j;
    unsigned int k;
    struct mixer_ctl *ctl;
    int values[MAX_CTL_VALS];
	unsigned int num_values;
	unsigned int num_ctl_vals;
    struct mixer_setting mixer_setting;
	unsigned ignored = 0;

    /* Get name, type and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
        else if (strcmp(attr[i], "ignore") == 0)
            attr_ignore = attr[i + 1];
    }

	if (attr_ignore && strcmp(attr_ignore, "1") == 0) {
		ignored = 1;
	}

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(state->path, sub_path);
            }
        }
    }

	else if (strcmp(tag_name, "ctl") == 0 && state->level == 1 && ignored) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);

		/* locate the mixer ctl in the list */
		for (i = 0; i < ar->num_mixer_ctls; i++) {
			if (ar->mixer_state[i].ctl == ctl)
				break;
		}
        ar->mixer_state[i].ignored = 1;
	}

    else if (strcmp(tag_name, "ctl") == 0) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
			/* TODO */
			num_values = 1;
			char *sub_attr_value;
			for (j = 0; j < strlen((char*)attr_value); j++) {
				if (attr_value[j] == ',') num_values++;
			}
			sub_attr_value = (char*)attr_value;
			k = strlen((char*)attr_value);
			for (j = 0; j < k; j++) {
				if (sub_attr_value[j] == ',') sub_attr_value[j] = '\0';
			}
			sub_attr_value = (char*)attr_value;
			for (j = 0; j < num_values; j++) {
            	values[j] = atoi(sub_attr_value);
#if 1
				ALOGV("attr='%s' idx=%u str='%s' val=%d", attr_name, j,
						sub_attr_value, values[j]);
#endif
				sub_attr_value += (strlen(sub_attr_value) + 1);
			}
            break;
        case MIXER_CTL_TYPE_ENUM:
			num_values = 1;
            values[0] = mixer_enum_string_to_value(ctl, (char *)attr_value);
			ALOGV("attr='%s' attr_val='%s' val=%d", attr_name, attr_value, values[0]);
            break;
        default:
			num_values = 1;
            values[0] = 0;
			ALOGV("attr='%s' UNKNOWN CTL TYPE", attr_name);
            break;
        }

        if (state->level == 1) {
            /* top level ctl (initial setting) */

            /* locate the mixer ctl in the list */
            for (i = 0; i < ar->num_mixer_ctls; i++) {
                if (ar->mixer_state[i].ctl == ctl)
                    break;
            }

            /* apply the new value */
            ar->mixer_state[i].ignored = 0;
            ar->mixer_state[i].ctl_vals = num_values;
			for (j = 0; j < num_values; j++) {
            	ar->mixer_state[i].new_value[j] = values[j];
			}
        } else {
            /* nested ctl (within a path) */
            mixer_setting.ctl = ctl;
            mixer_setting.ctl_vals = num_values;
			for (j = 0; j < num_values; j++) {
            	mixer_setting.value[j] = values[j];
			}
            path_add_setting(state->path, &mixer_setting);
        }
    }

    state->level++;
}
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_id = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int ctl_index;
    struct mixer_ctl *ctl;
    int value;
    unsigned int id;
    struct mixer_value mixer_value;

    /* Get name, id and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        if (strcmp(attr[i], "id") == 0)
            attr_id = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(ar, state->path, sub_path);
            }
        }
    }

    else if (strcmp(tag_name, "ctl") == 0) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
        if (ctl == NULL) {
            ALOGE("Control '%s' doesn't exist - skipping", attr_name);
            goto done;
        }

        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
            value = atoi((char *)attr_value);
            break;
        case MIXER_CTL_TYPE_ENUM:
            value = mixer_enum_string_to_value(ctl, (char *)attr_value);
            break;
        default:
            value = 0;
            break;
        }

        /* locate the mixer ctl in the list */
        for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) {
            if (ar->mixer_state[ctl_index].ctl == ctl)
                break;
        }

        if (state->level == 1) {
            /* top level ctl (initial setting) */

            /* apply the new value */
            if (attr_id) {
                /* set only one value */
                id = atoi((char *)attr_id);
                if (id < ar->mixer_state[ctl_index].num_values)
                    ar->mixer_state[ctl_index].new_value[id] = value;
                else
                    ALOGE("value id out of range for mixer ctl '%s'",
                          mixer_ctl_get_name(ctl));
            } else {
                /* set all values the same */
                for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++)
                    ar->mixer_state[ctl_index].new_value[i] = value;
            }
        } else {
            /* nested ctl (within a path) */
            mixer_value.ctl_index = ctl_index;
            mixer_value.value = value;
            if (attr_id)
                mixer_value.index = atoi((char *)attr_id);
            else
                mixer_value.index = -1;
            path_add_value(ar, state->path, &mixer_value);
        }
    }

done:
    state->level++;
}