All pastes #31733 Raw Edit

Untitled

public text v1 · immutable
#31733 ·published 2005-11-29 21:38 UTC
rendered paste body
/*
 * OpenPBX -- An open source telephony toolkit.
 *
 * Copyright (C) 2005, Roy Sigurd Karlsbakk
 *
 * Roy Sigurd Karlsbakk <roy@karlsbakk.net>
 *
 * See http://www.openpbx.org for more information about
 * the OpenPBX project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2. See the LICENSE file
 * at the top of the source tree.
 */

/*
 *
 * RRDial application
 * 
 */
#ifdef HAVE_CONFIG_H
#include "confdefs.h"
#endif

#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "openpbx.h"

OPENPBX_FILE_VERSION("$HeadURL: svn://svn.openpbx.org/openpbx/trunk/apps/app_rrdial.c $", "$Revision: 822 $")

#include "openpbx/file.h"
#include "openpbx/logger.h"
#include "openpbx/channel.h"
#include "openpbx/pbx.h"
#include "openpbx/module.h"
#include "openpbx/lock.h"
#include "openpbx/app.h"

#define RRDIAL_MAX_MEMBER_NAME 64
#define RRDIAL_MAX_MEMBERS 10
#define RRDIAL_MAX_POOLS 10

static char *tdesc = "Round Robin Dial Application";
static char *app = "RRDial";
static char *synopsis = 
"Round Robin Dial application.";
static char *descrip =
 "Dial one server out of a pool of servers givin in pools.conf\n"
 "in a weighted random order.\n";
static char *config_file = "pools.conf";

STANDARD_LOCAL_USER;

LOCAL_USER_DECL;

struct opbx_rrdial_member {
        char name[RRDIAL_MAX_MEMBER_NAME];
        int weight;
};

struct opbx_rrdial_pool {
        struct opbx_rrdial_member members[RRDIAL_MAX_MEMBERS];
};

static struct opbx_rrdial_members[RRDIAL_MAX_MEMBERS];

static int app_exec(struct opbx_channel *chan, void *data) {
        int res = 0;
        struct opbx_flags flags;
        struct localuser *u;
        char *options=NULL;
        char *dummy = NULL;
        char *args;
        int argc = 0;
        char *opts[2];
        char *argv[2];

        if (!(args = opbx_strdupa((char *)data))) {
                opbx_log(LOG_ERROR, "%s: Out of memory!\n",app);
                return -1;
        }

        if (!data) {
                opbx_log(LOG_WARNING, "%s requires an argument (pool)\n",app);
                return -1;
        }

        LOCAL_USER_ADD(u);

        /* Do our thing here */
        opbx_log(LOG_WARNING, "%s isn't finished yet. sorry.\n",app);

        /* Clean up */
        LOCAL_USER_REMOVE(u);
        return res;
}

/*
 * this is a mess. it really is
 *
 *   opbx_variable_retrieve(cfg, "section", "key");
 *     get variable key 'key' from section [section]
 *
 *   var = opbx_variable_browse(cfg, cat);
 *
 *   char * opbx_category_browse (struct opbx_config *config, const char *prev)
 *
 *     many A pointer to a previous category. This funtion is kind of non-
 *     intuitive in it's use. To begin, one passes NULL as the second arguement.
 *     It will return a pointer to the string of the first category in the file.
 *     From here on after, one must then pass the previous usage's return value
 *     as the second pointer, and it will return a pointer to the category name
 *     afterwards.
 *
 * /usr/local/openpbx.org/etc/pools.conf
 *
 */
static int reload_rrdial(void) {
        struct opbx_config *cfg;
        struct opbx_variable *var;
        char *cat = NULL;
        char *tmp;
        char weight_s[8];
        int members, weight;
        int member_count;
        int pool_count=0;

        /* clean up old config */
        memset(&opbx_rrdial_members, 0, sizeof opbx_rrdial_members);

        /* get the new config */
        cfg = opbx_config_load(config_file);
        if (!cfg) {
                opbx_log(LOG_WARNING, "No server pool config file (%s), so no server pools\n", config_file);
                return -1;
        }

        while (cat = opbx_category_browse (cfg, cat)) {
                if (strcasecmp(cat, "general") == 0) {
                        opbx_log(LOG_DEBUG, "Category 'general' is not currently in use, ignored.\n", cat);
                        continue;
                } else {
                        opbx_log(LOG_DEBUG, "Adding pool '%s'\n", cat);
                        pool_count++;
                        member_count=0;

                        if (pool_count > 1) {
                                opbx_log(LOG_WARNING, "%s doesn't support more than one pool yet. sorry...\n", app);
                                return 0;
                        }

                        for (var = opbx_variable_browse(cfg, cat); var ; var = var->next) {
                                opbx_log(LOG_DEBUG, "Server pool conf '%s' has line '%s'\n", cat, var->value);

                                /* Just check if this is a 'member'. It should be... We don't have much else at them moment */
                                if (strcasecmp(var->name, "member") == 0) {
                                        if ((tmp = strchr(var->value, ','))) {
                                                memset(&servername, 0, sizeof servername);
                                                strncpy((char *)&opbx_rrdial_members[member_count], var->value, RRDIAL_MAX_MEMBER_NAME-1);
                                                tmp = strchr(servername,',');
                                                if (tmp) {
                                                        *tmp = 0;
                                                        tmp++;
                                                        strncpy(weight_s, tmp, sizeof weight_s);
                                                        weight = strtol(weight_s, NULL, 0);
                                                        opbx_log(LOG_DEBUG, "Server pool '%s' has member '%s' with weight %d\n", cat, var->value, weight);
                                                } else {
                                                        opbx_log(LOG_DEBUG, "Line '%s' doesn't give a weight. Ignored.\n", var->value);
                                                }
                                        } else {
                                                opbx_log(LOG_DEBUG, "Line '%s' doesn't give a weight. Ignored.\n", var->value);
                                        }
                                } else {
                                        opbx_log(LOG_DEBUG, "I don't know what to do with a '%s' type", cat, var->name);
                                }
                        }
                        if (members == 0)
                                opbx_log(LOG_NOTICE, "Server pool '%s' has no members.\n", cat);
                        else
                                opbx_log(LOG_DEBUG, "Server pool '%s' has %i members.\n", cat, members);
                }
        }

        return 0;
}

int reload(void) {
        return reload_rrdial();
}

int unload_module(void) {
        STANDARD_HANGUP_LOCALUSERS;
        return opbx_unregister_application(app);
}

int load_module(void) {
        int res;

        res = opbx_register_application(app, app_exec, synopsis, descrip);
        if (res != 0) {
                opbx_log(LOG_DEBUG, "opbx_register_application returned %i\n", res);
                return res;
        }

        res = reload_rrdial();
        if (res != 0)
                opbx_log(LOG_DEBUG, "reload_rrdial returned %i\n", res);

        return res;
}

char *description(void) {
        return tdesc;
}

int usecount(void) {
        int res;
        STANDARD_USECOUNT(res);
        return res;
}