full path for open / openat relative filenames - ebpf

Using the opensnoop.py from iovisor/bcc, I'm trying to extend the ebpf code to handle extraction of full paths from a relative one.
For example, running opensnoop.py and in another terminal running cat anything.txt, the output in opensnoop will show the relative filename, not an absolute path:
$ sudo ./venv/bin/python bcc/tools/opensnoop.py | grep anything.txt &
$ cat anything.txt 2>/dev/null
19536 cat -1 2 anything.txt
$ cat /tmp/anything.txt 2>/dev/null
19540 cat -1 2 /tmp/anything.txt
I've narrored down the code block in opensnoop.py that i should look into amending, and adding in some logic similar to:
// .. existing code
bpf_probe_read_user(&data.fname, sizeof(data.fname), (void *)filename);
data.id = id;
data.ts = tsp / 1000;
data.uid = bpf_get_current_uid_gid();
data.flags = flags; // EXTENDED_STRUCT_MEMBER
data.ret = ret;
// new code to handle relative paths:
if (data.fname[0] != '/' && data.fname[0] != '\\0') {
// TODO if filename doesn't start with a /, need to convert relative path to abs
struct fs_struct *fs = ((struct task_struct *) bpf_get_current_task())->fs;
// TODO: get pwd path from fs->pwd
struct path *pwd_path = &fs->pwd // ?
// TODO: call bpf_d_path(pwd_path, buf, sz)
// TODO: update data.fname to insert buf pwd)
}
events.perf_submit(ctx, &data, sizeof(data));
Where I'm stuck is the TODO parts, there doesn't seem to be many / any good examples of using the new bpf_d_path helper function

Related

Generating DXL documentation using Doxygen : if is shown as a function

I am trying to generate some DXL documentation usings Doxygen , but the results are often not correct , DXL is used as a scripting language and that has a C/C++ like syntax with some changes , like for example i can ignor using the Semicolons , What should i do to correct this problem ?
which creates some problems while generating the documentation, here is an example of my dxl code database :
string replace (string sSource, string sSearch, string sReplace) {
int iLen = length sSource
if (iLen == 0) return ""
int iLenSearch = length(sSearch)
if (iLenSearch == 0) {
return ""
}
char firstChar = sSearch[0]
Buffer s = create()
int pos = 0, d1,d2;
int i
while (pos < iLen) {
char ch = sSource[pos];
bool found = true
if (ch != firstChar) {pos ++; s+= ch; continue}
for (i = 1; i < iLenSearch; i++) {
if (sSource[pos+i] != sSearch[i]) { found = false; break }
}
if (!found) {pos++; s+= ch; continue}
s += sReplace
pos += iLenSearch
}
string result = stringOf s
delete s
return result }
as i said the main difference with C and that may cause doxygen to interpret this code incorrectly is that in DXL , we dont have to use ";" .
thanks in advance
You must do three things to apply Doxygen successfully on DXL scripts:
1.) In Doxygen-GUI, 'Wizard' tab, section 'Mode' choose 'Optimize for C or PHP'
2.) The DXL code must be C-confom, i.e. each statement ends with a semicolon ';'
3.) In tab 'Expert' set language mapping for DXL and INC files in section 'Project' under 'EXTENSION_MAPPING':
dxl=C
inc=C
This all tells Doxygen to treat DXL scripts as C code.
Further, for DOORS to recognize a DXL file documented for DoxyGen as valid and bind it to a menu item, it must comply with certain header structure, consisting of single line and multi-line comment, e.g.
// <dxl-file>
/**
* #file <dxl-file>
* #copyright (c) ...
* #author Th. Grosser
* #date 01 Dec 2017
* #brief ...
*/

international chars in tcl/tk can't be handle

I use tcl shellicon command to extract icons, as it mentioned on wiki page below, there are some international character problems in it, then I write some code to test but it doesn't work, could anyone to help me correct it.
/*
* testdll.c
* gcc compile: gcc testdll.c -ltclstub86 -ltkstub86 -IC:\Users\L\tcc\include -IC:\Users\L\tcl\include -LC:\Users\L\tcl\lib -LC:\Users\L\tcc\lib -DUSE_TCL_STUBS -DUSE_TK_STUBS -shared -o testdll.dll
*/
#include <windows.h>
#include <tcl.h>
#include <stdlib.h>
int TestdllCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) {
char * path;
Tcl_DString ds;
if (objc > 2) {
Tcl_SetResult(interp, "Usage: testdll ?path?",NULL);
return TCL_ERROR;
}
if (objc == 2) {
path = Tcl_GetString(objv[objc-1]);
path = Tcl_TranslateFileName(interp, path, &ds);
if (path != TCL_OK) {
return TCL_ERROR;
}
}
Tcl_AppendResult(interp, ds, NULL);
return TCL_OK;
}
int DLLEXPORT Testdll_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "testdll", TestdllCmd, NULL, NULL);
Tcl_PkgProvide(interp, "testdll", "1.0");
return TCL_OK;
}
I compile it with:
gcc compile: gcc testdll.c -ltclstub86 -ltkstub86 -IC:\Users\USERNAME\tcc\include -IC:\Users\USERNAME\tcl\include -LC:\Users\USERNAME\tcl\lib -LC:\Users\USERNAME\tcc\lib -DUSE_TCL_STUBS -DUSE_TK_STUBS -shared -o testdll.dll
windows cmd shell run: tclsh testdll.tcl
load testdll
puts [testdll C:/Users/L/桌面]
the output is:
// This line isn't in the output, just to show the first line of output is a *EMPTY LINE*
while executing
"testdll 'C:/Users/L/桌面'"
invoked from within
"puts [testdll 'C:/Users/L/桌面']"
(file "testdll.tcl" line 2)
In fact, I want to print a line, whose content is "C:/Users/L/桌面"
I write this dll to debug how to replace Tcl_GetString,Tcl_TranslateFileName with Tcl_FSGetNormalizedPath, Tcl_FSGetNativePath, I wonder if it's clear?
Thank you!
Remove this:
if (path != TCL_OK) {
return TCL_ERROR;
}
You are comparing a char * to an int.
The manual page for Tcl_TranslateFileName says:
However, with the advent of the newer Tcl_FSGetNormalizedPath
and Tcl_FSGetNativePath, there is no longer any need to use this
procedure.
You should probably switch to more modern API call.

Removing comments with JFlex, but keeping line terminators

I'm writing lexical specification for JFlex (it's like flex, but for Java). I have problem with TraditionalComment (/* */) and DocumentationComment (/** */). So far I have this, taken from JFlex User's Manual:
LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace = {LineTerminator} | [ \t\f]
/* comments */
Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}
TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/"
EndOfLineComment = "//" {InputCharacter}* {LineTerminator}
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent = ( [^*] | \*+ [^/*] )*
{Comment} { /* Ignore comments */ }
{LineTerminator} { return LexerToken.PASS; }
LexerToken.PASS means that later I'm passing line terminators on output. Now, what I want to do is:
Ignore everything which is inside the comment, except new line terminators.
For example, consider such input:
/* Some
* quite long comment. */
In fact it is /* Some\n * quite long comment. */\n. With current lexer it will be converted to a single line. The output will be single '\n'. But I would like to have 2 lines, '\n\n'. In general, I would like that my output will always have the same number of lines as input. How to do it?
After couple of days I found a solution. I will post it here, maybe somebody will have the same problem.
The trick is, after recognizing that you are inside a comment - go once more through its body and if you spot new line terminators - pass them, not ignore:
%{
public StringBuilder newLines;
%}
// ...
{Comment} {
char[] ch;
ch = yytext().toCharArray();
newLines = new StringBuilder();
for (char c : ch)
{
if (c == '\n')
{
newLines.append(c);
}
}
return LexerToken.NEW_LINES;
}

How to get mach-o uuid of a running process?

to get UUID on mac i can use
dwarfdump -u path/to/compile/executable
also i can get UUID with simple crash
in 'Binary Images' section
Is the way to get UUID without crash on ios device?
An executable's (mach-o file) UUID is created by the linker ld and is stored in a load command named LC_UUID. You can see all load commands of a mach-o file using otool:
otool -l path_to_executable
> ...
> Load command 8
> cmd LC_UUID
> cmdsize 24
> uuid 3AB82BF6-8F53-39A0-BE2D-D5AEA84D8BA6
> ...
Any process can access its mach-o header using a global symbol named _mh_execute_header. Using this symbol you can iterate over the load commands to search LC_UUID. The payload of the command is the UUID:
#import <mach-o/ldsyms.h>
NSString *executableUUID()
{
const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1);
for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) {
if (((const struct load_command *)command)->cmd == LC_UUID) {
command += sizeof(struct load_command);
return [NSString stringWithFormat:#"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
command[0], command[1], command[2], command[3],
command[4], command[5],
command[6], command[7],
command[8], command[9],
command[10], command[11], command[12], command[13], command[14], command[15]];
} else {
command += ((const struct load_command *)command)->cmdsize;
}
}
return nil;
}

How to pass in psql password from program on Windows

I am currently working on PostgreSQL backup and restore functionality for my project. I have read this http://www.codeproject.com/Articles/37154/PostgreSQL-PostGis-Operations article and followed that approach to do this. It is working fine but recently I have changed the PostgreSQL authentication method to password in the pg_hba.con file. Hence it started prompting for the password whenever I execute psql.exe, pg_dump.exe, and pg_restore.exe. To provide the password through my project, I have used the "RedirectStandardInput" method. But it did not work and psql or pg_dump still prompt for the password. However "RedirectStandardOutput" and error methods are working fine.
I went through the PostgreSQL source code and found that GetConsoleMode and SetConsoleMode are used the remove the echo. I hope ( not sure ) it could be the reason, which is why I am unable to redirect the input.
PostgreSQL source code to prompt the password
simple_prompt(const char *prompt, int maxlen, bool echo)
{
int length;
char *destination;
FILE *termin,
*termout;
#ifdef HAVE_TERMIOS_H
struct termios t_orig,
t;
#else
#ifdef WIN32
HANDLE t = NULL;
LPDWORD t_orig = NULL;
#endif
#endif
destination = (char *) malloc(maxlen + 1);
if (!destination)
return NULL;
/*
* Do not try to collapse these into one "w+" mode file. Doesn't work on
* some platforms (eg, HPUX 10.20).
*/
termin = fopen(DEVTTY, "r");
termout = fopen(DEVTTY, "w");
if (!termin || !termout
#ifdef WIN32
/* See DEVTTY comment for msys */
|| (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
#endif
)
{
if (termin)
fclose(termin);
if (termout)
fclose(termout);
termin = stdin;
termout = stderr;
}
#ifdef HAVE_TERMIOS_H
if (!echo)
{
tcgetattr(fileno(termin), &t);
t_orig = t;
t.c_lflag &= ~ECHO;
tcsetattr(fileno(termin), TCSAFLUSH, &t);
}
#else
#ifdef WIN32
if (!echo)
{
/* get a new handle to turn echo off */
t_orig = (LPDWORD) malloc(sizeof(DWORD));
t = GetStdHandle(STD_INPUT_HANDLE);
/* save the old configuration first */
GetConsoleMode(t, t_orig);
/* set to the new mode */
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
}
#endif
#endif
if (prompt)
{
fputs(_(prompt), termout);
fflush(termout);
}
if (fgets(destination, maxlen + 1, termin) == NULL)
destination[0] = '\0';
length = strlen(destination);
if (length > 0 && destination[length - 1] != '\n')
{
/* eat rest of the line */
char buf[128];
int buflen;
do
{
if (fgets(buf, sizeof(buf), termin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
}
if (length > 0 && destination[length - 1] == '\n')
/* remove trailing newline */
destination[length - 1] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
fputs("\n", termout);
fflush(termout);
}
#else
#ifdef WIN32
if (!echo)
{
/* reset to the original console mode */
SetConsoleMode(t, *t_orig);
fputs("\n", termout);
fflush(termout);
free(t_orig);
}
#endif
#endif
if (termin != stdin)
{
fclose(termin);
fclose(termout);
}
return destination;
}
Please help me here, how to send the password to psql or pg_dump via C# code.
Since this is local to the application, the best thing to do is to set %PGPASSWORD% and then psql will not ask for the password. .pgpass could be used if you wanted to avoid supplying a password at all. In general you do not want to specify environment variables from the command line since they may show for other users but this is not a concern here.