Esempio n. 1
0
bool Basic_block::is_delayed_slot(Instruction *i){
   if (get_branch()== NULL)
      return false;
   int j = (getInst(get_branch()))->get_index();
   return (j < i-> get_index());

}
Esempio n. 2
0
static gboolean
builder_source_git_download (BuilderSource  *source,
                             gboolean        update_vcs,
                             BuilderContext *context,
                             GError        **error)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);
  g_autofree char *location = NULL;

  location = get_url_or_path (self, context, error);
  if (location == NULL)
    return FALSE;

  if (!builder_git_mirror_repo (location,
                                NULL,
                                update_vcs, TRUE, self->disable_fsckobjects,
                                get_branch (self),
                                context,
                                error))
    return FALSE;

  if (self->commit != NULL && self->branch != NULL)
    {
      g_autofree char *current_commit = builder_git_get_current_commit (location,get_branch (self), context, error);
      if (current_commit == NULL)
        return FALSE;
      if (strcmp (current_commit, self->commit) != 0)
        return flatpak_fail (error, "Git commit for branch %s is %s, but expected %s\n", self->branch, current_commit, self->commit);
    }

  return TRUE;
}
Esempio n. 3
0
static gboolean
builder_source_git_bundle (BuilderSource  *source,
                           BuilderContext *context,
                           GError        **error)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);

  g_autofree char *location = NULL;
  g_autoptr(GFile) mirror_dir = NULL;

  location = get_url_or_path (self, context, error);

  g_print ("builder_source_git_bundle %s\n", location);

  if (location == NULL)
    return FALSE;

  mirror_dir = flatpak_build_file (builder_context_get_app_dir (context),
                                   "sources/git",
                                   NULL);
  if (!flatpak_mkdir_p (mirror_dir, NULL, error))
    return FALSE;

  if (!builder_git_mirror_repo (location,
                                flatpak_file_get_path_cached (mirror_dir),
                                FALSE, TRUE, FALSE,
                                get_branch (self),
                                context,
                                error))
    return FALSE;

  return TRUE;
}
Esempio n. 4
0
void print(struct tree *str) {
	int i = 0;
	int len;

	if (str == NULL)
		return;

	len = str->width;
	switch(str->type) {
		case CHAR:
			putchar(str->data.c);
			break;
		case INT:
			printf("%d", str->data.i);
			break;
		case DOUBLE:
			printf("%f", str->data.d);
			break;
		case TREE:
			print(str->data.t);
			break;
		default:
			break;
	}

	while (i < len) {	
		print(get_branch(str, i++));
	}

}
Esempio n. 5
0
struct node *find_link (int index, struct node *parent, 
						struct node *child, int firsti, int lasti)
// Find and establish the suffix link for the given child node, 
// working downward from its parent's suffix link.
{
	int e, betalen, r, depth;
	struct node *vp, *branch, *leaf;

	// Capture beta for later consumption
	betalen = lasti - firsti;

	// traverse parent's suffix link.
	vp = parent -> sfxlink;
	branch = get_branch (firsti, vp);  

	if (branch && betalen) {	// Beta not empty
		// Consume Beta and Establish child -> sfxlink
		leaf = consume_beta (index, firsti, betalen, branch, child);
	} else {	
		// Beta was empty or no branch exists for the letter at input[index]
		child -> sfxlink = vp;
		leaf = find_path (index, index, vp);
	}
	return leaf;
}
Esempio n. 6
0
/*
 * Check if host in Request URI is local
 */
int is_uri_host_local(struct sip_msg* _msg, char* _s1, char* _s2)
{
    str branch;
    qvalue_t q;
    struct sip_uri puri;
    struct attr_list *attrs;
    str did;

    if ( is_route_type(REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE) ) {
	if (parse_sip_msg_uri(_msg) < 0) {
	    LM_ERR("error while parsing R-URI\n");
	    return -1;
	}
	return hash_table_lookup(&(_msg->parsed_uri.host), &did, &attrs);
    } else if (is_route_type(FAILURE_ROUTE)) {
	branch.s = get_branch(0, &branch.len, &q, 0, 0, 0, 0, 0, 0, 0);
	if (branch.s) {
	    if (parse_uri(branch.s, branch.len, &puri) < 0) {
		LM_ERR("error while parsing branch URI\n");
		return -1;
	    }
	    return hash_table_lookup(&(puri.host), &did, &attrs);
	} else {
	    LM_ERR("branch is missing, error in script\n");
	    return -1;
	}
    } else {
	LM_ERR("unsupported route type\n");
	return -1;
    }
}
Esempio n. 7
0
static gboolean
builder_source_git_update (BuilderSource  *source,
                           BuilderContext *context,
                           GError        **error)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);

  g_autoptr(GFile) mirror_dir = NULL;
  char *current_commit;
  g_autofree char *location = NULL;

  location = get_url_or_path (self, context, error);
  if (location == NULL)
    return FALSE;

  mirror_dir = git_get_mirror_dir (location, context);

  current_commit = git_get_current_commit (mirror_dir, get_branch (self), context, NULL);
  if (current_commit)
    {
      g_free (self->branch);
      self->branch = current_commit;
    }

  return TRUE;
}
Esempio n. 8
0
/*
 * Check if host in Request URI is local
 */
int is_uri_host_local(struct sip_msg* _msg, char* _s1, char* _s2)
{
	str branch;
	qvalue_t q;
	struct sip_uri puri;

	if ((route_type == REQUEST_ROUTE) || (route_type == BRANCH_ROUTE)) {
		if (parse_sip_msg_uri(_msg) < 0) {
			LM_ERR("Error while parsing R-URI\n");
			return -1;
		}
		return is_domain_local(&(_msg->parsed_uri.host));
	} else if (route_type == FAILURE_ROUTE) {
			branch.s = get_branch(0, &branch.len, &q, 0, 0, 0, 0);
			if (branch.s) {
				if (parse_uri(branch.s, branch.len, &puri) < 0) {
					LM_ERR("Error while parsing branch URI\n");
					return -1;
				}
				return is_domain_local(&(puri.host));
			} else {
				LM_ERR("Branch is missing, error in script\n");
				return -1;
			}
	} else {
		LM_ERR("Unsupported route type\n");
		return -1;
	}
}
Esempio n. 9
0
struct tree *get_branch_t(struct tree *root, struct tree *branch) {
	struct tree *child;
	inc_refcount(branch);
	child = (struct tree *)get_branch(root, branch->data.i);
	dec_refcount(branch);
	return child;
}
Esempio n. 10
0
int main(int argc, char *argv[]){
  if(argc != 2){
    fprintf(stderr, "Wrong number of arguments! Usage: %s [get-branch|get-pending|get-dir]\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  if(strcmp(argv[1], "get-branch") == 0){
    get_branch();
  }
  else if(strcmp(argv[1], "get-pending") == 0){
    int pending = get_pending();
    if(pending > 0){
      printf("%%B(%d)%%b\n", pending);
    }
  }
  else if(strcmp(argv[1], "get-dir") == 0){
    int files;
    int dirs;
    if(get_dirlisting(&files, &dirs)){
      printf("%d/%d\n", files, dirs);
    }
  }
  else {
    fprintf(stderr, "Unknown argument: '%s'. Usage: %s [get-branch|get-pending|get-dir]\n", argv[1], argv[0]);
    exit(EXIT_FAILURE);
  }
  return 0;
}
Esempio n. 11
0
static void
builder_source_git_checksum (BuilderSource  *source,
                             BuilderCache   *cache,
                             BuilderContext *context)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);

  g_autoptr(GFile) mirror_dir = NULL;
  g_autofree char *current_commit = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree char *location = NULL;

  builder_cache_checksum_str (cache, self->url);
  builder_cache_checksum_str (cache, self->path);
  builder_cache_checksum_str (cache, self->branch);

  location = get_url_or_path (self, context, &error);
  if (location != NULL)
    {
      mirror_dir = git_get_mirror_dir (location, context);

      current_commit = git_get_current_commit (mirror_dir, get_branch (self), context, &error);
      if (current_commit)
        builder_cache_checksum_str (cache, current_commit);
      else if (error)
        g_warning ("Failed to get current git checksum: %s", error->message);
    }
  else
    {
      g_warning ("No url or path");
    }
}
Esempio n. 12
0
struct node *consume_beta (int index, int firsti, int betalen, 
							struct node *startnode, struct node *u)
// Consume Beta (slice of input string);
// Establish suffix link of u to point to the spot at which Beta was consumed;
// Find leaf insertion location and return a pointer to it.
{
	int e, r, depth;
	struct node *branch, *leaf;

	r = 0;
	branch = startnode;

	while (r < betalen) {
		e = (branch -> endi) - (branch -> starti);
		if (r + e > betalen) {	// Beta is consumed mid-edge.
			// Break edge.  Assign the suffix link to the breakpoint and append leaf.
			u -> sfxlink = break_edge (branch -> starti + (betalen - r), branch); 
			allocate_node (&leaf, index, index + u -> sfxlink -> strdepth, slen, u -> sfxlink);
			push_branch (&(u -> sfxlink), leaf);
			break;
		} else if (r + e == betalen) {	// Beta is consumed at an existing node
			// Establish link and place the leaf by matching characters.
			u -> sfxlink = branch;
			depth = index - 1 + u -> strdepth;
			leaf = find_path (index, depth, branch);
			break;
		} else { 		// Hop to next node by adding its edge length to r.
			r += e;		
			branch = get_branch (firsti + r, branch);
		}
	}
	return leaf;
}
static inline int get_block(struct inode * inode, sector_t block,
			struct buffer_head *bh, int create)
{
	int err = -EIO;
	int offsets[DEPTH];
	Indirect chain[DEPTH];
	Indirect *partial;
	int left;
	int depth = block_to_path(inode, block, offsets);

	if (depth == 0)
		goto out;

reread:
	partial = get_branch(inode, depth, offsets, chain, &err);

	
	if (!partial) {
got_it:
		map_bh(bh, inode->i_sb, block_to_cpu(chain[depth-1].key));
		
		partial = chain+depth-1; 
		goto cleanup;
	}

	
	if (!create || err == -EIO) {
cleanup:
		while (partial > chain) {
			brelse(partial->bh);
			partial--;
		}
out:
		return err;
	}

	if (err == -EAGAIN)
		goto changed;

	left = (chain + depth) - partial;
	err = alloc_branch(inode, left, offsets+(partial-chain), partial);
	if (err)
		goto cleanup;

	if (splice_branch(inode, chain, partial, left) < 0)
		goto changed;

	set_buffer_new(bh);
	goto got_it;

changed:
	while (partial > chain) {
		brelse(partial->bh);
		partial--;
	}
	goto reread;
}
Esempio n. 14
0
struct node *find_path (int index, int sufdepth, struct node *v)
// Find path to the insertion point for the suffix beginning at input_string[index].
// Allocate and insert the node.
{
	int i, j, e;
	struct node *branch, *parent, *newint, *leaf, *tmp;
	
	// find child starting with input_string[sufdepth]
	i = sufdepth;
	parent = v;
	branch = get_branch (i, v);
	if (branch) {
		j = branch -> starti;
		e = branch -> endi - branch -> starti;
		// Look for the first mismatch in the current suffix and the path below v
		while (input_string[i] == input_string[j]) {
			if (!(--e)) {
				parent = branch;
				if ((branch = get_branch (++i, branch)) == NULL) break;
				j = branch -> starti;
				e = branch -> endi - branch -> starti;
			} else {
				++i; ++j;
			}
		}
	}
	
	// Allocate and insert a leaf at the branch point.
	if (branch) {	// Fork branch by making new internal node
		if (branch -> endi - branch -> starti > 1) {
			newint = break_edge (j, branch);
			allocate_node (&leaf, index, i, slen, newint);
			push_branch (&newint, leaf);
		} else {
			allocate_node (&leaf, index, i, slen, branch);
			push_branch (&branch, leaf);
		}
	} else {
		allocate_node (&leaf, index, i, slen, parent);
		push_branch (&parent, leaf);
	}
	return leaf;
}
Esempio n. 15
0
/** Return the next branch from the dset array.
 * 0 is returned if there are no more branches
 */
char* next_branch(int* len, qvalue_t* q, str* dst_uri, str* path,
					unsigned int* flags, struct socket_info** force_socket)
{
	char* ret;
	
	ret=get_branch(branch_iterator, len, q, dst_uri, path, flags,
					force_socket);
	if (likely(ret))
		branch_iterator++;
	return ret;
}
Esempio n. 16
0
File: block.c Progetto: rvba/minuit
t_lst *block_branch_get( t_block *block, int dir)
{
	t_lst *branch = lst_new( "branch");
	t_lst *bricks = block->bricks;
	t_link *l;
	t_block *target;
	t_brick *brick;

	for( l = bricks->first; l; l = l->next)
	{
		brick = l->data;
		target = get_block_connected( brick, dir);
		if( target) get_branch( target, branch, dir);
	}

	return branch;
}
Esempio n. 17
0
File: block.c Progetto: rvba/minuit
void get_branch( t_block *block, t_lst *lst, int dir)
{
	if( !block_in_list( block, lst))
	{
		lst_add( lst, block, block->id.name);

		t_lst *bricks = block->bricks;
		t_brick *brick;
		t_block *target;
		t_link *l;

		for( l = bricks->first; l; l = l->next)
		{
			brick = l->data;
			target = get_block_connected( brick, dir);
			if( target) get_branch( target, lst, dir);
		}
	}
}
Esempio n. 18
0
static gboolean
builder_source_git_extract (BuilderSource  *source,
                            GFile          *dest,
                            BuilderOptions *build_options,
                            BuilderContext *context,
                            GError        **error)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);
  g_autofree char *location = NULL;

  location = get_url_or_path (self, context, error);
  if (location == NULL)
    return FALSE;

  if (!builder_git_checkout (location, get_branch (self),
                             dest, context, error))
    return FALSE;

  return TRUE;
}
Esempio n. 19
0
static gboolean
builder_source_git_extract (BuilderSource  *source,
                            GFile          *dest,
                            BuilderContext *context,
                            GError        **error)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);

  g_autoptr(GFile) mirror_dir = NULL;
  g_autofree char *mirror_dir_path = NULL;
  g_autofree char *dest_path = NULL;
  g_autofree char *location = NULL;

  location = get_url_or_path (self, context, error);
  if (location == NULL)
    return FALSE;

  mirror_dir = git_get_mirror_dir (location, context);

  mirror_dir_path = g_file_get_path (mirror_dir);
  dest_path = g_file_get_path (dest);

  if (!git (NULL, NULL, error,
            "clone", mirror_dir_path, dest_path, NULL))
    return FALSE;

  if (!git (dest, NULL, error,
            "checkout", get_branch (self), NULL))
    return FALSE;

  if (!git_extract_submodule (location, dest, context, error))
    return FALSE;

  if (!git (dest, NULL, error,
            "config", "--local", "remote.origin.url",
            location, NULL))
    return FALSE;

  return TRUE;
}
Esempio n. 20
0
static Indirect *find_shared(struct inode *inode,
				int depth,
				int offsets[DEPTH],
				Indirect chain[DEPTH],
				block_t *top)
{
	Indirect *partial, *p;
	int k, err;

	*top = 0;
	for (k = depth; k > 1 && !offsets[k-1]; k--)
		;
	partial = get_branch(inode, k, offsets, chain, &err);

	write_lock(&pointers_lock);
	if (!partial)
		partial = chain + k-1;
	if (!partial->key && *partial->p) {
		write_unlock(&pointers_lock);
		goto no_top;
	}
	for (p=partial;p>chain && all_zeroes((block_t*)p->bh->b_data,p->p);p--)
		;
	if (p == chain + k - 1 && p > chain) {
		p->p--;
	} else {
		*top = *p->p;
		*p->p = 0;
	}
	write_unlock(&pointers_lock);

	while(partial > p)
	{
		brelse(partial->bh);
		partial--;
	}
no_top:
	return partial;
}
Esempio n. 21
0
static gboolean
builder_source_git_download (BuilderSource *source,
                             gboolean update_vcs,
                             BuilderContext *context,
                             GError **error)
{
  BuilderSourceGit *self = BUILDER_SOURCE_GIT (source);
  g_autofree char *url = NULL;

  url = get_url (self, context, error);
  if (url == NULL)
    return FALSE;

  if (!git_mirror_repo (url,
                        update_vcs,
                        get_branch (self),
                        context,
                        error))
    return FALSE;

  return TRUE;
}
Esempio n. 22
0
/*! \brief
 * Lookup contact in the database and rewrite Request-URI
 * \return: -1 : not found
 *          -2 : found but method not allowed
 *          -3 : error
 */
int lookup(struct sip_msg* _m, char* _t, char* _f, char* _s)
{
	unsigned int flags;
	urecord_t* r;
	str aor, uri;
	ucontact_t* ptr,*it;
	int res;
	int ret;
	str path_dst;
	str flags_s;
	char* ua = NULL;
	char* re_end = NULL;
	int re_len = 0;
	char tmp;
	regex_t ua_re;
	int regexp_flags = 0;
	regmatch_t ua_match;
	pv_value_t val;
	int_str istr;
	str sip_instance = {0,0},call_id = {0,0};

	/* branch index */
	int idx;

	/* temporary branch values*/
	int tlen;
	char *turi;

	qvalue_t tq;

	flags = 0;
	if (_f && _f[0]!=0) {
		if (fixup_get_svalue( _m, (gparam_p)_f, &flags_s)!=0) {
			LM_ERR("invalid owner uri parameter");
			return -1;
		}
		for( res=0 ; res< flags_s.len ; res++ ) {
			switch (flags_s.s[res]) {
				case 'm': flags |= REG_LOOKUP_METHODFILTER_FLAG; break;
				case 'b': flags |= REG_LOOKUP_NOBRANCH_FLAG; break;
				case 'r': flags |= REG_BRANCH_AOR_LOOKUP_FLAG; break;
				case 'u':
					if (flags_s.s[res+1] != '/') {
						LM_ERR("no regexp after 'u' flag");
						break;
					}
					res++;
					if ((re_end = strrchr(flags_s.s+res+1, '/')) == NULL) {
						LM_ERR("no regexp after 'u' flag");
						break;
					}
					res++;
					re_len = re_end-flags_s.s-res;
					if (re_len == 0) {
						LM_ERR("empty regexp");
						break;
					}
					ua = flags_s.s+res;
					flags |= REG_LOOKUP_UAFILTER_FLAG;
					LM_DBG("found regexp /%.*s/", re_len, ua);
					res += re_len;
					break;
				case 'i': regexp_flags |= REG_ICASE; break;
				case 'e': regexp_flags |= REG_EXTENDED; break;
				default: LM_WARN("unsuported flag %c \n",flags_s.s[res]);
			}
		}
	}
	if (flags&REG_BRANCH_AOR_LOOKUP_FLAG) {
		/* extract all the branches for further usage */
		nbranches = 0;
		while (
			(turi=get_branch(nbranches, &tlen, &tq, NULL, NULL, NULL, NULL))
				) {
			/* copy uri */
			branch_uris[nbranches].s = urimem[nbranches];
			if (tlen) {
				memcpy(branch_uris[nbranches].s, turi, tlen);
				branch_uris[nbranches].len = tlen;
			} else {
				*branch_uris[nbranches].s  = '\0';
				branch_uris[nbranches].len = 0;
			}

			nbranches++;
		}
		clear_branches();
		idx=0;
	}


	if (_s) {
		if (pv_get_spec_value( _m, (pv_spec_p)_s, &val)!=0) {
			LM_ERR("failed to get PV value\n");
			return -1;
		}
		if ( (val.flags&PV_VAL_STR)==0 ) {
			LM_ERR("PV vals is not string\n");
			return -1;
		}
		uri = val.rs;
	} else {
		if (_m->new_uri.s) uri = _m->new_uri;
		else uri = _m->first_line.u.request.uri;
	}

	if (extract_aor(&uri, &aor,&sip_instance,&call_id) < 0) {
		LM_ERR("failed to extract address of record\n");
		return -3;
	}

	get_act_time();

	ul.lock_udomain((udomain_t*)_t, &aor);
	res = ul.get_urecord((udomain_t*)_t, &aor, &r);
	if (res > 0) {
		LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
		ul.unlock_udomain((udomain_t*)_t, &aor);
		return -1;
	}

	if (flags & REG_LOOKUP_UAFILTER_FLAG) {
		tmp = *(ua+re_len);
		*(ua+re_len) = '\0';
		if (regcomp(&ua_re, ua, regexp_flags) != 0) {
			LM_ERR("bad regexp '%s'\n", ua);
			*(ua+re_len) = tmp;
			return -1;
		}
		*(ua+re_len) = tmp;
	}


	ptr = r->contacts;
	ret = -1;
	/* look first for an un-expired and suported contact */
search_valid_contact:
	while ( (ptr) &&
	!(VALID_CONTACT(ptr,act_time) && (ret=-2) && allowed_method(_m,ptr,flags)))
		ptr = ptr->next;
	if (ptr==0) {
		/* nothing found */
		LM_DBG("nothing found !\n");
		goto done;
	}

	ua_re_check(
		ret = -1;
		ptr = ptr->next;
		goto search_valid_contact
	);

	if (sip_instance.len && sip_instance.s) {
		LM_DBG("ruri has gruu in lookup\n");
		/* uri has GRUU */
		if (ptr->instance.len-2 != sip_instance.len ||
				memcmp(ptr->instance.s+1,sip_instance.s,sip_instance.len)) {
			LM_DBG("no match to sip instace - [%.*s] - [%.*s]\n",ptr->instance.len-2,ptr->instance.s+1,
					sip_instance.len,sip_instance.s);
			/* not the targeted instance, search some more */
			ptr = ptr->next;
			goto search_valid_contact;
		}

		LM_DBG("matched sip instace\n");
	}

	if (call_id.len && call_id.s) {
		/* decide whether GRUU is expired or not
		 *
		 * first - match call-id */
		if (ptr->callid.len != call_id.len ||
				memcmp(ptr->callid.s,call_id.s,call_id.len)) {
			LM_DBG("no match to call id - [%.*s] - [%.*s]\n",ptr->callid.len,ptr->callid.s,
					call_id.len,call_id.s);
			ptr = ptr->next;
			goto search_valid_contact;
		}

		/* matched call-id, check if there are newer contacts with
		 * same sip instace bup newer last_modified */

		it = ptr->next;
		while ( it ) {
			if (VALID_CONTACT(it,act_time)) {
				if (it->instance.len-2 == sip_instance.len && sip_instance.s &&
						memcmp(it->instance.s+1,sip_instance.s,sip_instance.len) == 0)
					if (it->last_modified > ptr->last_modified) {
						/* same instance id, but newer modified -> expired GRUU, no match at all */
						break;
					}
			}
			it=it->next;
		}

		if (it != NULL) {
			ret = -1;
			goto done;
		}
	}

	LM_DBG("found a complete match\n");

	ret = 1;
	if (ptr) {
		LM_DBG("setting as ruri <%.*s>\n",ptr->c.len,ptr->c.s);
		if (set_ruri(_m, &ptr->c) < 0) {
			LM_ERR("unable to rewrite Request-URI\n");
			ret = -3;
			goto done;
		}

		/* If a Path is present, use first path-uri in favour of
		 * received-uri because in that case the last hop towards the uac
		 * has to handle NAT. - agranig */
		if (ptr->path.s && ptr->path.len) {
			if (get_path_dst_uri(&ptr->path, &path_dst) < 0) {
				LM_ERR("failed to get dst_uri for Path\n");
				ret = -3;
				goto done;
			}
			if (set_path_vector(_m, &ptr->path) < 0) {
				LM_ERR("failed to set path vector\n");
				ret = -3;
				goto done;
			}
			if (set_dst_uri(_m, &path_dst) < 0) {
				LM_ERR("failed to set dst_uri of Path\n");
				ret = -3;
				goto done;
			}
		} else if (ptr->received.s && ptr->received.len) {
			if (set_dst_uri(_m, &ptr->received) < 0) {
				ret = -3;
				goto done;
			}
		}

		set_ruri_q( _m, ptr->q);

		setbflag( _m, 0, ptr->cflags);

		if (ptr->sock)
			_m->force_send_socket = ptr->sock;

		/* populate the 'attributes' avp */
		if (attr_avp_name != -1) {
			istr.s = ptr->attr;
			if (add_avp_last(AVP_VAL_STR, attr_avp_name, istr) != 0) {
				LM_ERR("Failed to populate attr avp!\n");
			}
		}

		ptr = ptr->next;
	}

	/* Append branches if enabled */
	/* If we got to this point and the URI had a ;gr parameter and it was matched
	 * to a contact. No point in branching */
	if ( flags&REG_LOOKUP_NOBRANCH_FLAG || (sip_instance.len && sip_instance.s) ) goto done;
	LM_DBG("looking for branches\n");

	do {
		for( ; ptr ; ptr = ptr->next ) {
			if (VALID_CONTACT(ptr, act_time) && allowed_method(_m,ptr,flags)) {
				path_dst.len = 0;
				if(ptr->path.s && ptr->path.len
				&& get_path_dst_uri(&ptr->path, &path_dst) < 0) {
					LM_ERR("failed to get dst_uri for Path\n");
					continue;
				}

				ua_re_check(continue);

				/* The same as for the first contact applies for branches
				 * regarding path vs. received. */
				LM_DBG("setting branch <%.*s>\n",ptr->c.len,ptr->c.s);
				if (append_branch(_m,&ptr->c,path_dst.len?&path_dst:&ptr->received,
				&ptr->path, ptr->q, ptr->cflags, ptr->sock) == -1) {
					LM_ERR("failed to append a branch\n");
					/* Also give a chance to the next branches*/
					continue;
				}

				/* populate the 'attributes' avp */
				if (attr_avp_name != -1) {
					istr.s = ptr->attr;
					if (add_avp_last(AVP_VAL_STR, attr_avp_name, istr) != 0) {
						LM_ERR("Failed to populate attr avp!\n");
					}
				}
			}
		}
		/* 0 branches condition also filled; idx initially -1*/
		if (!(flags&REG_BRANCH_AOR_LOOKUP_FLAG) || idx == nbranches)
			goto done;


		/* relsease old aor lock */
		ul.unlock_udomain((udomain_t*)_t, &aor);
		ul.release_urecord(r, 0);

		/* idx starts from -1 */
		uri = branch_uris[idx];
		if (extract_aor(&uri, &aor, NULL, &call_id) < 0) {
			LM_ERR("failed to extract address of record for branch uri\n");
			return -3;
		}

		/* release old urecord */

		/* get lock on new aor */
		LM_DBG("getting contacts from aor [%.*s]"
					"in branch %d\n", aor.len, aor.s, idx);
		ul.lock_udomain((udomain_t*)_t, &aor);
		res = ul.get_urecord((udomain_t*)_t, &aor, &r);

		if (res > 0) {
			LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
			goto done;
		}
		idx++;
		ptr = r->contacts;
	} while (1);
Esempio n. 23
0
static inline int get_block(struct inode * inode, sector_t block,
			struct buffer_head *bh, int create)
{
	int err = -EIO;
	int offsets[DEPTH];
	Indirect chain[DEPTH];
	Indirect *partial;
	int left;
	int depth = block_to_path(inode, block, offsets);

	if (depth == 0)
		goto out;

reread:
	partial = get_branch(inode, depth, offsets, chain, &err);

	/* Simplest case - block found, no allocation needed */
	if (!partial) {
got_it:
		map_bh(bh, inode->i_sb, block_to_cpu(chain[depth-1].key));
		/* Clean up and exit */
		partial = chain+depth-1; /* the whole chain */
		goto cleanup;
	}

	/* Next simple case - plain lookup or failed read of indirect block */
	if (!create || err == -EIO) {
cleanup:
		while (partial > chain) {
			brelse(partial->bh);
			partial--;
		}
out:
		return err;
	}

	/*
	 * Indirect block might be removed by truncate while we were
	 * reading it. Handling of that case (forget what we've got and
	 * reread) is taken out of the main path.
	 */
	if (err == -EAGAIN)
		goto changed;

	left = (chain + depth) - partial;
	err = alloc_branch(inode, left, offsets+(partial-chain), partial);
	if (err)
		goto cleanup;

	if (splice_branch(inode, chain, partial, left) < 0)
		goto changed;

	set_buffer_new(bh);
	goto got_it;

changed:
	while (partial > chain) {
		brelse(partial->bh);
		partial--;
	}
	goto reread;
}
Esempio n. 24
0
/* function returns:
 *       1 - forward successful
 *      -1 - error during forward
 */
int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
						struct proxy_l * proxy, int reset_bcounter, int locked)
{
	str reply_reason_487 = str_init("Request Terminated");
	str backup_uri;
	str backup_dst;
	int branch_ret, lowest_ret;
	str current_uri;
	branch_bm_t  added_branches;
	int i, q;
	struct cell *t_invite;
	int success_branch;
	str dst_uri;
	struct socket_info *bk_sock;
	unsigned int br_flags, bk_bflags;
	int idx;
	str path;
	str bk_path;

	/* make -Wall happy */
	current_uri.s=0;

	/* before doing enything, update the t flags from msg */
	t->uas.request->flags = p_msg->flags;

	if (p_msg->REQ_METHOD==METHOD_CANCEL) {
		t_invite=t_lookupOriginalT(  p_msg );
		if (t_invite!=T_NULL_CELL) {
			t_invite->flags |= T_WAS_CANCELLED_FLAG;
			cancel_invite( p_msg, t, t_invite, locked );
			return 1;
		}
	}

	/* do not forward requests which were already cancelled*/
	if (no_new_branches(t)) {
		LM_INFO("discarding fwd for a 6xx transaction\n");
		ser_error = E_NO_DESTINATION;
		return -1;
	}
	if (was_cancelled(t)) {
		/* is this the first attempt of sending a branch out ? */
		if (t->nr_of_outgoings==0) {
			/* if no other signalling was performed on the transaction
			 * and the transaction was already canceled, better
			 * internally generate the 487 reply here */
			if (locked)
				t_reply_unsafe( t, p_msg , 487 , &reply_reason_487);
			else
				t_reply( t, p_msg , 487 , &reply_reason_487);
		}
		LM_INFO("discarding fwd for a cancelled transaction\n");
		ser_error = E_NO_DESTINATION;
		return -1;
	}

	/* backup current uri, sock and flags... add_uac changes it */
	backup_uri = p_msg->new_uri;
	backup_dst = p_msg->dst_uri;
	bk_sock = p_msg->force_send_socket;
	bk_path = p_msg->path_vec;
	bk_bflags = p_msg->ruri_bflags;
	/* advertised address/port are not changed */

	/* check if the UAS retranmission port needs to be updated */
	if ( (p_msg->msg_flags ^ t->uas.request->msg_flags) & FL_FORCE_RPORT )
		su_setport( &t->uas.response.dst.to, p_msg->rcv.src_port );

	/* if no more specific error code is known, use this */
	lowest_ret=E_BUG;
	/* branches added */
	added_branches=0;
	/* branch to begin with */
	if (reset_bcounter) {
		t->first_branch=t->nr_of_outgoings;
		/* check if the previous branch is a PHONY one and if yes
		 * keep it in the set of active branches; that means the 
		 * transaction had a t_wait_for_new_branches() call prior to relay() */
		if ( t->first_branch>0 &&
		(t->uac[t->first_branch-1].flags & T_UAC_IS_PHONY) )
			t->first_branch--;
	}

	/* as first branch, use current uri */
	current_uri = *GET_RURI(p_msg);
	branch_ret = add_uac( t, p_msg, &current_uri, &backup_dst,
		getb0flags(p_msg), &p_msg->path_vec, proxy);
	if (branch_ret>=0)
		added_branches |= 1<<branch_ret;
	else
		lowest_ret=branch_ret;

	/* ....and now add the remaining additional branches */
	for( idx=0; (current_uri.s=get_branch( idx, &current_uri.len, &q,
	&dst_uri, &path, &br_flags, &p_msg->force_send_socket))!=0 ; idx++ ) {
		branch_ret = add_uac( t, p_msg, &current_uri, &dst_uri,
			br_flags, &path, proxy);
		/* pick some of the errors in case things go wrong;
		   note that picking lowest error is just as good as
		   any other algorithm which picks any other negative
		   branch result */
		if (branch_ret>=0)
			added_branches |= 1<<branch_ret;
		else
			lowest_ret=branch_ret;
	}
	/* consume processed branches */
	clear_branches();

	/* restore original stuff */
	p_msg->new_uri=backup_uri;
	p_msg->parsed_uri_ok = 0;/* just to be sure; add_uac may parse other uris*/
	p_msg->dst_uri = backup_dst;
	p_msg->force_send_socket = bk_sock;
	p_msg->path_vec = bk_path;
	p_msg->ruri_bflags = bk_bflags;

	/* update on_branch, _only_ if modified, otherwise it overwrites
	 * whatever it is already in the transaction */
	if (get_on_branch())
		t->on_branch = get_on_branch();

	/* update flags, if changed in branch route */
	t->uas.request->flags = p_msg->flags;

	/* things went wrong ... no new branch has been fwd-ed at all */
	if (added_branches==0) {
		LM_ERR("failure to add branches\n");
		ser_error = lowest_ret;
		return lowest_ret;
	}

	/* send them out now */
	success_branch=0;
	for (i=t->first_branch; i<t->nr_of_outgoings; i++) {
		if (added_branches & (1<<i)) {

			if (t->uac[i].br_flags & tcp_no_new_conn_bflag)
				tcp_no_new_conn = 1;

			do {
				if (check_blacklists( t->uac[i].request.dst.proto,
				&t->uac[i].request.dst.to,
				t->uac[i].request.buffer.s,
				t->uac[i].request.buffer.len)) {
					LM_DBG("blocked by blacklists\n");
					ser_error=E_IP_BLOCKED;
				} else {
					run_trans_callbacks(TMCB_PRE_SEND_BUFFER, t, p_msg, 0, i);

					if (SEND_BUFFER( &t->uac[i].request)==0) {
						ser_error = 0;
						break;
					}

					LM_ERR("sending request failed\n");
					ser_error=E_SEND;
				}
				/* get next dns entry */
				if ( t->uac[i].proxy==0 ||
				get_next_su( t->uac[i].proxy, &t->uac[i].request.dst.to,
				(ser_error==E_IP_BLOCKED)?0:1)!=0 )
					break;
				t->uac[i].request.dst.proto = t->uac[i].proxy->proto;
				/* update branch */
				if ( update_uac_dst( p_msg, &t->uac[i] )!=0)
					break;
			}while(1);

			tcp_no_new_conn = 0;

			if (ser_error) {
				shm_free(t->uac[i].request.buffer.s);
				t->uac[i].request.buffer.s = NULL;
				t->uac[i].request.buffer.len = 0;
				continue;
			}

			success_branch++;

			start_retr( &t->uac[i].request );
			set_kr(REQ_FWDED);

			/* successfully sent out -> run callbacks */
			if ( has_tran_tmcbs( t, TMCB_REQUEST_BUILT|TMCB_MSG_SENT_OUT) ) {
				set_extra_tmcb_params( &t->uac[i].request.buffer,
					&t->uac[i].request.dst);
				run_trans_callbacks( TMCB_REQUEST_BUILT|TMCB_MSG_SENT_OUT, t,
					p_msg, 0, 0);
			}

		}
	}

	return (success_branch>0)?1:-1;
}
Esempio n. 25
0
/*
 * determines the permission of the call
 * return values:
 * -1:	deny
 * 1:	allow
 */
static int check_routing(struct sip_msg* msg, int idx) 
{
	struct hdr_field *from;
	int len, q;
	static char from_str[EXPRESSION_LENGTH+1];
	static char ruri_str[EXPRESSION_LENGTH+1];
	char* uri_str;
	str branch;
	int br_idx;

	/* turn off control, allow any routing */
	if ((!allow[idx].rules) && (!deny[idx].rules)) {
		LM_DBG("no rules => allow any routing\n");
		return 1;
	}

	/* looking for FROM HF */
	if ((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) {
		LM_ERR("failed to parse message\n");
		return -1;
	}

	if (!msg->from) {
		LM_ERR("FROM header field not found\n");
		return -1;
	}

	/* we must call parse_from_header explicitly */
	if ((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) {
		LM_ERR("failed to parse From body\n");
		return -1;
	}

	from = msg->from;
	len = ((struct to_body*)from->parsed)->uri.len;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("From header field is too long: %d chars\n", len);
		return -1;
	}
	strncpy(from_str, ((struct to_body*)from->parsed)->uri.s, len);
	from_str[len] = '\0';

	/* looking for request URI */
	if (parse_sip_msg_uri(msg) < 0) {
		LM_ERR("uri parsing failed\n");
		return -1;
	}

	len = msg->parsed_uri.user.len + msg->parsed_uri.host.len + 5;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("Request URI is too long: %d chars\n", len);
		return -1;
	}

	strcpy(ruri_str, "sip:");
	memcpy(ruri_str + 4, msg->parsed_uri.user.s, msg->parsed_uri.user.len);
	ruri_str[msg->parsed_uri.user.len + 4] = '@';
	memcpy(ruri_str + msg->parsed_uri.user.len + 5, msg->parsed_uri.host.s, msg->parsed_uri.host.len);
	ruri_str[len] = '\0';

	LM_DBG("looking for From: %s Request-URI: %s\n", from_str, ruri_str);
	/* rule exists in allow file */
	if (search_rule(allow[idx].rules, from_str, ruri_str)) {
		if (check_all_branches) goto check_branches;
		LM_DBG("allow rule found => routing is allowed\n");
		return 1;
	}

	/* rule exists in deny file */
	if (search_rule(deny[idx].rules, from_str, ruri_str)) {
		LM_DBG("deny rule found => routing is denied\n");
		return -1;
	}

	if (!check_all_branches) {
		LM_DBG("neither allow nor deny rule found => routing is allowed\n");
		return 1;
	}

check_branches:
	for( br_idx=0 ; (branch.s=get_branch(br_idx,&branch.len,&q,0,0,0,0,0,0,0))!=0 ;
			br_idx++ ) {
		uri_str = get_plain_uri(&branch);
		if (!uri_str) {
			LM_ERR("failed to extract plain URI\n");
			return -1;
		}
		LM_DBG("looking for From: %s Branch: %s\n", from_str, uri_str);

		if (search_rule(allow[idx].rules, from_str, uri_str)) {
			continue;
		}

		if (search_rule(deny[idx].rules, from_str, uri_str)) {
			LM_DBG("deny rule found for one of branches => routing"
					"is denied\n");
			return -1;
		}
	}

	LM_DBG("check of branches passed => routing is allowed\n");
	return 1;
}
Esempio n. 26
0
/* function returns:
 *       1 - forward successful
 *      -1 - error during forward
 */
int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
	struct proxy_l * proxy)
{
	str backup_uri;
	str backup_dst;
	int branch_ret, lowest_ret;
	str current_uri;
	branch_bm_t  added_branches;
	int i, q;
	struct cell *t_invite;
	int success_branch;
	str dst_uri;
	struct socket_info *bk_sock;
	unsigned int br_flags;
	unsigned int bk_br_flags;
	int idx;
	str path;
	str bk_path;

	/* make -Wall happy */
	current_uri.s=0;

	/* before doing enything, update the t falgs from msg */
	t->uas.request->flags = p_msg->flags;

	if (p_msg->REQ_METHOD==METHOD_CANCEL) {
		t_invite=t_lookupOriginalT(  p_msg );
		if (t_invite!=T_NULL_CELL) {
			t_invite->flags |= T_WAS_CANCELLED_FLAG;
			cancel_invite( p_msg, t, t_invite );
			return 1;
		}
	}

	/* do not forward requests which were already cancelled*/
	if (was_cancelled(t) || no_new_branches(t)) {
		LM_ERR("discarding fwd for a cancelled/6xx transaction\n");
		ser_error = E_NO_DESTINATION;
		return -1;
	}

	/* backup current uri, sock and flags... add_uac changes it */
	backup_uri = p_msg->new_uri;
	backup_dst = p_msg->dst_uri;
	bk_sock = p_msg->force_send_socket;
	bk_br_flags = getb0flags();
	bk_path = p_msg->path_vec;

	/* check if the UAS retranmission port needs to be updated */
	if ( (p_msg->msg_flags ^ t->uas.request->msg_flags) & FL_FORCE_RPORT )
		su_setport( &t->uas.response.dst.to, p_msg->rcv.src_port );

	/* if no more specific error code is known, use this */
	lowest_ret=E_BUG;
	/* branches added */
	added_branches=0;
	/* branch to begin with */
	t->first_branch=t->nr_of_outgoings;

	/* as first branch, use current uri */
	current_uri = *GET_RURI(p_msg);
	branch_ret = add_uac( t, p_msg, &current_uri, &backup_dst,
		&p_msg->path_vec, proxy);
	if (branch_ret>=0)
		added_branches |= 1<<branch_ret;
	else
		lowest_ret=branch_ret;

	/* ....and now add the remaining additional branches */
	for( idx=0; (current_uri.s=get_branch( idx, &current_uri.len, &q,
	&dst_uri, &path, &br_flags, &p_msg->force_send_socket))!=0 ; idx++ ) {
		setb0flags(br_flags);
		branch_ret = add_uac( t, p_msg, &current_uri, &dst_uri, &path, proxy);
		/* pick some of the errors in case things go wrong;
		   note that picking lowest error is just as good as
		   any other algorithm which picks any other negative
		   branch result */
		if (branch_ret>=0)
			added_branches |= 1<<branch_ret;
		else
			lowest_ret=branch_ret;
	}
	/* consume processed branches */
	clear_branches();

	/* restore original stuff */
	p_msg->new_uri=backup_uri;
	p_msg->parsed_uri_ok = 0;/* just to be sure; add_uac may parse other uris*/
	p_msg->dst_uri = backup_dst;
	p_msg->force_send_socket = bk_sock;
	p_msg->path_vec = bk_path;
	setb0flags(bk_br_flags);
	/* update on_branch, if modified */
	t->on_branch = get_on_branch();
	/* update flags, if changed in branch route */
	t->uas.request->flags = p_msg->flags;

	/* things went wrong ... no new branch has been fwd-ed at all */
	if (added_branches==0) {
		LM_ERR("failure to add branches\n");
		ser_error = lowest_ret;
		return lowest_ret;
	}

	/* send them out now */
	success_branch=0;
	for (i=t->first_branch; i<t->nr_of_outgoings; i++) {
		if (added_branches & (1<<i)) {

#ifdef USE_TCP
			if (t->uac[i].br_flags & tcp_no_new_conn_bflag)
				tcp_no_new_conn = 1;
#endif

			do {
				if (check_blacklists( t->uac[i].request.dst.proto,
				&t->uac[i].request.dst.to,
				t->uac[i].request.buffer.s,
				t->uac[i].request.buffer.len)) {
					LM_DBG("blocked by blacklists\n");
					ser_error=E_IP_BLOCKED;
				} else {
					if (SEND_BUFFER( &t->uac[i].request)==0) {
						ser_error = 0;
						break;
					}
					LM_ERR("sending request failed\n");
					ser_error=E_SEND;
				}
				/* get next dns entry */
				if ( t->uac[i].proxy==0 ||
				get_next_su( t->uac[i].proxy, &t->uac[i].request.dst.to,
				(ser_error==E_IP_BLOCKED)?0:1)!=0 )
					break;
				t->uac[i].request.dst.proto = t->uac[i].proxy->proto;
				/* update branch */
				if ( update_uac_dst( p_msg, &t->uac[i] )!=0)
					break;
			}while(1);

#ifdef USE_TCP
			tcp_no_new_conn = 0;
#endif

			if (ser_error) {
				shm_free(t->uac[i].request.buffer.s);
				t->uac[i].request.buffer.s = NULL;
				t->uac[i].request.buffer.len = 0;
				continue;
			}

			success_branch++;

			start_retr( &t->uac[i].request );
			set_kr(REQ_FWDED);

			/* successfully sent out -> run callbacks */
			if ( has_tran_tmcbs( t, TMCB_REQUEST_BUILT) ) {
				set_extra_tmcb_params( &t->uac[i].request.buffer,
					&t->uac[i].request.dst);
				run_trans_callbacks( TMCB_REQUEST_BUILT, t, p_msg,0,
					-p_msg->REQ_METHOD);
			}

		}
	}

	return (success_branch>0)?1:-1;
}
Esempio n. 27
0
int main(int argc, char *argv[])
{
	struct unionfs_addbranch_args addargs;
	struct unionfs_rdwrbranch_args rdwrargs;
	unsigned long remountdata[3];
	fd_set branchlist;
	struct stat st;

	int fd = -1;
	int ret, i;

	char *path, resolv_path[PATH_MAX], resolv_bp[PATH_MAX];
	char *options = NULL, *actual_path = NULL;
	int action;

	char *branchpath;
	int branchnum;
	int unionpos = 1;
	int modepos = 2;

	progname = argv[0];

	/* check that minimum number of args were specified */
	if (argc < 3)
		usage();

	if (argv[1][0] == '-' && argv[1][1] == '-') {
		modepos = 1;
		unionpos = 2;
	} else {
		modepos = 2;
		unionpos = 1;
	}

	if (realpath(argv[unionpos], resolv_path) == NULL) {
		perror("realpath()");
		exit(EXIT_FAILURE);
	}
	path = resolv_path;
	if (strcmp(path, "/") && (path[strlen(path) - 1] == '/')) {
		path[strlen(path) - 1] = '\0';
	}

	if (!strcmp(argv[modepos], "--add")) {
		action = ADD;
	} else if (!strcmp(argv[modepos], "--remove")) {
		action = REMOVE;
	} else if (!strcmp(argv[modepos], "--mode")) {
		action = MODE;
	} else if (!strcmp(argv[modepos], "--list")) {
		action = LIST;
	} else if (!strcmp(argv[modepos], "--query")) {
		action = QUERY;
	} else {
		usage();
	}

	if (stat(path, &st) == -1) {
		fprintf(stderr, "stat(%s): %s\n", path, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (find_union(path, &options, &actual_path, 1) < 0) {
		fprintf(stderr, "%s is not a valid union.\n", path);
		exit(EXIT_FAILURE);
	}
	branches = parse_options(options);
	if (!branches) {
		fprintf(stderr, "Could not parse options from /proc/mounts!\n");
		exit(EXIT_FAILURE);
	}

	/* open file on which ioctl will operate (that is actually any file in the union) */
	if (action != REMOVE) {
		fd = open(path, O_RDONLY);
		if (fd < 0) {
			fprintf(stderr, "open(%s): %s\n", path,
				strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/* Parse the action's options into something usable, and do it. */
	switch (action) {
	case ADD:
		if (argc < 4)
			usage();

		/* Default values if the user leaves them unspecified. */
		branchnum = 0;
		addargs.ab_perms = MAY_READ | MAY_WRITE;
		branchpath = NULL;
		for (i = 3; i < argc; i++) {
			if (argv[i][0] == '-' && argv[i][1] == '-') {
				if (!strcmp(argv[i], "--before")) {
					i++;
					if (i == argc) {
						fprintf(stderr,
							"%s requires an argument!\n",
							argv[i - 1]);
						usage();
					}

					branchnum = get_branch(argv[i]);
					if (branchnum == -1) {
						fprintf(stderr,
							"%s is not a valid branch.\nThe current branch configuration is:\n",
							argv[i]);
						dump_branches("\t");
					}
				} else if (!strcmp(argv[i], "--after")) {
					i++;
					if (i == argc) {
						fprintf(stderr,
							"%s requires an argument!\n",
							argv[i - 1]);
						usage();
					}

					branchnum = get_branch(argv[i]);
					if (branchnum == -1) {
						fprintf(stderr,
							"%s is not a valid branch.\nThe current branch configuration is:\n",
							argv[i]);
						dump_branches("\t");
					}
					branchnum++;
				} else if (!strcmp(argv[i], "--mode")) {
					i++;
					if (i == argc) {
						fprintf(stderr,
							"%s requires an argument!\n",
							argv[i - 1]);
						usage();
					}

					if (!strcmp(argv[i], "ro")) {
						addargs.ab_perms = MAY_READ;
					} else if (!strcmp(argv[i], "rw")) {
						addargs.ab_perms =
						    MAY_READ | MAY_WRITE;
					} else {
						fprintf(stderr,
							"Valid modes are ro and rw you specified: \"%s\"\n",
							argv[i]);
						usage();
					}
				} else {
					fprintf(stderr, "Unknown option: %s\n",
						argv[i]);
					usage();
				}
			} else {
				/* The options must go before the path */
				if ((i + 1) != argc) {
					fprintf(stderr,
						"The path of the branch to add must go after all options.\n");
					usage();
				}
				if (branchnum != -1) {
					fprintf(stderr,
						"%s already exists in the Union\n",
						argv[i]);
					usage();
				}
				branchpath = argv[i];
			}
		}
		if (!branchpath) {
			fprintf(stderr,
				"You must specify the path to add into the union!\n");
			usage();
		}

		if (realpath(branchpath, resolv_bp) == NULL) {
			perror("realpath()");
			exit(EXIT_FAILURE);
		}

		addargs.ab_branch = branchnum;
		addargs.ab_path = resolv_bp;

		errno = 0;
		ret = ioctl(fd, UNIONFS_IOCTL_ADDBRANCH, &addargs);
		if (ret < 0) {
			switch (errno) {
			case E2BIG:
				fprintf(stderr,
					"Unionfs supports only %d branches.\n",
					FD_SETSIZE);
				break;
			}
			fprintf(stderr, "Failed to add %s into %s: %s",
				branchpath, path, strerror(errno));
			exit(EXIT_FAILURE);
		}
		break;
	case MODE:
		if (argc != 5) {
			usage();
		}

		if (!strcmp(argv[4], "ro")) {
			rdwrargs.rwb_perms = MAY_READ;
			branchnum = 3;
		} else if (!strcmp(argv[4], "rw")) {
			rdwrargs.rwb_perms = MAY_READ | MAY_WRITE;
			branchnum = 3;
		} else if (!strcmp(argv[3], "ro")) {
			rdwrargs.rwb_perms = MAY_READ;
			branchnum = 4;
		} else if (!strcmp(argv[3], "rw")) {
			rdwrargs.rwb_perms = MAY_READ | MAY_WRITE;
			branchnum = 4;
		} else {
			usage();
		}

		if (realpath(argv[branchnum], resolv_bp) == NULL) {
			perror("realpath()");
			exit(EXIT_FAILURE);
		}
		branchpath = resolv_bp;

		/* Set a branches writeable status. */
		rdwrargs.rwb_branch = get_branch(branchpath);
		if (rdwrargs.rwb_branch == -1) {
			fprintf(stderr,
				"%s is not a valid branch.\nThe current branch configuration is:\n",
				branchpath);
			dump_branches("\t");
			exit(EXIT_FAILURE);
		}

		ret = ioctl(fd, UNIONFS_IOCTL_RDWRBRANCH, &rdwrargs);
		if (ret < 0) {
			fprintf(stderr,
				"Failed to set permissions for %s in %s: %s",
				branchpath, path, strerror(errno));
			exit(EXIT_FAILURE);
		}

		goto out;
		break;
	case REMOVE:
		if (argc != 4)
			usage();

		if (realpath(argv[3], resolv_bp) == NULL) {
			perror("realpath()");
			exit(EXIT_FAILURE);
		}
		branchpath = resolv_bp;

		branchnum = get_branch(branchpath);
		if (branchnum == -1) {
			fprintf(stderr,
				"%s is not a valid branch.\nThe current branch configuration is:\n",
				branchpath);
			dump_branches("\t");
			exit(EXIT_FAILURE);
		}

		errno = 0;
		remountdata[0] = UNIONFS_REMOUNT_MAGIC;
		remountdata[1] = UNIONFS_IOCTL_DELBRANCH;
		remountdata[2] = branchnum;
		ret =
		    mount("unionfs", actual_path, "unionfs",
			  MS_REMOUNT | MS_MGC_VAL, remountdata);
		if (ret < 0) {
			fprintf(stderr, "Failed to remove %s from %s: %s",
				branchpath, path, strerror(errno));
			exit(EXIT_FAILURE);
		}
		break;
	case LIST:
		dump_branches("\t");
		break;

	case QUERY:
		if (argc != 3) {
			usage();
		}

		if ((fd = open(argv[unionpos], O_RDONLY)) < 0) {
			fprintf(stderr,
				"Unable to open file %s : %s",
				argv[unionpos], strerror(errno));
			exit(EXIT_FAILURE);
		}

		ret = ioctl(fd, UNIONFS_IOCTL_QUERYFILE, &branchlist);
		if (ret < 0) {
			fprintf(stderr,
				"Unable to retrieve list of branches for file %s : %s\n",
				argv[unionpos], strerror(errno));
			exit(EXIT_FAILURE);
		}

		for (i = 0; i <= ret; i++) {
			char r, w;
			r = (branchperms[i] & MAY_READ) ? 'r' : '-';
			w = (branchperms[i] & MAY_WRITE) ? 'w' : '-';

			if (FD_ISSET(i, &branchlist))
				printf("%s\t%s (%c%c)\n", argv[unionpos],
				       branches[i], r, w);
		}
		break;
	}

      out:
	if (fd != -1)
		close(fd);
	exit(EXIT_SUCCESS);
}
Esempio n. 28
0
/* 
 * Loads contacts in destination set into contacts_avp in reverse
 * priority order and associated each contact with Q_FLAG telling if
 * contact is the last one in its priority class.  Finally, removes
 * all branches from destination set.
 */
int t_load_contacts(struct sip_msg* msg, char* key, char* value)
{
    str uri, tmp, dst_uri, path, branch_info, *ruri;
    qvalue_t first_q, q;
    struct contact *contacts, *next, *prev, *curr;
    int_str val;
    int first_idx, idx;
    struct socket_info* sock;
    unsigned int flags;

    /* Check if contacts_avp has been defined */
    if (contacts_avp.n == 0) {
		LM_ERR("feature has been disabled - "
		       "to enable define contacts_avp module parameter");
		return -1;
    }

    /* Check if anything needs to be done */
    if (nr_branches == 0) {
		LM_DBG("t_load_contacts(): nothing to do - no branches!\n");
		return 1;
    }

    ruri = (str *)0;

    /* Take first q from Request-URI */
    ruri = GET_RURI(msg);
    if (!ruri) {
	LM_ERR("no Request-URI found\n");
	return -1;
    }
    first_q = get_ruri_q();
    first_idx = 0;

    /* Check if all q values are equal */
    for(idx = first_idx; (tmp.s = get_branch(idx, &tmp.len, &q, 0, 0, 0, 0))
			!= 0; idx++) {
		if (q != first_q) {
			goto rest;
		}
    }

    LM_DBG("t_load_contacts(): nothing to do - all contacts have same q!\n");
    return 1;

rest:

    /* Allocate memory for first contact */
    contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
    if (!contacts) {
		LM_ERR("no memory for contact info\n");
		return -1;
    }

    /* Insert Request-URI branch to first contact */
    contacts->uri.s = ruri->s;
    contacts->uri.len = ruri->len;
    contacts->dst_uri = msg->dst_uri;
    contacts->sock = msg->force_send_socket;
    getbflagsval(0, &contacts->flags);
    contacts->path = msg->path_vec;
    contacts->q = first_q;
    contacts->next = (struct contact *)0;

    /* Insert (remaining) branches to contact list in increasing q order */

    for(idx = first_idx;
		(uri.s = get_branch(idx,&uri.len,&q,&dst_uri,&path,&flags,&sock))
			!= 0;
		idx++ ) {
		next = (struct contact *)pkg_malloc(sizeof(struct contact));
		if (!next) {
			LM_ERR("no memory for contact info\n");
			free_contact_list(contacts);
			return -1;
		}
		next->uri = uri;
		next->q = q;
		next->dst_uri = dst_uri;
		next->path = path;
		next->flags = flags;
		next->sock = sock;
		next->next = (struct contact *)0;
		prev = (struct contact *)0;
		curr = contacts;
		while (curr && (curr->q < q)) {
			prev = curr;
			curr = curr->next;
		}
		if (!curr) {
			next->next = (struct contact *)0;
			prev->next = next;
		} else {
			next->next = curr;
			if (prev) {
				prev->next = next;
			} else {
				contacts = next;
			}
		}    
    }

    /* Assign values for q_flags */
    curr = contacts;
    curr->q_flag = 0;
    while (curr->next) {
		if (curr->q < curr->next->q) {
			curr->next->q_flag = Q_FLAG;
		} else {
			curr->next->q_flag = 0;
		}
		curr = curr->next;
    }

    /* Add contacts to contacts_avp */
    curr = contacts;
    while (curr) {
		if (encode_branch_info(&branch_info, curr) == 0) {
			LM_ERR("encoding of branch info failed\n");
			free_contact_list(contacts);
			if (branch_info.s) pkg_free(branch_info.s);
			return -1;
		}
		val.s = branch_info;
		add_avp(contacts_avp_type|AVP_VAL_STR|(curr->q_flag),
				contacts_avp, val);
		pkg_free(branch_info.s);
		LM_DBG("loaded contact <%.*s> with q_flag <%d>\n",
		       STR_FMT(&val.s), curr->q_flag);
		curr = curr->next;
    }

    /* Clear all branches */
    clear_branches();

    /* Free contact list */
    free_contact_list(contacts);

    return 1;
}
Esempio n. 29
0
/*! \brief
 * Loads contacts in destination set into "serial_fork" AVP in reverse
 * priority order and associated each contact with Q_FLAG telling if
 * contact is the last one in its priority class.  Finally, removes
 * all branches from destination set.
 */
int serialize_branches(struct sip_msg *msg, int clean_before )
{
	static struct serial_contact contacts[MAX_BRANCHES];
	int n, last, first, i, prev;
	str branch, *ruri;
	qvalue_t q, ruri_q;
	char *p;
	str dst_uri, path, enc_info;
	unsigned int flags;
	struct socket_info *sock_info;
	int_str val;
	int idx;

	/* Check if anything needs to be done */
	if (nr_branches == 0) {
		LM_DBG("nothing to do - no branches!\n");
		return 0;
	}

	ruri = GET_RURI(msg);
	ruri_q = get_ruri_q();
	flags = getb0flags();

	for (idx = 0; (branch.s = get_branch(idx,&branch.len,&q,0,0,0,0)); idx++) {
		if (q != ruri_q)
			break;
	}

	if (branch.s == 0) {
		LM_DBG("nothing to do - all same q!\n");
		return 0;
	}

	/* reset contact array */
	n = 0;

	/* Insert Request-URI to contact list */
	enc_info.len = 3 * sizeof(long)
			+ ruri->len + msg->dst_uri.len + msg->path_vec.len + 3;
	enc_info.s = (char*) pkg_malloc (enc_info.len);

	if (!enc_info.s) {
		LM_ERR("no pkg memory left\n");
		goto error; /* nothing to free here */
	}

	memset(enc_info.s, 0, enc_info.len);
	p = enc_info.s;

	LM_DBG("Msg information <%.*s,%.*s,%.*s,%d,%u>\n",
			ruri->len, ruri->s,
			msg->dst_uri.len, msg->dst_uri.s,
			msg->path_vec.len, msg->path_vec.s,
			ruri_q, flags);

	*((long*) p) = (long)msg->force_send_socket;
	p += sizeof(long);
	*((long*) p) = (long)flags;
	p += sizeof(long);
	*((long*) p) = (long)ruri_q;
	p += sizeof(long);

	memcpy(p , ruri->s, ruri->len);
	p += ruri->len + 1;
	memcpy(p, msg->dst_uri.s, msg->dst_uri.len);
	p += msg->dst_uri.len + 1;
	memcpy(p, msg->path_vec.s, msg->path_vec.len);

	contacts[n].enc_info = enc_info;
	contacts[n].q = ruri_q;
	contacts[n].next = -1;
	last = n;
	first = n;
	n++;

	/* Insert branch URIs to contact list in increasing q order */
	for (idx = 0;(branch.s = get_branch(idx, &branch.len, &q,
					&dst_uri, &path, &flags, &sock_info)); idx++){

		enc_info.len = 3 * sizeof(long)
						+ branch.len + dst_uri.len + path.len + 3;
		enc_info.s = (char*) pkg_malloc (enc_info.len);

		if (!enc_info.s) {
			LM_ERR("no pkg memory left\n");
			goto error_free;
		}

		memset(enc_info.s, 0, enc_info.len);
		p = enc_info.s;

		LM_DBG("Branch information <%.*s,%.*s,%.*s,%d,%u>\n", 
				branch.len, branch.s,
				dst_uri.len, dst_uri.s,
				path.len, path.s,
				q, flags);

		*((long*) p) = (long)sock_info;
		p += sizeof(long);
		*((long*) p) = (long)flags;
		p += sizeof(long);
		*((long*) p) = (long)q;
		p += sizeof(long);

		memcpy(p , branch.s, branch.len);
		p += branch.len + 1;
		memcpy(p, dst_uri.s, dst_uri.len);
		p += dst_uri.len + 1;
		memcpy(p, path.s, path.len);

		contacts[n].enc_info = enc_info;
		contacts[n].q = q;

		/* insert based on q */
		for (i = first, prev=-1; i != -1 && contacts[i].q < q; prev=i,i = contacts[i].next);

		if (i == -1) {
			/* append */
			last = contacts[last].next = n;
			contacts[n].next = -1;
		} else {
			if (i == first) {
				/* first element */
				contacts[n].next = first;
				first = n;
			} else {
				/* before pos i */
				contacts[n].next = contacts[prev].next;
				contacts[prev].next = n;
			}
		}

		n++;
	}

	/* Assign values for q_flags */
	for (i = first; contacts[i].next != -1; i = contacts[i].next) {
		if (contacts[i].q < contacts[contacts[i].next].q)
			contacts[contacts[i].next].q_flag = Q_FLAG;
		else
			contacts[contacts[i].next].q_flag = 0;
	}

	if (clean_before)
		destroy_avps( 0/*type*/, serial_avp, 1/*all*/);

	/* Add contacts to "contacts" AVP */
	for (i = first; i != -1; i = contacts[i].next) {
		val.s = contacts[i].enc_info;

		if (add_avp( AVP_VAL_STR|contacts[i].q_flag, serial_avp, val)) {
			LM_ERR("failed to add avp\n");
			goto error_free;
		}

		pkg_free(contacts[i].enc_info.s);
		contacts[i].enc_info.s = NULL;
	}

	/* Clear all branches */
	clear_branches();

	return 0;
error_free:
	for( i=0 ; i<n ; i++) {
		if (contacts[i].enc_info.s)
			pkg_free(contacts[i].enc_info.s);
	}
error:
	return -1;
}
Esempio n. 30
0
/* function returns:
 *       1 - forward successful
 *      -1 - error during forward
 */
int t_forward_nonack( struct cell *t, struct sip_msg* p_msg , 
	struct proxy_l * proxy, int proto)
{
	str backup_uri;
	str backup_dst;
	int branch_ret, lowest_ret;
	str current_uri;
	branch_bm_t  added_branches;
	int i, q;
	struct cell *t_invite;
	int success_branch;
	int try_new;
	str dst_uri;
	struct socket_info *bk_sock;
	int rurib_flags;
	int br_flags;
	int idx;

	/* make -Wall happy */
	current_uri.s=0;

	set_kr(REQ_FWDED);

	if (p_msg->REQ_METHOD==METHOD_CANCEL) {
		t_invite=t_lookupOriginalT(  p_msg );
		if (t_invite!=T_NULL_CELL) {
			t_invite->flags |= T_WAS_CANCELLED_FLAG;
			e2e_cancel( p_msg, t, t_invite );
			UNREF(t_invite);
			return 1;
		}
	}

	/* do not forward requests which were already cancelled*/
	if (was_cancelled(t)) {
		LOG(L_ERR,"ERROR:tm:t_forward_nonack: discarding fwd for "
				"a cancelled transaction\n");
		return -1;
	}

	/* backup current uri, sock and flags ... add_uac changes it */
	backup_uri = p_msg->new_uri;
	backup_dst = p_msg->dst_uri;
	bk_sock = p_msg->force_send_socket;
	rurib_flags = p_msg->flags&(~gflags_mask);

	/* if no more specific error code is known, use this */
	lowest_ret=E_BUG;
	/* branches added */
	added_branches=0;
	/* branch to begin with */
	t->first_branch=t->nr_of_outgoings;

	/* on first-time forwarding, use current uri, later only what
	   is in additional branches (which may be continuously refilled)
	*/
	if (t->first_branch==0) {
		try_new=1;
		current_uri = *GET_RURI(p_msg);
		branch_ret = add_uac( t, p_msg, &current_uri, &backup_dst,
			proxy, proto );
		if (branch_ret>=0)
			added_branches |= 1<<branch_ret;
		else
			lowest_ret=branch_ret;
	} else try_new=0;

	for( idx=0; (current_uri.s=get_branch( idx, &current_uri.len, &q,
	&dst_uri, &br_flags, &p_msg->force_send_socket))!=0 ; idx++ ) {
		try_new++;
		p_msg->flags = (p_msg->flags&gflags_mask) | br_flags;
		branch_ret=add_uac( t, p_msg, &current_uri, &dst_uri, proxy, proto);
		/* pick some of the errors in case things go wrong;
		   note that picking lowest error is just as good as
		   any other algorithm which picks any other negative
		   branch result */
		if (branch_ret>=0) 
			added_branches |= 1<<branch_ret;
		else
			lowest_ret=branch_ret;
	}
	/* consume processed branches */
	clear_branches();

	/* restore original stuff */
	p_msg->new_uri=backup_uri;
	p_msg->parsed_uri_ok = 0;/* just to be sure; add_uac may parse other uris*/
	p_msg->dst_uri = backup_dst;
	p_msg->force_send_socket = bk_sock;
	/* update on_branch, if modified */
	t->on_branch = get_on_branch();
	/* set flags */
	p_msg->flags = (p_msg->flags&gflags_mask)|rurib_flags;
	t->uas.request->flags = p_msg->flags&gflags_mask;

	/* don't forget to clear all branches processed so far */

	/* things went wrong ... no new branch has been fwd-ed at all */
	if (added_branches==0) {
		if (try_new==0) {
			LOG(L_ERR, "ERROR:tm:t_forward_nonack: no branch for "
				"forwarding\n");
			return -1;
		}
		LOG(L_ERR, "ERROR:tm:t_forward_nonack: failure to add branches\n");
		return lowest_ret;
	}

	/* send them out now */
	success_branch=0;
	for (i=t->first_branch; i<t->nr_of_outgoings; i++) {
		if (added_branches & (1<<i)) {
			if (SEND_BUFFER( &t->uac[i].request)==-1) {
				LOG(L_ERR, "ERROR:tm:t_forward_nonack: sending request "
					"failed\n");
				if (proxy) { proxy->errors++; proxy->ok=0; }
			} else {
				success_branch++;
			}
			start_retr( &t->uac[i].request );
		}
	}
	if (success_branch<=0) {
		ser_error=E_SEND;
		return -1;
	}
	return 1;
}