Show reflect_main.c syntax highlighted
char reflect_main_c_cvsid [] = "$Id: reflect_main.c,v 1.2 2005/02/24 02:08:17 adparker Exp $";
#include <stdlib.h>
#include "emrun/emrun.h"
#include "libmisc/misc.h"
#include "libmisc/misc_init.h"
#include "libdev/query_dev.h"
#include "fusd/fusd.h"
#include "link/link.h"
#include "reflect.h"
#include "reflect_extras.h"
/*static void
usage (char * name);
*/
// Returns 1 if a > b, else returns 0
/*static int
reflect_seq_no_greater (reflect_seq_no_t a,
reflect_seq_no_t b);
*/
static reflect_state_t
reflect_state_init ();
/*static char *
get_uses_arg (int argc, char * argv[]);
*/
// ref type name to number
// ref type number to name
// reflect_link_receive;
// link_receive_block_have
static int
reflect_query_dev_get_process (query_context_t * q,
char * command,
size_t buf_size,
buf_t * print,
buf_t * bin);
static void
reflect_query_dev_get_usage (query_context_t * q,
buf_t * buf);
// reflect_query_dev_get_ascii_process;
static int
reflect_query_dev_set_process (query_context_t * q,
char * command,
size_t buf_size,
buf_t * print,
buf_t * bin);
static GSList *
reflect_copy_pkt(GSList * list,
reflect_pkt_t * new_pkt,
size_t buf_size);
// query_dev_set_bin receive block_have
//reflect_timer_blocks_have;
static void
setup_query_dev (char * device_name,
reflect_state_t * state,
query_process_cb_t process_cb,
query_usage_cb_t usage_cb,
query_context_t ** query_context_ref);
/*static void
setup_link (char * uses,
reflect_state_t * state,
lu_pkt_receive_cb_t receive_cb);
*/
static int
reflect_query_dev_set_process (query_context_t * q,
char * command,
size_t buf_size,
buf_t * print,
buf_t * bin);
static GSList *
reflect_copy_pkt(GSList * list,
reflect_pkt_t * new_pkt,
size_t buf_size);
static gint
compare_type_node_reflect_pkt(gconstpointer a,
gconstpointer b);
static int
reflect_query_dev_get_process (query_context_t * q,
char * command,
size_t buf_size,
buf_t * print,
buf_t * bin);
static void
reflect_get_bin (GSList * list, buf_t * bin);
static void
reflect_get_bin_foreach (gpointer data, gpointer user_data);
static void
reflect_query_dev_get_usage (query_context_t * q,
buf_t * buf);
int
main (int argc, char * argv[])
{
elog (LOG_INFO, "Starting up.");
misc_init (&argc, argv, CVSTAG);
reflect_state_t state = reflect_state_init ();
// char * uses = get_uses_arg (argc, argv);
// setup_link (uses, &state, reflect_link_receive);
setup_query_dev (REFLECT_QUERY_DEV_GET,
& state,
reflect_query_dev_get_process,
reflect_query_dev_get_usage,
& (state.query_dev_get_ref));
/* setup_query_dev (REFLECT_QUERY_DEV_GET_ASCII,
& state,
reflect_query_dev_get_ascii_process,
& (state.query_dev_get_ascii_ref));
*/
setup_query_dev (REFLECT_QUERY_DEV_SET,
& state,
reflect_query_dev_set_process,
NULL,
& (state.query_dev_set_ref));
/*
if ( (g_timer_add(5000,
reflect_timer_blocks_have,
&state,
NULL,
NULL)) < 0)
{
elog(LOG_CRIT, "Unable to create timer event");
exit(1);
}
*/
g_main ();
elog (LOG_ALERT, "Event system terminated abnormally.");
return 1;
}
/////////////////////////
/*static void
usage (char * name)
{
misc_print_usage (name, "", "");
exit (1);
}*/
/////////////////////////
/*static int
reflect_seq_no_greater(reflect_seq_no_t a,
reflect_seq_no_t b)
{
if (a.sec > b.sec) return 1;
if (a.sec < b. sec) return 0;
if (a.usec > b.usec) return 1;
if (a.usec < b.usec) return 0;
if (a.increment > b.increment) return 1;
return 0;
}*/
/////////////////////////
static reflect_state_t
reflect_state_init ()
{
reflect_state_t state =
{
block_have_list : NULL,
query_dev_get_ref: NULL,
query_dev_set_ref: NULL
};
return state;
}
/////////////////////////
/*static char *
get_uses_arg (int argc, char * argv[])
{
char * uses = link_parse_uses (&argc, argv, NULL);
if (uses == NULL) {
elog (LOG_CRIT, "Please specify a link to use!");
usage (argv[0]);
}
return uses;
}*/
////////////////////////
static void
setup_query_dev (char * device_name,
reflect_state_t * state,
query_process_cb_t process_cb,
query_usage_cb_t usage_cb,
query_context_t ** query_context_ref)
{
*query_context_ref = NULL;
query_dev_opts_t query_opts = {
device: {
devname: device_name,
device_info: state
},
process: process_cb,
usage: usage_cb
};
if (query_dev_new (&query_opts, query_context_ref) < 0)
{
elog (LOG_CRIT, "Can't create query dev %s: %m",
query_opts.device.devname);
exit (1);
}
}
////////////////////////
/*static void
setup_link (char * uses,
reflect_state_t * state,
lu_pkt_receive_cb_t receive_cb)
{
lu_opts_t lu_opts =
{
opts: {
name: uses,
data: state,
pkt_type: PKT_TYPE_REFLECT
},
receive: receive_cb
};
if (lu_open (&lu_opts, NULL) < 0)
{
elog (LOG_CRIT,
"Cannot open %s: %m",
link_name (&lu_opts.opts, NULL));
exit (1);
}
}*/
/////////////////////////
/*
* Check that input is:
* not null.
* >= reflect_pkt_t size
* buf_size == rflect_pkt_t + data_bytes
*
* Switch on type
* BLOCK_HAVE
*/
static int
reflect_query_dev_set_process (query_context_t * q,
char * command,
size_t buf_size,
buf_t * print,
buf_t * bin)
{
reflect_state_t * state = (reflect_state_t *)qdev_data(q);
if (command == NULL)
{
elog (LOG_CRIT,"Ignoring NULL");
goto done;
}
if (buf_size < sizeof(reflect_pkt_t))
{
elog (LOG_CRIT,"Size of command was: %d. "
"Expected to be >= reflect_pkt_t: %d",
buf_size, sizeof(reflect_pkt_t));
goto done;
}
reflect_pkt_t * new_pkt = (reflect_pkt_t *)command;
elog (LOG_NOTICE,"Packet you gave me:");
elog (LOG_NOTICE,"Type: %d",new_pkt->type);
elog (LOG_NOTICE,"Node ID: %d",new_pkt->node_id);
elog (LOG_NOTICE,"Seq_no %d %d %d",new_pkt->seq_no.sec,
new_pkt->seq_no.usec, new_pkt->seq_no.increment);
elog (LOG_NOTICE,"Data Bytes %d",new_pkt->data_bytes);
if (buf_size != (sizeof(reflect_pkt_t) + new_pkt->data_bytes))
{
elog (LOG_CRIT, "Oops. Total size of reflect packet "
"!= reflect_packet_header + data_bytes. Skipping.");
goto done;
}
switch (new_pkt->type)
{
case REFLECT_PKT_TYPE_BLOCK_HAVE:
state->block_have_list =
reflect_copy_pkt(state->block_have_list, new_pkt, buf_size);
break;
default:
elog (LOG_CRIT,"I don't understand type :%d", new_pkt->type);
}
done:
return QUERY_DONE;
}
////////////////////////////////////
static GSList *
reflect_copy_pkt(GSList * list,
reflect_pkt_t * new_pkt,
size_t buf_size)
{
reflect_pkt_t * local_pkt = (reflect_pkt_t*)malloc (buf_size);
memcpy(local_pkt, new_pkt, buf_size);
elog (LOG_NOTICE,"Copied packet:");
elog (LOG_NOTICE,"Type: %d",local_pkt->type);
elog (LOG_NOTICE,"Node ID: %d",local_pkt->node_id);
elog (LOG_NOTICE,"Seq_no %d %d %d",local_pkt->seq_no.sec,
local_pkt->seq_no.usec,
local_pkt->seq_no.increment);
elog (LOG_NOTICE,"Data Bytes %d",local_pkt->data_bytes);
list = gslist_find_free_replace_custom (list,
local_pkt,
compare_type_node_reflect_pkt);
return list;
}
///////////////////////////////////
static gint
compare_type_node_reflect_pkt(gconstpointer a,
gconstpointer b)
{
// -1 if a < b
// 0 if a == b
// 1 if a > b
reflect_pkt_t * ref_a = (reflect_pkt_t*)a;
reflect_pkt_t * ref_b = (reflect_pkt_t*)b;
gint result = compare_uint32(ref_a->type, ref_b->type);
if (result != 0) return result;
result = compare_uint32(ref_a->node_id, ref_b->node_id);
return result;
}
////////////////////////////////////
// command should be:
// TYPE=NAME
// TYPES
static int
reflect_query_dev_get_process (query_context_t * q,
char * command,
size_t buf_size,
buf_t * print,
buf_t * bin)
{
elog (LOG_CRIT, " ");
reflect_state_t * state = (reflect_state_t *)qdev_data(q);
char * output_method = NULL;
char * type = NULL;
parser_state_t * ps = misc_parse_init(command, MISC_PARSE_COMMA_SCHEME);
ps->skip_whitespace = 1;
while(misc_parse_next_kvp(ps) != -1)
{
if (strcmp(ps->key,"OUTPUT") == 0)
{
output_method = ps->value;
}
else if (strcmp(ps->key, "TYPE") == 0)
{
type = ps->value;
}
else
{
elog (LOG_CRIT,"Unrecognized key: %s", ps->key);
goto done;
}
}
if (output_method == NULL)
{
output_method = "ASCII";
}
if ( (strcmp(output_method,"ASCII") != 0) &&
(strcmp(output_method,"BINARY") != 0) )
{
elog (LOG_CRIT,"Unrecognized output method: %s",output_method);
goto done;
}
// At this point, output_method is set, and type is set.
if ( strcmp(type, "BLOCKS_HAVE") == 0 )
{
if ( strcmp(output_method, "BINARY") == 0)
{
// copy a list of reflect_pkt_ts into bin
reflect_get_bin(state->block_have_list, bin);
}
else
{
elog (LOG_CRIT, "Unknown output_method: %s", output_method);
goto done;
}
}
else
{
elog (LOG_CRIT, "Unrecognized command: %s",command);
goto done;
}
done:
misc_parse_cleanup(ps);
return QUERY_DONE;
}
////////////////////////////////
static void
reflect_get_bin (GSList * list, buf_t * bin)
{
buf_iter_t * iter = buf_item_iter_new(bin);
// foreach item in the have blocks list, append a copy to bin.
g_slist_foreach(list, reflect_get_bin_foreach, iter);
buf_item_iter_destroy(iter,0);
return;
}
/////////////////////////////////
static void
reflect_get_bin_foreach (gpointer data, gpointer user_data)
{
reflect_pkt_t * pkt = (reflect_pkt_t*)data;
buf_iter_t * iter = (buf_iter_t*) user_data;
buf_item_iter_append_str (iter,
(const char *)pkt,
sizeof(reflect_pkt_t) + pkt->data_bytes);
return;
}
/////////////////////////////////
static void
reflect_query_dev_get_usage (query_context_t * q,
buf_t * buf)
{
bufprintf(buf, "Input is a string that looks like:\n");
bufprintf(buf, " OUTPUT=<BINARY|ASCII>,TYPE=<type>\n");
bufprintf(buf, " \n");
bufprintf(buf, "Known types are:\n");
bufprintf(buf, " BLOCKS_HAVE\n");
}
See more files for this project here