Esempio n. 1
0
bool
conf_set_value_in_file(const char *path, const char *key, const char *value,
                       char **errmsg)
{
	FILE *infile, *outfile;
	char *outpath;
	char buf[10000];
	bool found;
	const struct conf_item *item;

	item = find_conf(key);
	if (!item) {
		*errmsg = format("unknown configuration option \"%s\"", key);
		return false;
	}

	infile = fopen(path, "r");
	if (!infile) {
		*errmsg = format("%s: %s", path, strerror(errno));
		return false;
	}

	outpath = format("%s.tmp.%s", path, tmp_string());
	outfile = fopen(outpath, "w");
	if (!outfile) {
		*errmsg = format("%s: %s", outpath, strerror(errno));
		free(outpath);
		fclose(infile);
		return false;
	}

	found = false;
	while (fgets(buf, sizeof(buf), infile)) {
		char *errmsg2, *key2, *value2;
		bool ok;
		ok = parse_line(buf, &key2, &value2, &errmsg2);
		if (ok && key2 && str_eq(key2, key)) {
			found = true;
			fprintf(outfile, "%s = %s\n", key, value);
		} else {
			fputs(buf, outfile);
		}
		free(key2);
		free(value2);
	}

	if (!found) {
		fprintf(outfile, "%s = %s\n", key, value);
	}

	fclose(infile);
	fclose(outfile);
	if (x_rename(outpath, path) != 0) {
		*errmsg = format("rename %s to %s: %s", outpath, path, strerror(errno));
		return false;
	}
	free(outpath);

	return true;
}
Esempio n. 2
0
static bool
handle_conf_setting(struct conf *conf, const char *key, const char *value,
                    char **errmsg, bool from_env_variable, bool negate_boolean,
                    const char *origin)
{
	const struct conf_item *item;

	item = find_conf(key);
	if (!item) {
		*errmsg = format("unknown configuration option \"%s\"", key);
		return false;
	}

	if (from_env_variable && item->parser == parse_bool) {
		/*
		 * Special rule for boolean settings from the environment: any value means
		 * true.
		 */
		bool *value = (bool *)((char *)conf + item->offset);
		*value = !negate_boolean;
		goto out;
	}

	if (!item->parser(value, (char *)conf + item->offset, errmsg)) {
		return false;
	}
	if (item->verifier && !item->verifier((char *)conf + item->offset, errmsg)) {
		return false;
	}

out:
	conf->item_origins[item->number] = origin;
	return true;
}
Esempio n. 3
0
/*--- count_exec: The MeetmeCount application */
static int count_exec(struct ast_channel *chan, void *data)
{
	struct localuser *u;
	int res = 0;
	struct ast_conference *conf;
	int count;
	char *confnum, *localdata;
	char val[80] = "0"; 

	if (!data || ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "MeetMeCount requires an argument (conference number)\n");
		return -1;
	}
	localdata = ast_strdupa(data);
	LOCAL_USER_ADD(u);
	confnum = strsep(&localdata,"|");       
	conf = find_conf(chan, confnum, 0, 0, NULL);
	if (conf)
		count = conf->users;
	else
		count = 0;

	if (localdata && !ast_strlen_zero(localdata)){
		/* have var so load it and exit */
		snprintf(val,sizeof(val), "%i",count);
		pbx_builtin_setvar_helper(chan, localdata,val);
	} else {
		if (chan->_state != AST_STATE_UP)
			ast_answer(chan);
		res = ast_say_number(chan, count, "", chan->language, (char *) NULL); /* Needs gender */
	}
	LOCAL_USER_REMOVE(u);
	return res;
}
Esempio n. 4
0
struct cw_conference* start_conference( struct cw_conf_member* member ) 
{
    struct cw_conference* conf = NULL ;

    // check input
    if ( member == NULL )
    {
    	cw_log( LOG_WARNING, "unable to handle null member\n" ) ;
    	return NULL ;
    }

    // look for an existing conference
    cw_log( CW_CONF_DEBUG, "attempting to find requested conference\n" ) ;

    // acquire mutex
    cw_mutex_lock( &start_stop_conf_lock ) ;

    conf = find_conf( member->id ) ;
	
    // unable to find an existing conference, try to create one
    if ( conf == NULL )
    {
	// create a new conference
	cw_log( CW_CONF_DEBUG, "attempting to create requested conference\n" ) ;
	
	// create the new conference with one member
	conf = create_conf( member->id, member ) ;

	// return an error if create_conf() failed
	if ( conf == NULL ) 
	{
	    cw_log( LOG_ERROR, "unable to find or create requested conference\n" ) ;
	    cw_mutex_unlock( &start_stop_conf_lock ) ;
	    return NULL ;
	}
    }
    else
    {
	// existing conference found, add new member to the conference
	// once we call add_member(), this thread
	// is responsible for calling delete_member()
	//
	add_member( conf, member) ;
    }	

    // release mutex
    cw_mutex_unlock( &start_stop_conf_lock ) ;
    
    return conf ;
}
Esempio n. 5
0
bool
conf_print_items(struct conf *conf,
                 void (*printer)(const char *descr, const char *origin,
                                 void *context),
                 void *context)
{
	char *s = x_strdup("");
	char *s2;

	reformat(&s, "base_dir = %s", conf->base_dir);
	printer(s, conf->item_origins[find_conf("base_dir")->number], context);

	reformat(&s, "cache_dir = %s", conf->cache_dir);
	printer(s, conf->item_origins[find_conf("cache_dir")->number], context);

	reformat(&s, "cache_dir_levels = %u", conf->cache_dir_levels);
	printer(s, conf->item_origins[find_conf("cache_dir_levels")->number],
	        context);

	reformat(&s, "compiler = %s", conf->compiler);
	printer(s, conf->item_origins[find_conf("compiler")->number], context);

	reformat(&s, "compiler_check = %s", conf->compiler_check);
	printer(s, conf->item_origins[find_conf("compiler_check")->number], context);

	reformat(&s, "compression = %s", conf->compression ? "true" : "false");
	printer(s, conf->item_origins[find_conf("compression")->number], context);

	reformat(&s, "compression_level = %u", conf->compression_level);
	printer(s, conf->item_origins[find_conf("compression_level")->number],
	        context);

	reformat(&s, "cpp_extension = %s", conf->cpp_extension);
	printer(s, conf->item_origins[find_conf("cpp_extension")->number], context);

	reformat(&s, "direct_mode = %s", conf->direct_mode ? "true" : "false");
	printer(s, conf->item_origins[find_conf("direct_mode")->number], context);

	reformat(&s, "disable = %s", conf->disable ? "true" : "false");
	printer(s, conf->item_origins[find_conf("disable")->number], context);

	reformat(&s, "extra_files_to_hash = %s", conf->extra_files_to_hash);
	printer(s, conf->item_origins[find_conf("extra_files_to_hash")->number],
	        context);

	reformat(&s, "hard_link = %s", conf->hard_link ? "true" : "false");
	printer(s, conf->item_origins[find_conf("hard_link")->number], context);

	reformat(&s, "hash_dir = %s", conf->hash_dir ? "true" : "false");
	printer(s, conf->item_origins[find_conf("hash_dir")->number], context);

	reformat(&s, "log_file = %s", conf->log_file);
	printer(s, conf->item_origins[find_conf("log_file")->number], context);

	reformat(&s, "max_files = %u", conf->max_files);
	printer(s, conf->item_origins[find_conf("max_files")->number], context);

	s2 = format_parsable_size_with_suffix(conf->max_size);
	reformat(&s, "max_size = %s", s2);
	printer(s, conf->item_origins[find_conf("max_size")->number], context);
	free(s2);

	reformat(&s, "path = %s", conf->path);
	printer(s, conf->item_origins[find_conf("path")->number], context);

	reformat(&s, "prefix_command = %s", conf->prefix_command);
	printer(s, conf->item_origins[find_conf("prefix_command")->number], context);

	reformat(&s, "read_only = %s", conf->read_only ? "true" : "false");
	printer(s, conf->item_origins[find_conf("read_only")->number], context);

	reformat(&s, "recache = %s", conf->recache ? "true" : "false");
	printer(s, conf->item_origins[find_conf("recache")->number], context);

	reformat(&s, "run_second_cpp = %s", conf->run_second_cpp ? "true" : "false");
	printer(s, conf->item_origins[find_conf("run_second_cpp")->number], context);

	reformat(&s, "sloppiness = ");
	if (conf->sloppiness & SLOPPY_FILE_MACRO) {
		reformat(&s, "%sfile_macro, ", s);
	}
	if (conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME) {
		reformat(&s, "%sinclude_file_mtime, ", s);
	}
	if (conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME) {
		reformat(&s, "%sinclude_file_ctime, ", s);
	}
	if (conf->sloppiness & SLOPPY_TIME_MACROS) {
		reformat(&s, "%stime_macros, ", s);
	}
	if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
		reformat(&s, "%sfile_stat_matches, ", s);
	}
	if (conf->sloppiness) {
		/* Strip last ", ". */
		s[strlen(s) - 2] = '\0';
	}
	printer(s, conf->item_origins[find_conf("sloppiness")->number], context);

	reformat(&s, "stats = %s", conf->stats ? "true" : "false");
	printer(s, conf->item_origins[find_conf("stats")->number], context);

	reformat(&s, "temporary_dir = %s", conf->temporary_dir);
	printer(s, conf->item_origins[find_conf("temporary_dir")->number], context);

	if (conf->umask == UINT_MAX) {
		reformat(&s, "umask = ");
	} else {
		reformat(&s, "umask = %03o", conf->umask);
	}
	printer(s, conf->item_origins[find_conf("umask")->number], context);

	reformat(&s, "unify = %s", conf->unify ? "true" : "false");
	printer(s, conf->item_origins[find_conf("unify")->number], context);

	free(s);
	return true;
}
Esempio n. 6
0
/*--- conf_exec: The meetme() application */
static int conf_exec(struct ast_channel *chan, void *data)
{
	int res=-1;
	struct localuser *u;
	char confno[AST_MAX_EXTENSION] = "";
	int allowretry = 0;
	int retrycnt = 0;
	struct ast_conference *cnf;
	int confflags = 0;
	int dynamic = 0;
	int empty = 0, empty_no_pin = 0;
	char *notdata, *info, *inflags = NULL, *inpin = NULL, the_pin[AST_MAX_EXTENSION] = "";

	if (!data || ast_strlen_zero(data)) {
		allowretry = 1;
		notdata = "";
	} else {
		notdata = data;
	}
	LOCAL_USER_ADD(u);
	if (chan->_state != AST_STATE_UP)
		ast_answer(chan);

	info = ast_strdupa((char *)notdata);

	if (info) {
		char *tmp = strsep(&info, "|");
		strncpy(confno, tmp, sizeof(confno) - 1);
		if (ast_strlen_zero(confno)) {
			allowretry = 1;
		}
	}
	if (info)
		inflags = strsep(&info, "|");
	if (info)
		inpin = strsep(&info, "|");
	if (inpin)
		strncpy(the_pin, inpin, sizeof(the_pin) - 1);

	if (inflags) {
		if (strchr(inflags, 'a'))
			confflags |= CONFFLAG_ADMIN;
		if (strchr(inflags, 'm'))
			confflags |= CONFFLAG_MONITOR;
		if (strchr(inflags, 'p'))
			confflags |= CONFFLAG_POUNDEXIT;
		if (strchr(inflags, 's'))
			confflags |= CONFFLAG_STARMENU;
		if (strchr(inflags, 't'))
			confflags |= CONFFLAG_TALKER;
		if (strchr(inflags, 'q'))
			confflags |= CONFFLAG_QUIET;
		if (strchr(inflags, 'M'))
			confflags |= CONFFLAG_MOH;
		if (strchr(inflags, 'x'))
			confflags |= CONFFLAG_MARKEDEXIT;
		if (strchr(inflags, 'X'))
			confflags |= CONFFLAG_EXIT_CONTEXT;
		if (strchr(inflags, 'A'))
			confflags |= CONFFLAG_MARKEDUSER;
		if (strchr(inflags, 'b'))
			confflags |= CONFFLAG_AGI;
		if (strchr(inflags, 'w'))
			confflags |= CONFFLAG_WAITMARKED;
		if (strchr(inflags, 'd'))
			dynamic = 1;
		if (strchr(inflags, 'D')) {
			dynamic = 1;
			if (! inpin) {
				strncpy(the_pin, "q", sizeof(the_pin) - 1);
			}
		}
		if (strchr(inflags, 'e'))
			empty = 1;
		if (strchr(inflags, 'E')) {
			empty = 1;
			empty_no_pin = 1;
		}
	}

	do {
		if (retrycnt > 3)
			allowretry = 0;
		if (empty) {
			int i, map[1024];
			struct ast_config *cfg;
			struct ast_variable *var;
			int confno_int;

			memset(map, 0, sizeof(map));

			ast_mutex_lock(&conflock);
			cnf = confs;
			while (cnf) {
				if (sscanf(cnf->confno, "%d", &confno_int) == 1) {
					/* Disqualify in use conference */
					if (confno_int >= 0 && confno_int < 1024)
						map[confno_int]++;
				}
				cnf = cnf->next;
			}
			ast_mutex_unlock(&conflock);

			/* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */
			if ((empty_no_pin) || (!dynamic)) {
				cfg = ast_load("meetme.conf");
				if (cfg) {
					var = ast_variable_browse(cfg, "rooms");
					while(var) {
						if (!strcasecmp(var->name, "conf")) {
							char *stringp = ast_strdupa(var->value);
							if (stringp) {
								char *confno_tmp = strsep(&stringp, "|,");
								int found = 0;
								if (sscanf(confno_tmp, "%d", &confno_int) == 1) {
									if ((confno_int >= 0) && (confno_int < 1024)) {
										if (stringp && empty_no_pin) {
											map[confno_int]++;
										}
									}
								}
								if (! dynamic) {
									/* For static:  run through the list and see if this conference is empty */
									ast_mutex_lock(&conflock);
									cnf = confs;
									while (cnf) {
										if (!strcmp(confno_tmp, cnf->confno)) {
											/* The conference exists, therefore it's not empty */
											found = 1;
											break;
										}
										cnf = cnf->next;
									}
									ast_mutex_unlock(&conflock);
									if (!found) {
										/* At this point, we have a confno_tmp (static conference) that is empty */
										if ((empty_no_pin && ((!stringp) || (stringp && (stringp[0] == '\0')))) || (!empty_no_pin)) {
										/* Case 1:  empty_no_pin and pin is nonexistant (NULL)
										 * Case 2:  empty_no_pin and pin is blank (but not NULL)
										 * Case 3:  not empty_no_pin
										 */
											strncpy(confno, confno_tmp, sizeof(confno) - 1);
											break;
											/* XXX the map is not complete (but we do have a confno) */
										}
									}
								}
							} else {
								ast_log(LOG_ERROR, "Out of memory\n");
							}
						}
						var = var->next;
					}
					ast_destroy(cfg);
				}
			}
			/* Select first conference number not in use */
			if (ast_strlen_zero(confno) && dynamic) {
				for (i=0;i<1024;i++) {
					if (!map[i]) {
						snprintf(confno, sizeof(confno), "%d", i);
						break;
					}
				}
			}

			/* Not found? */
			if (ast_strlen_zero(confno)) {
				res = ast_streamfile(chan, "conf-noempty", chan->language);
				if (!res)
					ast_waitstream(chan, "");
			} else {
				if (sscanf(confno, "%d", &confno_int) == 1) {
					res = ast_streamfile(chan, "conf-enteringno", chan->language);
					if (!res) {
						ast_waitstream(chan, "");
						res = ast_say_digits(chan, confno_int, "", chan->language);
					}
				} else {
					ast_log(LOG_ERROR, "Could not scan confno '%s'\n", confno);
				}
			}
		}
		while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) {
			/* Prompt user for conference number */
			res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0);
			if (res < 0) {
				/* Don't try to validate when we catch an error */
				confno[0] = '\0';
				allowretry = 0;
				break;
			}
		}
		if (!ast_strlen_zero(confno)) {
			/* Check the validity of the conference */
			cnf = find_conf(chan, confno, 1, dynamic, the_pin);
			if (!cnf) {
				res = ast_streamfile(chan, "conf-invalid", chan->language);
				if (!res)
					ast_waitstream(chan, "");
				res = -1;
				if (allowretry)
					confno[0] = '\0';
			} else {
				if (!ast_strlen_zero(cnf->pin)) {
					char pin[AST_MAX_EXTENSION]="";
					int j;

					/* Allow the pin to be retried up to 3 times */
					for (j=0; j<3; j++) {
						if (*the_pin) {
							strncpy(pin, the_pin, sizeof(pin) - 1);
							res = 0;
						} else {
							/* Prompt user for pin if pin is required */
							res = ast_app_getdata(chan, "conf-getpin", pin + strlen(pin), sizeof(pin) - 1 - strlen(pin), 0);
						}
						if (res >= 0) {
							if (!strcasecmp(pin, cnf->pin)) {
								/* Pin correct */
								allowretry = 0;
								/* Run the conference */
								res = conf_run(chan, cnf, confflags);
								break;
							} else {
								/* Pin invalid */
								res = ast_streamfile(chan, "conf-invalidpin", chan->language);
								if (!res)
									ast_waitstream(chan, AST_DIGIT_ANY);
								if (res < 0)
									break;
								pin[0] = res;
								pin[1] = '\0';
								res = -1;
								if (allowretry)
									confno[0] = '\0';
							}
						} else {
							res = -1;
							allowretry = 0;
							break;
						}

						/* Don't retry pin with a static pin */
						if (*the_pin) {
							break;
						}
					}
				} else {
					/* No pin required */
					allowretry = 0;

					/* Run the conference */
					res = conf_run(chan, cnf, confflags);
				}
			}
		}
	} while (allowretry);
	/* Do the conference */
	LOCAL_USER_REMOVE(u);
	return res;
}
char *acf_nconfcount_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) {
	struct localuser *u;
	char *info, *options=NULL, *confno;
	char tmpbuf[16];

	*buf = '\0';
	
	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "NCONFCOUNT requires an argument (confno)\n");
		return buf;
	}

	LOCAL_USER_ACF_ADD(u);

	info = ast_strdupa(data);
	if (!info) {
		ast_log(LOG_ERROR, "Out of memory\n");
		LOCAL_USER_REMOVE(u);
		return buf;
	}
	
	confno = strsep(&info, "|");
	options = info;

	struct ast_conference *conf = find_conf(confno);
	if (conf == NULL) {
		LOCAL_USER_REMOVE(u);
		return buf;
	}

	if (ast_strlen_zero(options)) {
		/* Count All Members */
		snprintf(tmpbuf, 15, "%d", conf->membercount);
		ast_copy_string(buf, tmpbuf, len);
	} else {
		/* Count Certain types of Members */
		int i;
		short counter = 0;
		struct ast_conf_member *member_list = conf->memberlist;
		while (member_list) {

			for ( i = 0 ; i < strlen(options) ; ++i ) {
				switch (options[i]) {
				case 'M':
					if (member_list->type == MEMBERTYPE_MASTER) {
						++counter;
					}
					break ;
				case 'S':
					if (member_list->type == MEMBERTYPE_SPEAKER) {
						++counter;
					}
					break ;
				case 'L':
					if (member_list->type == MEMBERTYPE_LISTENER) {
						++counter;
					}
					break ;
				case 'T':
					if (member_list->type == MEMBERTYPE_TALKER) {
						++counter;
					}
					break ;
				case 'C':
					if (member_list->type == MEMBERTYPE_CONSULTANT) {
						++counter;
					}
					break ;
				default:
					ast_log(LOG_WARNING, "Unknown option '%c'.\n", options[i]);
				}
			}

			member_list = member_list->next;
		}
		snprintf(tmpbuf, 15, "%d", counter);
		ast_copy_string(buf, tmpbuf, len);
	}

	LOCAL_USER_REMOVE(u);
	return buf;
}