Asterisk:undefined reference to `SQLAllocHandle' - c

I added a test.c in asterisk/main directory to test ODBC. Unfortunately it shows like below when I run make.
test.o: In function `test_function':
/usr/src/asterisk-certified-13.8-cert3/main/libtest.c:10:
undefined reference to `SQLAllocHandle'
test.c like this:
#include "asterisk/res_odbc.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
int test_function(void){
int res;
SQLHANDLE output_handle;
res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &output_handle);
if ( (res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) ) {
ast_log(LOG_DEBUG, "AllocHandle Success!\n");
} else {
ast_log(LOG_WARNING, "Error AllocHandle");
}
return 0;
}
How can I fix this? Thanks!

You should change Makefile for include libs into your module.
But that is WRONG method when you working with asterisk.
Correct method is user REALTIME or func_odbc and make it care about connection.

Related

Implementing parsing with the ls command in C

I'm trying to implement the ls command in C with a few parameters like -a, -l... or -la, but I'm having issues with the parsing, when I use the input I get Segmentation Fault, this is an example of the -a parameter:
int comparator(char *av) {
int i = 0;
if (my_strcmp((av[i]), "-a") == 0)
return 0;
else
return 1;
}
int my_ls_a(char *path) {
int comp = comparator(path);
DIR *pdirec = opendir(".");
struct dirent *direc;
direc = readdir(pdirec);
while (direc != NULL || comp == 0) {
my_printf("%s ", direc->d_name);
direc = readdir(pdirec);
}
if ((path = readdir(pdirec)) == NULL)
my_printf("\n");
if (pdirec == NULL)
return (84);
closedir(pdirec);
return (0);
}
And this is my main:
int main(int ac, char *av[]) {
if (ac == 1)
my_ls_a(av[0]);
return 0;
}
I already have all the #include in a .h by the way.
When I only use the main function it works but not when I add the parameter -a.
It's probably better to use getopt() for parameter parsing instead of writing your own parser.
You have undefined behavior in the function comparator in my_strcmp((av[i]), "-a") because av is defined as a char * so you are passing a character where my_strcmp probably expects a pointer.
You should compile with -Wall -Werror to avoid such silly mistakes.
It is unclear why you pass only a single argument to my_ls_a. You should pass both ac and the argument array av and iterate on the arguments to parse the options.

driver in globus toolkit

I have been trying to run an example driver program given in the globus toolkit website. This is the program:
#include "globus_xio.h"
int main(int argc,char *argv[])
{
globus_result_t res;
char * driver_name;
globus_xio_driver_t driver;
globus_xio_stack_t stack;
globus_xio_handle_t handle;
globus_size_t nbytes;
char * contact_string = NULL;
char buf[256];
contact_string = argv[1];
driver_name = argv[2];
globus_module_activate(GLOBUS_XIO_MODULE);
res = globus_xio_driver_load(driver_name,&driver);
assert(res == GLOBUS_SUCCESS);
res = globus_xio_stack_init(&stack, NULL);
assert(res == GLOBUS_SUCCESS);
res = globus_xio_stack_push_driver(stack, driver);
assert(res == GLOBUS_SUCCESS);
res = globus_xio_handle_create(&handle, stack);
assert(res == GLOBUS_SUCCESS);
res = globus_xio_open(handle, contact_string, NULL);
assert(res == GLOBUS_SUCCESS);
do
{
res = globus_xio_read(handle, buf, sizeof(buf) - 1, 1, &nbytes, NULL);
if(nbytes > 0)
{
buf[nbytes] = '\0';
fprintf(stderr, "%s", buf);
}
} while(res == GLOBUS_SUCCESS);
globus_xio_close(handle, NULL);
globus_module_deactivate(GLOBUS_XIO_MODULE);
return 0;
}
When I compile this using the command
cc -I /usr/include/globus globus_xio_example.c
I get the following errors
/tmp/ccLMLlIi.o: In function `main':
globus_xio_example.c:(.text+0x57): undefined reference to `globus_i_xio_module'
globus_xio_example.c:(.text+0x5c): undefined reference to `globus_module_activate'
globus_xio_example.c:(.text+0x75): undefined reference to `globus_xio_driver_load'
globus_xio_example.c:(.text+0xb1): undefined reference to `globus_xio_stack_init'
globus_xio_example.c:(.text+0xf2): undefined reference to `globus_xio_stack_push_driver'
globus_xio_example.c:(.text+0x133): undefined reference to `globus_xio_handle_create'
globus_xio_example.c:(.text+0x179): undefined reference to `globus_xio_open'
globus_xio_example.c:(.text+0x1d1): undefined reference to `globus_xio_read'
globus_xio_example.c:(.text+0x22b): undefined reference to `globus_xio_close'
globus_xio_example.c:(.text+0x230): undefined reference to `globus_i_xio_module'
globus_xio_example.c:(.text+0x235): undefined reference to `globus_module_deactivate'
collect2: ld returned 1 exit status
It appears that the command used to compile is insufficient:
cc -I /usr/include/globus globus_xio_example.c
Specifically, the linker process indicates that there are a number of symbols that could not be resolved. I suspect that the command used to compile is lacking directives as to which library(s) needs to be linked to resolve the undefined symbols.
HINT:
Use 'globus-makefile-header' to help determine library dependencies.
% globus-makefile-header -flavor=gcc32dbg globus_xio > header
Examine the contents of 'header' for appropriate makefile macros.
Include header in your makefile and use the needed makefile macros.
Try this gcc -I /usr/include/globus globus_xio_example.c -lglobus_xio -lglobus_common

called library procedure is running in infinity cycle on gnu/linux

I've got an library which must read data from sqlite database by calling
extern int read(char** argv, int argc); // from header
it must process:
int read(char** argv, int argc) {
char* lineborder1;
char* lineborder2;
char* spaces1;
char* spaces2;
int maxl2 = 0, maxl1 = 0;
int i, maxi1, maxi2;
if (prelude() == -1) return -1;
// etc...
where prelude is inner procedure for sqlite connection:
int prelude() {
timefile = 0;
f = NULL;
#ifndef WIN32
char* temp = (char*)calloc(200, sizeof(char));
#endif
queries = (char**)malloc(sizeof(char*) * q_cnt);
for (x = 0; x < q_cnt; x++) {
queries[x] = (char*)malloc(sizeof(char) * q_size);
}
#ifdef WIN32
retval = sqlite3_open("todo.db3", &handle);
#else
home = (char*)getenv("HOME");
strcpy(temp, home);
retval = sqlite3_open(strcat(temp, "/.todo.db3"), &handle);
free(temp);
#endif
if (retval) {
printf("Database connection failed\n\r");
return -1;
}
return 0;
}
whole source is here : bitbucket: ctodo.c
I call this read from my application:
else if ((strcmp(argv[1], "read") == 0) || (strcmp(argv[1], "r") == 0)) {
return read(argv, argc);
but getting infinity cycle of this read call:
>>./todo r
Database connection failed
Database connection failed
Database connection failed
.... etc
here is how do I build it:
gcc -I . -c -o todo.a ctodo.c -lsqlite3 -O3
gcc -I . -o todo cctodo.c -lsqlite3 -O3 todo.a
help or version calls wrok fine and read works fine on windows, something specific to my linux build is here but I can't find a bug so far. what could call this read to run in infinity cycle like that?
The read function is defined in libc.so, and used to, you know, read data.
It is exceedingly likely that sqlite3_open() calls it.
By introducing your own function called read(), you've made your program enter infinite loop. If you wait long enough, your program will run out of stack and crash.
Doctor, it hurts when I do that. Well, don't do that :-)

gcc reports "will never be executed" about the line: while(fgets(line, MAX_LINE, stdin) != NULL)

I'm looking for an explanation why gcc are giving this warning for me.
I'm compiling with the gcc-3 on cygwin with the -Wunreachable-code flag, and the gcc says this warning for me:
main.c:223: warning: will never be executed
That's this line: while(fgets(line, MAX_LINE, stdin) != NULL) {
This code is inside a if(exp) { } block where exp is dynamically set according to command-line-arguments(parsed by getopt() ), look at the code part:
if(mystruct.hastab) {
the default value is 0. But it's become 1 if -t flag is passed to application, as you can see at following:
struct mystruct_t {
//...
int hastab;
} mystruct;
int main(int argc, char *argv[])
{
int opt;
memset(&mystruct, 0, sizeof(mystruct));
while((opt = getopt(argc, argv, optString)) != -1) {
switch(opt) {
case 't':
mystruct.hastab = 1;
break;
//....
}
}
proc();
return 0;
}
void
proc(void)
{
char *buf, *tmpbuf, line[MAX_LINE + 1], *p, *fullfilename;
if(mystruct.hastab) {
while(fgets(line, MAX_LINE, stdin) != NULL) {
//...
}
} else {
//...
}
}
So, there's a reason for the code be executed. As happens.
Sounds like gcc is convinced hastab is never set, or that it is only set after the code it's warning about. It certainly seems like gcc is wrong, but since you only gave us snippets it is hard to be sure. I don't think anyone can help you further unless we see a complete program we can compile ourselves.
Here's another possibility: the problem is with macros. Here's a simple example that demonstrates your error:
#include <string.h>
int s;
int main(int argc, char *argv[]) {
memset(&s, 0, sizeof(s));
}
When I compile this, I get:
$ gcc -Wunreachable-code tmp.c
tmp.c: In function ‘main’:
tmp.c:4: warning: will never be executed
The error is not particularly enlightening. However, if you run the preprocessor, look what memset expands to:
$ gcc -E tmp.c
...
int s;
int main(int argc, char *argv[]) {
((__builtin_object_size (&s, 0) != (size_t) -1) ? __builtin___memset_chk (&s, 0, sizeof(s), __builtin_object_size (&s, 0)) : __inline_memset_chk (&s, 0, sizeof(s)));
}
I suspect because of the constant size of s, only one of the branches of the ?: is ever executed, and this is what gcc is complaining about. In your case, it's probably that fgets is a macro. Run gcc -E, find your problem line in the output, and see if it's wonky (mine isn't, but I'm not running cygwin).
Moral of the story: preprocessors & macros suck.
If I had to guess I'd say gcc is considering that there are 2 cases where you can call proc() without having set mystruct.hastab to something other than 0.
The first case is if this evaulates to false on the first run through, since you will drop out of the loop without executing your switch statement:
while((opt = getopt(argc, argv, optString)) != -1) {
The second case is if opt is never 't':
switch(opt) {
case 't':
mystruct.hastab = 1;
So you will fall out of the loop without ever having set mystruct.hastab to a non-zero value.

How to change Keyboard Layout (a X11 API solution)

I want to change keyboard layout in Linux by programming,
What X11's API function does this?
I found one good solution.
It's a c++ class wrriten by Jay Bromley, that I can add to my app and using it.
source code
It's very easy to use:
#include "XKeyboard.h"
XKeyboard xkb;
std::string cGrpName=xkb.currentGroupName(); //return somethings like "USA"
std::string cGrpSymb=xkb.currentGroupSymbol(); //return somethings like "us"
xkb.setGroupByNum(0);//set keyboard layout to first layout in available ones
you can read source code and found some another useful functions.
for compiling standalone version you need to un-comments "int main" function present in "XKeyboard.cpp" (or write your own main.cpp) and use somethings like this:
g++ *.cpp -o getxkblayout -L/usr/lib -lX11
I'm not sure what the X11 library function is but setxkbmap is the bash command I use to achieve it. Maybe searching along these lines will find what you want (or at a pinch you could just execute the bash command).
Example
setxkbmap dvorak
setxkbmap us
EDIT:
After a strace of setxkbmap didn't turn up anything useful I suggest just calling:
system(“setxkbmap us”);
A pure X11 API solution should look something like this:
#include <stdio.h>
#include <X11/XKBlib.h>
int main() {
Display* _display;
char* displayName = "";
_display = XOpenDisplay(displayName);
XkbDescRec* _kbdDescPtr = XkbAllocKeyboard();
XkbGetNames(_display, XkbSymbolsNameMask, _kbdDescPtr);
Atom symName = _kbdDescPtr -> names -> symbols;
char* layoutString = XGetAtomName(_display, symName);
XCloseDisplay(_display);
printf("%s\n", layoutString);
}
Compile with -lX11 flag
This will print something like pc+us+inet(evdev) for English (USA) qwerty layout, pc+ru+us:2+inet(evdev) for Russian йцукен layout, pc+us(dvorak)+us:2+inet(evdev) for English dvorak layout.
Yesterday I was trying to make auto layuout switcher to EN for Google's xsecurelock. I tryed to find some existing solutions for X11 api, but...
So I decided to write my own with some help from S. Razi.
Here is the code: (run with gcc -lX11)
#include <stdio.h>
#include <stdlib.h>
#include <X11/XKBlib.h>
int main(){
Display* _display;
char* displayName = "";
_display = XOpenDisplay(displayName);
int _deviceId = XkbUseCoreKbd;
int i = 0;
int _groupCount = 0;
XkbDescRec* kbdDescPtr = XkbAllocKeyboard();
if (kbdDescPtr == NULL) {
printf("%s\n", "Failed to get keyboard description.");
return False;
}
kbdDescPtr->dpy = _display;
if (_deviceId != XkbUseCoreKbd) {
kbdDescPtr->device_spec = _deviceId;
}
XkbGetControls(_display, XkbAllControlsMask, kbdDescPtr);
XkbGetNames(_display, XkbSymbolsNameMask, kbdDescPtr);
XkbGetNames(_display, XkbGroupNamesMask, kbdDescPtr);
/* count groups */
Atom* groupSource = kbdDescPtr->names->groups;
if (kbdDescPtr->ctrls != NULL) {
_groupCount = kbdDescPtr->ctrls->num_groups;
} else {
_groupCount = 0;
while (_groupCount < XkbNumKbdGroups &&
groupSource[_groupCount] != 0) {
_groupCount++;
}
}
/* get group names */
Atom* tmpGroupSource = kbdDescPtr->names->groups;
Atom curGroupAtom;
char* groupName;
for (i = 0; i < _groupCount; i++) {
if ((curGroupAtom = tmpGroupSource[i]) != None) {
char* groupNameC = XGetAtomName(_display, curGroupAtom);
if (groupNameC == NULL) {
continue;
} else {
groupName = groupNameC;
char *temp = "English";
if (strncmp(temp, groupName, 7) == 0){
printf ("%s\n", groupName);
printf ("%d\n", i);
XkbLockGroup(_display, _deviceId, i);
XFree(groupNameC);
XCloseDisplay(_display);
}
return 0;
}
}
}
}
Here you can change char* temp = "English" to name of the group of your layout (exmp: "Russian"), and this simple code will switch your current layout :)

Resources