Trying to write to file using g_file_set_contents - glib

I just want to use GNOME glib functions to simply write and read a file. I think my syntaxes are wrong in calling the functions. I tried to open a file with g_fopen("filenam.txt", "w"); but it didnt create any file. I also used g_file_set_contents and I am trying to save my Gstring s into a file file.txt with code as
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
uint8_t *opdu;
uint16_t handle, i, olen;
size_t plen;
//GString *s;
const gchar *s;
gssize length;
length = 100;
handle = get_le16(&pdu[1]);
switch (pdu[0]) {
case ATT_OP_HANDLE_NOTIFY:
s = g_string_new(NULL);
//g_string_printf(s, "Movement data = 0x%04x value: ",handle);
g_file_set_contents("file.txt", s, 100, NULL);
break;
case ATT_OP_HANDLE_IND:
s = g_string_new(NULL);
g_string_printf(s, "Indication handle = 0x%04x value: ",handle);
break;
default:
error("Invalid opcode\n");
return;
}
for (i = 3; i < len; i++)
g_string_append_printf(s, "%02x ", pdu[i]);
rl_printf("%s\n", s->str);
g_string_free(s, TRUE);
if (pdu[0] == ATT_OP_HANDLE_NOTIFY)
return;
opdu = g_attrib_get_buffer(attrib, &plen);
olen = enc_confirmation(opdu, plen);
if (olen > 0)
g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
}

You're conflating GString* and gchar*. The g_string_*() functions expect a GString*, and g_file_set_contents() expects gchar*. If you want the raw data, use the str field.
Also, I suggest turning on some more warnings on your compiler, since it really should be complaining during development if you try to do this. Passing -Wall should do the trickā€¦

Related

Lua mount filesystem

I want to mount a filesystem on Linux using Lua, but I haven't found any capability in the lua 5.4 manual or the LuaFileSytem library. Is there some way to mount a filesystem in Lua or with an existing library?
Like most platform-dependent syscall, Lua won't provide such mapping out of the box.
So you'll need some C-API module that does the trick.
Looks like https://github.com/justincormack/ljsyscall is generic "but" focused on LuaJIT and https://luaposix.github.io/luaposix/ doesn't provide mount.
I recently had similar needs, and I ended doing the C module:
static int l_mount(lua_State* L)
{
int res = 0;
// TODO add more checks on args!
const char *source = luaL_checkstring(L, 1);
const char *target = luaL_checkstring(L, 2);
const char *type = luaL_checkstring(L, 3);
lua_Integer flags = luaL_checkinteger(L, 4);
const char *data = luaL_checkstring(L, 5);
res = mount(source, target, type, flags, data);
if ( res != 0)
{
int err = errno;
lua_pushnil(L);
lua_pushfstring(L, "mount failed: errno[%s]", strerror(err));
return 2;
}
else
{
lua_pushfstring(L, "ok");
return 1;
}
}
#define register_constant(s)\
lua_pushinteger(L, s);\
lua_setfield(L, -2, #s);
// Module functions
static const luaL_Reg R[] =
{
{ "mount", l_mount },
{ NULL, NULL }
};
int luaopen_sysutils(lua_State* L)
{
luaL_newlib(L, R);
// do more mount defines mapping, maybe in some table.
register_constant(MS_RDONLY);
//...
return 1;
}
Compile this as a C Lua module, and don't forget that you need CAP_SYS_ADMIN to call mount syscall.

lua line numbers after multiple calls to loadbuffer

I load two strings with loadbuffer into one lua_state.
if( luaL_loadbuffer( L, str.c_str(), str.size(), "line") != 0 )
{
printf( "%s\n", lua_tostring ((lua_State *)L, -1));
}
lua_pcall(L, 0, 0, 0);
if( luaL_loadbuffer( L, str2.c_str(), str2.size(), "line2") != 0 )
{
printf( "%s\n", lua_tostring ((lua_State *)L, -1));
}
lua_pcall(L, 0, 0, 0);
For example:
function f ()
print( "Hello World!")
end
and
function g ()
f(
end
The forgotten ) in the second string throws an error:
[string "line2"]:9: unexpected Symbol
But 9 is the line number from string 1 plus string 2. The line number should be 3.
Is there a way to reset the line number counter before call to loadbuffer?
I guess this link describes your situation:
http://www.corsix.org/content/common-lua-pitfall-loading-code
You are loading two chunks of information, calling the chunks will put them consecutive into the global table. The lua_pcall(L, 0, 0, 0); is not calling your f() and g(), but is constructing your lua code sequential.
Your code could possibly be simplified to:
if (luaL_dostring(L, str.c_str()))
{
printf("%s\n", lua_tostring (L, -1));
}
if (luaL_dostring(L, str2.c_str()));
{
printf("%s\n", lua_tostring (L, -1));
}
which also protects against calling a chunk when it fails to load;
You are right Enigma, the code from str2 is appended consecutive. A breakpoint in
static void statement (LexState *ls) {
in lparser.cpp shows LexState.linenumber to be 5 and 7 for str, and 5, 7, 14 and 16 for str2.
So str is lexed and added to the VM twice.
I will find a different way to put a script made of multiple files into one VM.
Just if someone would need it too.
Add this function to lauxlib.h
LUALIB_API int (luaL_loadbuffers) (lua_State *L, size_t count, const char **buff, size_t *sz,
const char **name, const char *mode);
and to lauxlib.c
#include"lzio.h"
#include"ldo.h"
#include"ltable.h"
#include"lgc.h"
LUALIB_API int luaL_loadbuffers (lua_State *L, size_t count, const char **buff, size_t *sz,
const char **name, const char *mode)
{
ZIO z;
int status;
int i;
for( i=0; i<count; i++)
{
LoadS ls;
ls.s = buff[i];
ls.size = sz[i];
lua_lock(L);
luaZ_init(L, &z, getS, &ls);
status = luaD_protectedparser(L, &z, name[i], mode);
if (status == LUA_OK) { /* no errors? */
LClosure *f = clLvalue(L->top - 1); /* get newly created function */
if (f->nupvalues == 1) { /* does it have one upvalue? */
/* get global table from registry */
Table *reg = hvalue(&G(L)->l_registry);
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
setobj(L, f->upvals[0]->v, gt);
luaC_barrier(L, f->upvals[0], gt);
} // == 1
lua_pcall( L, 0, 0, 0);
}
lua_unlock(L);
if( status != LUA_OK )
break;
}
return status;
}
Every string/file gets its own line numnbering.
It is just a copy, almost, of lua_load in lapi.c. So easy to adjust in a new release of LUA.

dylib or executable export list

I am writing a plugins subsystem and one of the ideas is to iterate through a dylib (or at least current global scope) exported functions. I know there are other ways, just really want to give this one a try.
What I am wondering, is there a way to get a list of functions exported by a dylib or available in global scope through OS X and iOS API?
Thanks in advance!
You can use a command 'nm' for getting an information from a dynamic library.
See additionally system manual for this command on Mac.
If you are looking to do that from code, you could use this method.
std::vector<std::string> load_mach_o(std::string file_name)
{
/*
Parse the Mach-O structure to find all the exported symbols
Mach-O structure:
mach_header_64
cmd
...
cmd
data
...
data
*/
std::vector<std::string> methods;
off_t offset = sizeof(struct mach_header_64);
BYTE * bytes = load_bytes(file_name.c_str());
if (bytes == NULL)
{
return methods;
}
struct mach_header_64 *header = (struct mach_header_64 *)bytes;
//Get the load commands
struct load_command *cmd = (struct load_command *)(bytes + offset);
for (uint32_t i = 0U; i < header->ncmds; i++)
{
if (cmd->cmd == LC_SYMTAB)
{
struct symtab_command * symtab = (struct symtab_command *)cmd;
off_t string_start = 0;
const char* strings = (const char *)(bytes + symtab->stroff + 1);
for (uint32_t i = 0 ; i < symtab->strsize ; i++)
{
if (strings[i] == '\0')
{
i++;
size_t size = sizeof(char) * (i - string_start);
if (size == 1)
{
string_start = i+1;
continue;
}
methods.push_back(std::string((const char *)(strings + string_start)));
string_start = i+1;
}
}
}
offset += cmd->cmdsize;
//load next command
cmd = (struct load_command *)(bytes + offset);
}
free(bytes);
return methods;
}
This function read the file and parses the structure till mach-O strings section, then, parses each string and store it in a vector containing all the exposed functions.
Best regards.

Save BIO into char* (from SMIME_write_CMS)

I want to save (pipe/copy) a BIO into a char array.
When I know the size it works, but otherwise not.
For example, I can store the content of my char* into a BIO using this
const unsigned char* data = ...
myBio = BIO_new_mem_buf((void*)data, strlen(data));
But when I try to use SMIME_write_CMS which takes a BIO (what I've created before) for the output it doesn't work.
const int SIZE = 50000;
unsigned char *temp = malloc(SIZE);
memset(temp, 0, SIZE);
out = BIO_new_mem_buf((void*)temp, SIZE);
if (!out) {
NSLog(#"Couldn't create new file!");
assert(false);
}
int finished = SMIME_write_CMS(out, cms, in, flags);
if (!finished) {
NSLog(#"SMIME write CMS didn't succeed!");
assert(false);
}
printf("cms encrypted: %s\n", temp);
NSLog(#"All succeeded!");
The OpenSSL reference uses a direct file output with the BIO.
This works but I can't use BIO_new_file() in objective-c... :-/
out = BIO_new_file("smencr.txt", "w");
if (!out)
goto err;
/* Write out S/MIME message */
if (!SMIME_write_CMS(out, cms, in, flags))
goto err;
Do you guys have any suggestion?
I would suggest trying to use SIZE-1, that way you are guaranteed that it is NULL terminated. Otherwise, it is possible that it is just over running the buffer.
out = BIO_new_mem_buf((void*)temp, SIZE-1);
Let me know if that helps.
Edit:
When using BIO_new_mem_buf() it is a read only buffer, so you cannot write to it. If you want to write to memory use:
BIO *bio = BIO_new(BIO_s_mem());

madvise() function not working

I am trying madvise() to mark allocated memory as mergeable so that two applications having same pages can be merged.
While using the madvise() function it shows "invalid argument".
#include<stdio.h>
#include<sys/mman.h>
#include<stdlib.h>
#include<errno.h>
#define ADDR 0xf900f000
int main()
{
int *var1=NULL,*var2=NULL;
size_t size=0;
size = 1000*sizeof(int);
var1 = (int*)malloc(size);
var2 = (int *)malloc(size);
int i=0;
for(i=0;i<999;i++)
{
var1[i] = 1;
}
for(i=0;i<999;i++)
{
var2[i] = 1;
}
i = -1;
while(i<0)
{
i = madvise((void *)var1, size, MADV_MERGEABLE); //to declare mergeable
printf("%d %p\n", i, var1); //to print the output value
err(1,NULL); //to print the generated error
i = madvise((void *)var2, size, MADV_MERGEABLE); //to declare mergeable
printf("%d\n", i);
}
return 0;
}
Error:
a.out: Invalid argument
Please help me.
Thank You.
You can only merge whole pages. You can't merge arbitrary chunks of data.

Resources