Exemplo n.º 1
0
static NTSTATUS rpcint_dispatch(struct pipes_struct *p,
				TALLOC_CTX *mem_ctx,
				uint32_t opnum,
				const DATA_BLOB *in_data,
				DATA_BLOB *out_data)
{
	struct pipe_rpc_fns *fns = find_pipe_fns_by_context(p->contexts, 0);
	uint32_t num_cmds = fns->n_cmds;
	const struct api_struct *cmds = fns->cmds;
	uint32_t i;
	bool ok;

	/* set opnum */
	p->opnum = opnum;

	for (i = 0; i < num_cmds; i++) {
		if (cmds[i].opnum == opnum && cmds[i].fn != NULL) {
			break;
		}
	}

	if (i == num_cmds) {
		return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
	}

	p->in_data.data = *in_data;
	p->out_data.rdata = data_blob_null;

	ok = cmds[i].fn(p);
	p->in_data.data = data_blob_null;
	if (!ok) {
		data_blob_free(&p->out_data.rdata);
		talloc_free_children(p->mem_ctx);
		return NT_STATUS_RPC_CALL_FAILED;
	}

	if (p->fault_state) {
		NTSTATUS status;

		status = NT_STATUS(p->fault_state);
		p->fault_state = 0;
		data_blob_free(&p->out_data.rdata);
		talloc_free_children(p->mem_ctx);
		return status;
	}

	*out_data = p->out_data.rdata;
	talloc_steal(mem_ctx, out_data->data);
	p->out_data.rdata = data_blob_null;

	talloc_free_children(p->mem_ctx);
	return NT_STATUS_OK;
}
Exemplo n.º 2
0
static void free_pipe_context(struct pipes_struct *p)
{
	data_blob_free(&p->out_data.frag);
	data_blob_free(&p->out_data.rdata);
	data_blob_free(&p->in_data.data);

	DEBUG(3, ("free_pipe_context: "
		"destroying talloc pool of size %lu\n",
		(unsigned long)talloc_total_size(p->mem_ctx)));
	talloc_free_children(p->mem_ctx);
}
Exemplo n.º 3
0
static bool test_free_children(void)
{
	void *root;
	const char *p1, *p2, *name, *name2;

	talloc_enable_null_tracking();
	root = talloc_new(NULL);
	p1 = talloc_strdup(root, "foo1");
	p2 = talloc_strdup(p1, "foo2");

	talloc_set_name(p1, "%s", "testname");
	talloc_free_children(p1);
	/* check its still a valid talloc ptr */
	talloc_get_size(talloc_get_name(p1));
	if (strcmp(talloc_get_name(p1), "testname") != 0) {
		return false;
	}

	talloc_set_name(p1, "%s", "testname");
	name = talloc_get_name(p1);
	talloc_free_children(p1);
	/* check its still a valid talloc ptr */
	talloc_get_size(talloc_get_name(p1));
	torture_assert("name", name == talloc_get_name(p1), "name ptr changed");
	torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0,
		       "wrong name");
	CHECK_BLOCKS("name1", p1, 2);

	/* note that this does not free the old child name */
	talloc_set_name_const(p1, "testname2");
	name2 = talloc_get_name(p1);
	/* but this does */
	talloc_free_children(p1);
	torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0,
		       "wrong name");
	CHECK_BLOCKS("name1", p1, 1);

	talloc_report_full(root, stdout);
	talloc_free(root);
	return true;
}
Exemplo n.º 4
0
static void free_pipe_context(pipes_struct *p)
{
	if (p->mem_ctx) {
		DEBUG(3,("free_pipe_context: destroying talloc pool of size "
			 "%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
		talloc_free_children(p->mem_ctx);
	} else {
		p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
		if (p->mem_ctx == NULL) {
			p->fault_state = True;
		}
	}
}
Exemplo n.º 5
0
static void gen_inst(CTX *ctx, struct ir_inst *in)
{
    struct ir_type res_t = in->result_type;
    bool is_void = type_is_void(res_t);
    // Don't write anything not needed. Note that void values are never actually
    // "used" by the generated C code, and instead are replaced with VOID_VAL.
    if (!ir_op_writes_side_effects(in->op) && !ir_op_is_branch(in->op)) {
        if (is_void)
            return;
        if (in->users_count == 0)
            return;
        // If it has 1 use, it can be generated inline.
        if (write_inline && in->users_count == 1) {
            // But if it crosses side effects, it must be generated earlier.
            // NOTE: if there are any not yet generated instructions with read
            //       side-effects, we must generate the code before crossing
            //       write side-effects as well.
            // Consider: t1=read; t2=neg(t1); call a(); call b(t2);
            // Mustn't turn into: call a(); call b(neg(read));
            bool crosses_sideffects = false;
            if (has_outstanding_sideffect_reads(in)) {
                struct ir_inst *user= in->users[0];
                for (struct ir_inst *cur = in; cur; cur = cur->next) {
                    if (cur == user)
                        break;
                    if (ir_op_writes_side_effects(cur->op)) {
                        crosses_sideffects = true;
                        break;
                    }
                }
            }
            if (!crosses_sideffects)
                return;
        }
    }

    set_loc(ctx, in->loc);
    indent(ctx);
    if (!TEST_UNION0(IR_TYPE, any, &res_t) && !is_void && in->users_count > 0)
    {
        if (in->scratch1_i == -1)
            in->scratch1_i = ctx->reg++;
        P(ctx, "%s %s = ", type(ctx, res_t), get_temp(ctx, in->scratch1_i));
    }

    write_inst(ctx, in, false);

    fprintf(ctx->f, ";\n");

    talloc_free_children(ctx->tmp);
}
Exemplo n.º 6
0
void print_notify_send_messages(struct messaging_context *msg_ctx,
				unsigned int timeout)
{
	if (!print_notify_messages_pending())
		return;

	if (!create_send_ctx())
		return;

	while (print_notify_messages_pending())
		print_notify_send_messages_to_printer(
			msg_ctx, notify_queue_head->msg->printer, timeout);

	talloc_free_children(send_ctx);
	num_messages = 0;
}
Exemplo n.º 7
0
/** Retrieve any errors from the SQL driver
 *
 * Retrieves errors from the driver from the last operation and writes them to
 * to request/global log, in the ERROR, WARN, INFO and DEBUG categories.
 *
 * @param inst Instance of rlm_sql.
 * @param request Current request, may be NULL.
 * @param handle Handle to retrieve errors for.
 * @param force_debug Force all errors to be logged as debug messages.
 */
void rlm_sql_print_error(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle, bool force_debug)
{
	char const	*driver;
	sql_log_entry_t	log[20];
	size_t		num, i;

	num = (inst->module->sql_error)(handle->log_ctx, log, (sizeof(log) / sizeof(*log)), handle, inst->config);
	if (num == 0) {
		ROPTIONAL(RERROR, ERROR, "Unknown error");
		return;
	}

	driver = inst->config->sql_driver_name;

	for (i = 0; i < num; i++) {
		if (force_debug) goto debug;

		switch (log[i].type) {
		case L_ERR:
			ROPTIONAL(RERROR, ERROR, "%s: %s", driver, log[i].msg);
			break;

		case L_WARN:
			ROPTIONAL(RWARN, WARN, "%s: %s", driver, log[i].msg);
			break;

		case L_INFO:
			ROPTIONAL(RINFO, INFO, "%s: %s", driver, log[i].msg);
			break;

		case L_DBG:
		default:
		debug:
			ROPTIONAL(RDEBUG, DEBUG, "%s: %s", driver, log[i].msg);
			break;
		}
	}

	talloc_free_children(handle->log_ctx);
}
Exemplo n.º 8
0
static int mod_detach(void *instance)
{
	rlm_sql_t *inst = instance;

	if (inst->pool) fr_connection_pool_delete(inst->pool);

	/*
	 *  We need to explicitly free all children, so if the driver
	 *  parented any memory off the instance, their destructors
	 *  run before we unload the bytecode for them.
	 *
	 *  If we don't do this, we get a SEGV deep inside the talloc code
	 *  when it tries to call a destructor that no longer exists.
	 */
	talloc_free_children(inst);

	/*
	 *  Decrements the reference count. The driver object won't be unloaded
	 *  until all instances of rlm_sql that use it have been destroyed.
	 */
	if (inst->handle) dlclose(inst->handle);

	return 0;
}
Exemplo n.º 9
0
struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11,
                               struct mp_fifo *key_fifo,
                               struct input_ctx *input_ctx)
{
    char **vo_list = opts->video_driver_list;
    int i;
    struct vo *vo = talloc_ptrtype(NULL, vo);
    struct vo initial_values = {
        .opts = opts,
        .x11 = x11,
        .key_fifo = key_fifo,
        .input_ctx = input_ctx,
        .event_fd = -1,
        .registered_fd = -1,
    };
    // first try the preferred drivers, with their optional subdevice param:
    if (vo_list && vo_list[0])
        while (vo_list[0][0]) {
            char *name = strdup(vo_list[0]);
            vo_subdevice = strchr(name,':');
            if (!strcmp(name, "pgm"))
                mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "The pgm video output driver has been replaced by -vo pnm:pgmyuv.\n");
            if (!strcmp(name, "md5"))
                mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "The md5 video output driver has been replaced by -vo md5sum.\n");
            if (vo_subdevice) {
                vo_subdevice[0] = 0;
                ++vo_subdevice;
            }
            for (i = 0; video_out_drivers[i]; i++) {
                const struct vo_driver *video_driver = video_out_drivers[i];
                const vo_info_t *info = video_driver->info;
                if (!strcmp(info->short_name, name)) {
                    // name matches, try it
                    *vo = initial_values;
                    vo->driver = video_driver;
                    if (!vo_preinit(vo, vo_subdevice)) {
                        free(name);
                        return vo; // success!
                    }
                    talloc_free_children(vo);
		}
	    }
            // continue...
            free(name);
            ++vo_list;
            if (!(vo_list[0]))
                return NULL; // do NOT fallback to others
	}
    // now try the rest...
    vo_subdevice = NULL;
    for (i = 0; video_out_drivers[i]; i++) {
        const struct vo_driver *video_driver = video_out_drivers[i];
        *vo = initial_values;
        vo->driver = video_driver;
        if (!vo_preinit(vo, vo_subdevice))
            return vo; // success!
        talloc_free_children(vo);
    }
    free(vo);
    return NULL;
}

static int event_fd_callback(void *ctx, int fd)
{
    struct vo *vo = ctx;
    vo_check_events(vo);
    return MP_INPUT_NOTHING;
}

int vo_config(struct vo *vo, uint32_t width, uint32_t height,
                     uint32_t d_width, uint32_t d_height, uint32_t flags,
                     char *title, uint32_t format)
{
    struct MPOpts *opts = vo->opts;
    panscan_init(vo);
    aspect_save_orig(vo, width, height);
    aspect_save_prescale(vo, d_width, d_height);

    if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
        aspect(vo, &d_width, &d_height, A_NOZOOM);
        vo->dx = (int)(opts->vo_screenwidth - d_width) / 2;
        vo->dy = (int)(opts->vo_screenheight - d_height) / 2;
        geometry(&vo->dx, &vo->dy, &d_width, &d_height,
                 opts->vo_screenwidth, opts->vo_screenheight);
        geometry_xy_changed |= xinerama_screen >= 0;
        vo->dx += xinerama_x;
        vo->dy += xinerama_y;
        vo->dwidth = d_width;
        vo->dheight = d_height;
    }

    int ret = vo->driver->config(vo, width, height, d_width, d_height, flags,
                                 title, format);
    vo->config_ok = (ret == 0);
    vo->config_count += vo->config_ok;
    if (vo->registered_fd == -1 && vo->event_fd != -1 && vo->config_ok) {
        mp_input_add_key_fd(vo->input_ctx, vo->event_fd, 1, event_fd_callback,
                            NULL, vo);
        vo->registered_fd = vo->event_fd;
    }
    return ret;
}

/**
 * \brief lookup an integer in a table, table must have 0 as the last key
 * \param key key to search for
 * \result translation corresponding to key or "to" value of last mapping
 *         if not found.
 */
int lookup_keymap_table(const struct mp_keymap *map, int key) {
  while (map->from && map->from != key) map++;
  return map->to;
}

/**
 * \brief helper function for the kind of panscan-scaling that needs a source
 *        and destination rectangle like Direct3D and VDPAU
 */
static void src_dst_split_scaling(int src_size, int dst_size, int scaled_src_size,
                                  int *src_start, int *src_end, int *dst_start, int *dst_end) {
  if (scaled_src_size > dst_size) {
    int border = src_size * (scaled_src_size - dst_size) / scaled_src_size;
    // round to a multiple of 2, this is at least needed for vo_direct3d and ATI cards
    border = (border / 2 + 1) & ~1;
    *src_start = border;
    *src_end   = src_size - border;
    *dst_start = 0;
    *dst_end   = dst_size;
  } else {
    *src_start = 0;
    *src_end   = src_size;
    *dst_start = (dst_size - scaled_src_size) / 2;
    *dst_end   = *dst_start + scaled_src_size;
  }
}

/**
 * Calculate the appropriate source and destination rectangle to
 * get a correctly scaled picture, including pan-scan.
 * Can be extended to take future cropping support into account.
 *
 * \param crop specifies the cropping border size in the left, right, top and bottom members, may be NULL
 * \param borders the border values as e.g. EOSD (ASS) and properly placed DVD highlight support requires,
 *                may be NULL and only left and top are currently valid.
 */
void calc_src_dst_rects(struct vo *vo, int src_width, int src_height,
                        struct vo_rect *src, struct vo_rect *dst,
                        struct vo_rect *borders, const struct vo_rect *crop)
{
  static const struct vo_rect no_crop = {0, 0, 0, 0, 0, 0};
  int scaled_width  = 0;
  int scaled_height = 0;
  if (!crop) crop = &no_crop;
  src_width  -= crop->left + crop->right;
  src_height -= crop->top  + crop->bottom;
  if (src_width  < 2) src_width  = 2;
  if (src_height < 2) src_height = 2;
  dst->left = 0; dst->right  = vo->dwidth;
  dst->top  = 0; dst->bottom = vo->dheight;
  src->left = 0; src->right  = src_width;
  src->top  = 0; src->bottom = src_height;
  if (borders) {
    borders->left = 0; borders->top = 0;
  }
  if (aspect_scaling()) {
    aspect(vo, &scaled_width, &scaled_height, A_WINZOOM);
    panscan_calc_windowed(vo);
    scaled_width  += vo->panscan_x;
    scaled_height += vo->panscan_y;
    if (borders) {
      borders->left = (vo->dwidth  - scaled_width ) / 2;
      borders->top  = (vo->dheight - scaled_height) / 2;
    }
    src_dst_split_scaling(src_width, vo->dwidth, scaled_width,
                          &src->left, &src->right, &dst->left, &dst->right);
    src_dst_split_scaling(src_height, vo->dheight, scaled_height,
                          &src->top, &src->bottom, &dst->top, &dst->bottom);
  }
  src->left += crop->left; src->right  += crop->left;
  src->top  += crop->top;  src->bottom += crop->top;
  src->width  = src->right  - src->left;
  src->height = src->bottom - src->top;
  dst->width  = dst->right  - dst->left;
  dst->height = dst->bottom - dst->top;
}

/**
 * Generates a mouse movement message if those are enable and sends it
 * to the "main" MPlayer.
 *
 * \param posx new x position of mouse
 * \param posy new y position of mouse
 */
void vo_mouse_movement(struct vo *vo, int posx, int posy)
{
  char cmd_str[40];
  if (!enable_mouse_movements)
    return;
  snprintf(cmd_str, sizeof(cmd_str), "set_mouse_pos %i %i", posx, posy);
  mp_input_queue_cmd(vo->input_ctx, mp_input_parse_cmd(cmd_str));
}
Exemplo n.º 10
0
/** Create and insert a cache entry
 *
 * @return
 *	- #RLM_MODULE_OK on success.
 *	- #RLM_MODULE_UPDATED if we merged the cache entry.
 *	- #RLM_MODULE_FAIL on failure.
 */
static rlm_rcode_t cache_insert(rlm_cache_t const *inst, REQUEST *request, rlm_cache_handle_t **handle,
				uint8_t const *key, size_t key_len, int ttl)
{
	vp_map_t		const *map;
	vp_map_t		**last, *c_map;

	VALUE_PAIR		*vp;
	bool			merge = false;
	rlm_cache_entry_t	*c;
	size_t			len;

	TALLOC_CTX		*pool;

	if ((inst->config.max_entries > 0) && inst->driver->count &&
	    (inst->driver->count(&inst->config, inst->driver_inst->data, request, handle) > inst->config.max_entries)) {
		RWDEBUG("Cache is full: %d entries", inst->config.max_entries);
		return RLM_MODULE_FAIL;
	}

	c = cache_alloc(inst, request);
	if (!c) return RLM_MODULE_FAIL;

	c->key = talloc_memdup(c, key, key_len);
	c->key_len = key_len;
	c->created = c->expires = request->packet->timestamp.tv_sec;
	c->expires += ttl;

	last = &c->maps;

	RDEBUG2("Creating new cache entry");

	/*
	 *	Alloc a pool so we don't have excessive allocs when
	 *	gathering VALUE_PAIRs to cache.
	 */
	pool = talloc_pool(NULL, 2048);
	for (map = inst->maps; map != NULL; map = map->next) {
		VALUE_PAIR	*to_cache = NULL;
		fr_cursor_t	cursor;

		rad_assert(map->lhs && map->rhs);

		/*
		 *	Calling map_to_vp gives us exactly the same result,
		 *	as if this were an update section.
		 */
		if (map_to_vp(pool, &to_cache, request, map, NULL) < 0) {
			RDEBUG2("Skipping %s", map->rhs->name);
			continue;
		}

		for (vp = fr_cursor_init(&cursor, &to_cache);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			/*
			 *	Prevent people from accidentally caching
			 *	cache control attributes.
			 */
			if (map->rhs->type == TMPL_TYPE_LIST) switch (vp->da->attr) {
			case FR_CACHE_TTL:
			case FR_CACHE_STATUS_ONLY:
			case FR_CACHE_MERGE_NEW:
			case FR_CACHE_ENTRY_HITS:
				RDEBUG2("Skipping %s", vp->da->name);
				continue;

			default:
				break;
			}

			RINDENT();
			if (RDEBUG_ENABLED2) map_debug_log(request, map, vp);
			REXDENT();

			MEM(c_map = talloc_zero(c, vp_map_t));
			c_map->op = map->op;

			/*
			 *	Now we turn the VALUE_PAIRs into maps.
			 */
			switch (map->lhs->type) {
			/*
			 *	Attributes are easy, reuse the LHS, and create a new
			 *	RHS with the fr_value_box_t from the VALUE_PAIR.
			 */
			case TMPL_TYPE_ATTR:
				c_map->lhs = map->lhs;	/* lhs shouldn't be touched, so this is ok */
			do_rhs:
				MEM(c_map->rhs = tmpl_init(talloc(c_map, vp_tmpl_t),
							   TMPL_TYPE_DATA, map->rhs->name, map->rhs->len, T_BARE_WORD));
				if (fr_value_box_copy(c_map->rhs, &c_map->rhs->tmpl_value, &vp->data) < 0) {
					REDEBUG("Failed copying attribute value");
				error:
					talloc_free(pool);
					talloc_free(c);
					return RLM_MODULE_FAIL;
				}
				c_map->rhs->tmpl_value_type = vp->vp_type;
				if (vp->vp_type == FR_TYPE_STRING) {
					c_map->rhs->quote = is_printable(vp->vp_strvalue, vp->vp_length) ?
						T_SINGLE_QUOTED_STRING : T_DOUBLE_QUOTED_STRING;
				}
				break;

			/*
			 *	Lists are weird... We need to fudge a new LHS template,
			 *	which is a combination of the LHS list and the attribute.
			 */
			case TMPL_TYPE_LIST:
			{
				char attr[256];

				MEM(c_map->lhs = tmpl_init(talloc(c_map, vp_tmpl_t),
							   TMPL_TYPE_ATTR, map->lhs->name, map->lhs->len, T_BARE_WORD));
				c_map->lhs->tmpl_da = vp->da;
				if (vp->da->flags.is_unknown) { /* for tmpl_verify() */
					c_map->lhs->tmpl_unknown = fr_dict_unknown_acopy(c_map->lhs, vp->da);
					c_map->lhs->tmpl_da = c_map->lhs->tmpl_unknown;
				}

				c_map->lhs->tmpl_tag = vp->tag;
				c_map->lhs->tmpl_list = map->lhs->tmpl_list;
				c_map->lhs->tmpl_num = map->lhs->tmpl_num;
				c_map->lhs->tmpl_request = map->lhs->tmpl_request;

				/*
				 *	We need to rebuild the attribute name, to be the
				 *	one we copied from the source list.
				 */
				len = tmpl_snprint(attr, sizeof(attr), c_map->lhs);
				if (is_truncated(len, sizeof(attr))) {
					REDEBUG("Serialized attribute too long.  Must be < "
						STRINGIFY(sizeof(attr)) " bytes, got %zu bytes", len);
					goto error;
				}
				c_map->lhs->len = len;
				c_map->lhs->name = talloc_typed_strdup(c_map->lhs, attr);
			}
				goto do_rhs;

			default:
				rad_assert(0);
			}
			*last = c_map;
			last = &(*last)->next;
		}
		talloc_free_children(pool); /* reset pool state */
	}
	talloc_free(pool);

	/*
	 *	Check to see if we need to merge the entry into the request
	 */
	vp = fr_pair_find_by_da(request->control, attr_cache_merge_new, TAG_ANY);
	if (vp && vp->vp_bool) merge = true;

	if (merge) cache_merge(inst, request, c);

	for (;;) {
		cache_status_t ret;

		ret = inst->driver->insert(&inst->config, inst->driver_inst->data, request, *handle, c);
		switch (ret) {
		case CACHE_RECONNECT:
			if (cache_reconnect(handle, inst, request) == 0) continue;
			return RLM_MODULE_FAIL;

		case CACHE_OK:
			RDEBUG2("Committed entry, TTL %d seconds", ttl);
			cache_free(inst, &c);
			return merge ? RLM_MODULE_UPDATED :
				       RLM_MODULE_OK;

		default:
			talloc_free(c);	/* Failed insertion - use talloc_free not the driver free */
			return RLM_MODULE_FAIL;
		}
	}
}
Exemplo n.º 11
0
static void print_notify_send_messages_to_printer(struct messaging_context *msg_ctx,
						  const char *printer,
						  unsigned int timeout)
{
	char *buf;
	struct notify_queue *pq, *pq_next;
	size_t msg_count = 0, offset = 0;
	size_t num_pids = 0;
	size_t i;
	pid_t *pid_list = NULL;
	struct timeval end_time = timeval_zero();

	/* Count the space needed to send the messages. */
	for (pq = notify_queue_head; pq; pq = pq->next) {
		if (strequal(printer, pq->msg->printer)) {
			if (!flatten_message(pq)) {
				DEBUG(0,("print_notify_send_messages: Out of memory\n"));
				talloc_free_children(send_ctx);
				num_messages = 0;
				return;
			}
			offset += (pq->buflen + 4);
			msg_count++;
		}	
	}
	offset += 4; /* For count. */

	buf = (char *)TALLOC(send_ctx, offset);
	if (!buf) {
		DEBUG(0,("print_notify_send_messages: Out of memory\n"));
		talloc_free_children(send_ctx);
		num_messages = 0;
		return;
	}

	offset = 0;
	SIVAL(buf,offset,msg_count);
	offset += 4;
	for (pq = notify_queue_head; pq; pq = pq_next) {
		pq_next = pq->next;

		if (strequal(printer, pq->msg->printer)) {
			SIVAL(buf,offset,pq->buflen);
			offset += 4;
			memcpy(buf + offset, pq->buf, pq->buflen);
			offset += pq->buflen;

			/* Remove from list. */
			DLIST_REMOVE(notify_queue_head, pq);
		}
	}

	DEBUG(5, ("print_notify_send_messages_to_printer: sending %lu print notify message%s to printer %s\n", 
		  (unsigned long)msg_count, msg_count != 1 ? "s" : "", printer));

	/*
	 * Get the list of PID's to send to.
	 */

	if (!print_notify_pid_list(printer, send_ctx, &num_pids, &pid_list))
		return;

	if (timeout != 0) {
		end_time = timeval_current_ofs(timeout, 0);
	}

	for (i = 0; i < num_pids; i++) {
		messaging_send_buf(msg_ctx,
				   pid_to_procid(pid_list[i]),
				   MSG_PRINTER_NOTIFY2 | MSG_FLAG_LOWPRIORITY,
				   (uint8 *)buf, offset);

		if ((timeout != 0) && timeval_expired(&end_time)) {
			break;
		}
	}
}
Exemplo n.º 12
0
int m_config_parse(m_config_t *config, const char *location, bstr data,
                   char *initial_section, int flags)
{
    m_profile_t *profile = m_config_add_profile(config, initial_section);
    void *tmp = talloc_new(NULL);
    int line_no = 0;
    int errors = 0;

    bstr_eatstart0(&data, "\xEF\xBB\xBF"); // skip BOM

    while (data.len) {
        talloc_free_children(tmp);
        bool ok = false;

        line_no++;
        char loc[512];
        snprintf(loc, sizeof(loc), "%s:%d:", location, line_no);

        bstr line = bstr_strip_linebreaks(bstr_getline(data, &data));
        if (!skip_ws(&line))
            continue;

        // Profile declaration
        if (bstr_eatstart0(&line, "[")) {
            bstr profilename;
            if (!bstr_split_tok(line, "]", &profilename, &line)) {
                MP_ERR(config, "%s missing closing ]\n", loc);
                goto error;
            }
            if (skip_ws(&line)) {
                MP_ERR(config, "%s unparseable extra characters: '%.*s'\n",
                       loc, BSTR_P(line));
                goto error;
            }
            profile = m_config_add_profile(config, bstrto0(tmp, profilename));
            continue;
        }

        bstr_eatstart0(&line, "--");

        bstr option = line;
        while (line.len && (mp_isalnum(line.start[0]) || line.start[0] == '_' ||
                            line.start[0] == '-'))
            line = bstr_cut(line, 1);
        option.len = option.len - line.len;
        skip_ws(&line);

        bstr value = {0};
        if (bstr_eatstart0(&line, "=")) {
            skip_ws(&line);
            if (line.len && (line.start[0] == '"' || line.start[0] == '\'')) {
                // Simple quoting, like "value"
                char term[2] = {line.start[0], 0};
                line = bstr_cut(line, 1);
                if (!bstr_split_tok(line, term, &value, &line)) {
                    MP_ERR(config, "%s unterminated quote\n", loc);
                    goto error;
                }
            } else if (bstr_eatstart0(&line, "%")) {
                // Quoting with length, like %5%value
                bstr rest;
                long long len = bstrtoll(line, &rest, 10);
                if (rest.len == line.len || !bstr_eatstart0(&rest, "%") ||
                    len > rest.len)
                {
                    MP_ERR(config, "%s fixed-length quoting expected - put "
                           "\"quotes\" around the option value if you did not "
                           "intend to use this, but your option value starts "
                           "with '%%'\n", loc);
                    goto error;
                }
                value = bstr_splice(rest, 0, len);
                line = bstr_cut(rest, len);
            } else {
                // No quoting; take everything until the comment or end of line
                int end = bstrchr(line, '#');
                value = bstr_strip(end < 0 ? line : bstr_splice(line, 0, end));
                line.len = 0;
            }
        }
        if (skip_ws(&line)) {
            MP_ERR(config, "%s unparseable extra characters: '%.*s'\n",
                   loc, BSTR_P(line));
            goto error;
        }

        int res;
        if (profile) {
            if (bstr_equals0(option, "profile-desc")) {
                m_profile_set_desc(profile, value);
                res = 0;
            } else {
                res = m_config_set_profile_option(config, profile, option, value);
            }
        } else {
            res = m_config_set_option_ext(config, option, value, flags);
        }
        if (res < 0) {
            MP_ERR(config, "%s setting option %.*s='%.*s' failed.\n",
                   loc, BSTR_P(option), BSTR_P(value));
            goto error;
        }

        ok = true;
    error:
        if (!ok)
            errors++;
        if (errors > 16) {
            MP_ERR(config, "%s: too many errors, stopping.\n", location);
            break;
        }
    }

    talloc_free(tmp);
    return 1;
}
Exemplo n.º 13
0
errno_t
nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
                        struct nss_cmd_ctx *cmd_ctx,
                        struct sss_packet *packet,
                        struct cache_req_result *result)
{
    TALLOC_CTX *tmp_ctx;
    struct ldb_message *msg;
    struct sized_string pwfield;
    struct sized_string *name;
    struct sized_string gecos;
    struct sized_string homedir;
    struct sized_string shell;
    uint32_t gid;
    uint32_t uid;
    uint32_t num_results;
    size_t rp;
    size_t body_len;
    uint8_t *body;
    int i;
    errno_t ret;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    /* First two fields (length and reserved), filled up later. */
    ret = sss_packet_grow(packet, 2 * sizeof(uint32_t));
    if (ret != EOK) {
        return ret;
    }

    rp = 2 * sizeof(uint32_t);

    num_results = 0;
    for (i = 0; i < result->count; i++) {
        talloc_free_children(tmp_ctx);
        msg = result->msgs[i];

        /* Password field content. */
        to_sized_string(&pwfield, nss_get_pwfield(nss_ctx, result->domain));

        ret = nss_get_pwent(tmp_ctx, nss_ctx, result->domain, msg, &uid, &gid,
                            &name, &gecos, &homedir, &shell);
        if (ret != EOK) {
            continue;
        }

        /* Adjust packet size: uid, gid + string fields. */

        ret = sss_packet_grow(packet, 2 * sizeof(uint32_t)
                                          + name->len + gecos.len + homedir.len
                                          + shell.len + pwfield.len);
        if (ret != EOK) {
            goto done;
        }

        sss_packet_get_body(packet, &body, &body_len);

        /* Fill packet. */

        SAFEALIGN_SET_UINT32(&body[rp], uid, &rp);
        SAFEALIGN_SET_UINT32(&body[rp], gid, &rp);
        SAFEALIGN_SET_STRING(&body[rp], name->str, name->len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], pwfield.str, pwfield.len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], gecos.str, gecos.len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], homedir.str, homedir.len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], shell.str, shell.len, &rp);

        num_results++;

        /* Do not store entry in memory cache during enumeration or when
         * requested. */
        if (!cmd_ctx->enumeration
                && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
            ret = sss_mmap_cache_pw_store(&nss_ctx->pwd_mc_ctx, name, &pwfield,
                                          uid, gid, &gecos, &homedir, &shell);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE,
                      "Failed to store user %s (%s) in mmap cache [%d]: %s!\n",
                      name->str, result->domain->name, ret, sss_strerror(ret));
            }
        }
    }

    ret = EOK;

done:
    talloc_free(tmp_ctx);

    if (ret != EOK) {
        sss_packet_set_size(packet, 0);
        return ret;
    }

    sss_packet_get_body(packet, &body, &body_len);
    SAFEALIGN_COPY_UINT32(body, &num_results, NULL);
    SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); /* reserved */

    return EOK;
}
Exemplo n.º 14
0
/*
  measure the speed of talloc versus malloc
*/
static bool test_speed(void)
{
	void *ctx = talloc_new(NULL);
	unsigned count;
	const int loop = 1000;
	int i;
	struct timeval tv;

	printf("test: speed\n# TALLOC VS MALLOC SPEED\n");

	tv = timeval_current();
	count = 0;
	do {
		void *p1, *p2, *p3;
		for (i=0;i<loop;i++) {
			p1 = talloc_size(ctx, loop % 100);
			p2 = talloc_strdup(p1, "foo bar");
			p3 = talloc_size(p1, 300);
			talloc_free(p1);
		}
		count += 3 * loop;
	} while (timeval_elapsed(&tv) < 5.0);

	fprintf(stderr, "talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));

	talloc_free(ctx);

	ctx = talloc_pool(NULL, 1024);

	tv = timeval_current();
	count = 0;
	do {
		void *p1, *p2, *p3;
		for (i=0;i<loop;i++) {
			p1 = talloc_size(ctx, loop % 100);
			p2 = talloc_strdup(p1, "foo bar");
			p3 = talloc_size(p1, 300);
			talloc_free_children(ctx);
		}
		count += 3 * loop;
	} while (timeval_elapsed(&tv) < 5.0);

	talloc_free(ctx);

	fprintf(stderr, "talloc_pool: %.0f ops/sec\n", count/timeval_elapsed(&tv));

	tv = timeval_current();
	count = 0;
	do {
		void *p1, *p2, *p3;
		for (i=0;i<loop;i++) {
			p1 = malloc(loop % 100);
			p2 = strdup("foo bar");
			p3 = malloc(300);
			free(p1);
			free(p2);
			free(p3);
		}
		count += 3 * loop;
	} while (timeval_elapsed(&tv) < 5.0);
	fprintf(stderr, "malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));

	printf("success: speed\n");

	return true;
}
Exemplo n.º 15
0
/** Create and insert a cache entry.
 *
 * @return
 *	- #RLM_MODULE_OK on success.
 *	- #RLM_MODULE_UPDATED if we merged the cache entry.
 *	- #RLM_MODULE_FAIL on failure.
 */
static rlm_rcode_t cache_insert(rlm_cache_t *inst, REQUEST *request, rlm_cache_handle_t **handle,
				char const *key, int ttl)
{
	vp_map_t		const *map;
	vp_map_t		**last, *c_map;

	VALUE_PAIR		*vp;
	bool			merge = false;
	rlm_cache_entry_t	*c;

	TALLOC_CTX		*pool;

	if ((inst->max_entries > 0) && inst->module->count &&
	    (inst->module->count(inst, request, handle) > inst->max_entries)) {
		RWDEBUG("Cache is full: %d entries", inst->max_entries);
		return RLM_MODULE_FAIL;
	}

	c = cache_alloc(inst, request);
	if (!c) return RLM_MODULE_FAIL;

	c->key = talloc_typed_strdup(c, key);
	c->created = c->expires = request->timestamp;
	c->expires += ttl;

	last = &c->maps;

	RDEBUG("Creating new cache entry");

	/*
	 *	Alloc a pool so we don't have excessive mallocs when
	 *	gathering VALUE_PAIRs to cache.
	 */
	pool = talloc_pool(NULL, 1024);
	for (map = inst->maps; map != NULL; map = map->next) {
		VALUE_PAIR	*to_cache = NULL;
		vp_cursor_t	cursor;

		rad_assert(map->lhs && map->rhs);

		/*
		 *	Calling map_to_vp gives us exactly the same result,
		 *	as if this were an update section.
		 */
		if (map_to_vp(pool, &to_cache, request, map, NULL) < 0) {
			RDEBUG("Skipping %s", map->rhs->name);
			continue;
		}

		for (vp = fr_cursor_init(&cursor, &to_cache);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			/*
			 *	Prevent people from accidentally caching
			 *	cache control attributes.
			 */
			if (map->rhs->type == TMPL_TYPE_LIST) switch (vp->da->attr) {
			case PW_CACHE_TTL:
			case PW_CACHE_STATUS_ONLY:
			case PW_CACHE_READ_ONLY:
			case PW_CACHE_MERGE:
			case PW_CACHE_ENTRY_HITS:
				RDEBUG2("Skipping %s", vp->da->name);
				continue;

			default:
				break;
			}

			RINDENT();
			if (RDEBUG_ENABLED2) map_debug_log(request, map, vp);
			REXDENT();

			MEM(c_map = talloc_zero(c, vp_map_t));
			c_map->op = map->op;

			/*
			 *	Now we turn the VALUE_PAIRs into maps.
			 */
			switch (map->lhs->type) {
			/*
			 *	Attributes are easy, reuse the LHS, and create a new
			 *	RHS with the value_data_t from the VALUE_PAIR.
			 */
			case TMPL_TYPE_ATTR:
				c_map->lhs = map->lhs;	/* lhs shouldn't be touched, so this is ok */
			do_rhs:
				MEM(c_map->rhs = tmpl_init(talloc(c_map, vp_tmpl_t),
							   TMPL_TYPE_DATA, map->rhs->name, map->rhs->len));
				if (value_data_copy(c_map->rhs, &c_map->rhs->tmpl_data_value,
						    vp->da->type, &vp->data) < 0) {
					REDEBUG("Failed copying attribute value");
					talloc_free(pool);
					talloc_free(c);
					return RLM_MODULE_FAIL;
				}
				c_map->rhs->tmpl_data_type = vp->da->type;
				break;

			/*
			 *	Lists are weird... We need to fudge a new LHS template,
			 *	which is a combination of the LHS list and the attribute.
			 */
			case TMPL_TYPE_LIST:
			{
				char attr[256];

				MEM(c_map->lhs = tmpl_init(talloc(c_map, vp_tmpl_t),
							   TMPL_TYPE_ATTR, map->lhs->name, map->lhs->len));
				c_map->lhs->tmpl_da = vp->da;
				c_map->lhs->tmpl_tag = vp->tag;
				c_map->lhs->tmpl_list = map->lhs->tmpl_list;
				c_map->lhs->tmpl_num = map->lhs->tmpl_num;
				c_map->lhs->tmpl_request = map->lhs->tmpl_request;

				/*
				 *	We need to rebuild the attribute name, to be the
				 *	one we copied from the source list.
				 */
				c_map->lhs->len = tmpl_prints(attr, sizeof(attr), c_map->lhs, NULL);
				c_map->lhs->name = talloc_strdup(map->lhs, attr);
			}
				goto do_rhs;

			default:
				rad_assert(0);
			}
			*last = c_map;
			last = &(*last)->next;
		}
		talloc_free_children(pool); /* reset pool state */
	}
	talloc_free(pool);

	/*
	 *	Check to see if we need to merge the entry into the request
	 */
	vp = pairfind(request->config, PW_CACHE_MERGE, 0, TAG_ANY);
	if (vp && (vp->vp_integer > 0)) merge = true;

	if (merge) cache_merge(inst, request, c);

	for (;;) {
		cache_status_t ret;

		ret = inst->module->insert(inst, request, handle, c);
		switch (ret) {
		case CACHE_RECONNECT:
			if (cache_reconnect(inst, request, handle) == 0) continue;
			return RLM_MODULE_FAIL;

		case CACHE_OK:
			RDEBUG("Commited entry, TTL %d seconds", ttl);
			cache_free(inst, &c);
			return merge ? RLM_MODULE_UPDATED :
				       RLM_MODULE_OK;

		default:
			talloc_free(c);	/* Failed insertion - use talloc_free not the driver free */
			return RLM_MODULE_FAIL;
		}
	}
}