Can't run execv - c++

I've been trying to run command using exevp as follows:
char *args[11];
args[0] = (char*)lgulppath.c_str();
args[1] = (char*)"-i";
args[2] = (char*)sniffer_interface.c_str();
args[3] = (char*)"-r";
args[4] = (char*)pcapfileLimit.c_str();
args[5] = (char*)"-C";
args[6] = (char*)"1";
args[7] = (char*)"-f";
args[8] = (char*)serverip_filter.c_str();
args[9] = (char*)"-o";
args[10] = (char*)lpipepath.c_str();
execv("/usr/sbin/program",args);
this works. HOWEVER, when I want to have the first parameter "/usr/sbin/program" as a parameter say:
string str = "/usr/sbin/program";
//char* args is assigned as above
execv(str.c_str(),args);
this fails and returns -1. I CAN'T GET WHY THOUGH.
Thanks everybody

Null terminate the arguments you pass to execv. Something like
char *args[12];
// other args..
args[11] = (char*) 0;

Related

Is there a way to copy and paste data while simultaneously increasing a number in that data each time?

Basically I have in my program -
team[0].game[2] = loadvar[1];
team[0].game[3] = loadvar[2];
team[0].game[4] = loadvar[3];
team[0].game[5] = loadvar[4];
team[0].game[6] = loadvar[5];
team[0].game[7] = loadvar[6];
team[0].game[8] = loadvar[7];
team[0].game[9] = loadvar[8];
team[0].game[10] = loadvar[9];
team[0].game[11] = loadvar[10];
team[0].game[12] = loadvar[11];
team[1].game[1] = loadvar[13];
team[1].game[2] = loadvar[14];
team[1].game[3] = loadvar[15];
team[1].game[4] = loadvar[16];
team[1].game[5] = loadvar[17];
team[1].game[6] = loadvar[18];
team[1].game[7] = loadvar[19];
team[1].game[8] = loadvar[20];
team[1].game[9] = loadvar[21];
team[1].game[10] = loadvar[22];
team[1].game[11] = loadvar[23];
team[1].game[12] = loadvar[24];
team[2].game[1] = loadvar[26];
team[2].game[2] = loadvar[27];
team[2].game[3] = loadvar[28];
team[2].game[4] = loadvar[29];
team[2].game[5] = loadvar[30];
team[2].game[6] = loadvar[31];
team[2].game[7] = loadvar[32];
team[2].game[8] = loadvar[33];
team[2].game[9] = loadvar[34];
team[2].game[10] = loadvar[35];
team[2].game[11] = loadvar[36];
team[2].game[12] = loadvar[37];
team[3].game[1] = loadvar[39];
team[3].game[2] = loadvar[40];
team[3].game[3] = loadvar[41];
team[3].game[4] = loadvar[42];
team[3].game[5] = loadvar[43];
team[3].game[6] = loadvar[44];
team[3].game[7] = loadvar[45];
team[3].game[8] = loadvar[46];
team[3].game[9] = loadvar[47];
team[3].game[10] = loadvar[48];
team[3].game[11] = loadvar[49];
team[3].game[12] = loadvar[50];
team[4].game[1] = loadvar[52];
team[4].game[2] = loadvar[53];
team[4].game[3] = loadvar[54];
team[4].game[4] = loadvar[55];
team[4].game[5] = loadvar[56];
team[4].game[6] = loadvar[57];
team[4].game[7] = loadvar[58];
team[4].game[8] = loadvar[59];
team[4].game[9] = loadvar[60];
team[4].game[10] = loadvar[61];
team[4].game[11] = loadvar[62];
team[4].game[12] = loadvar[63];
I'm retrieving the data from a text file.
Basically, in the program, I'm having to copy and paste the same thing over and over again, and increasing the array number for the team and loadvar. Is there anyway I can copy and paste it, and it do the number increasing for me?
Simply don't copy + paste, rather use loops to do the incrementing numbers, e.g. for
int v = 1;
for (int t = 0; t < 5; ++t)
{
for (int g = 1; g <= 12; ++g)
{
team[t].game[g] = loadvar[v++];
}
}
I've kept game indexed from 1-12 as in your question, but I suspect you might mean to index from 0-11. Be careful of this common source of bug for beginner programming.
If you really want to copy and paste, you can write something like this
int i = 0;
int j = 2;
int k = 1;
team[i].game[j++] = loadvar[k++];
team[i].game[j++] = loadvar[k++];
and so on. However the shorter and less error prone way would be two nested for loops.

Error using SHFileOperation() to copy a folder

I am trying to use SHFileOperation() to copy a folder, but get this error:
a value of type "const char *" cannot be assigned to an entity of type "PCZZWSTR"
for both s.pTo and s.pFrom.
The code I'm using is:
SHFILEOPSTRUCT s = { 0 };
s.hwnd = hWnd;
s.wFunc = FO_COPY;
s.fFlags = FOF_SILENT;
s.pTo = "C:\\Users\\styler\\Desktop\\Folder1\0";
s.pFrom = "C:\\Users\\styler\\Desktop\\Software\\Folder2\\Folder3\\*\0";
SHFileOperation(&s);
What am I doing wrong in s.pTo and s.pFrom? I am setting those equal to the target folder and the source folder, but why is this not working?
The compiler is telling you that you are trying to assign char string literals to wchar_t string pointers (PCZZWSTR = CONST WCHAR *). That means you must be compiling with UNICODE defined, where SHFileOperation() maps to SHFileOperationW() which expects wchar_t* string pointers instead of char* string pointers.
So, you need to prefix your string literals with the L prefix, eg:
SHFILEOPSTRUCT s = { 0 };
s.hwnd = hWnd;
s.wFunc = FO_COPY;
s.fFlags = FOF_SILENT;
s.pTo = L"C:\\Users\\styler\\Desktop\\Folder1\0";
s.pFrom = L"C:\\Users\\styler\\Desktop\\Software\\Folder2\\Folder3\\*\0";
SHFileOperation(&s);
Or, since you are actually using the TCHAR version of SHFileOperation(), use the TEXT() macro to match your string literals to the actual character type used by TCHAR:
SHFILEOPSTRUCT s = { 0 };
s.hwnd = hWnd;
s.wFunc = FO_COPY;
s.fFlags = FOF_SILENT;
s.pTo = TEXT("C:\\Users\\styler\\Desktop\\Folder1\0");
s.pFrom = TEXT("C:\\Users\\styler\\Desktop\\Software\\Folder2\\Folder3\\*\0");
SHFileOperation(&s);

Unable to call SecItemAdd Successfully

I'm trying to add a simple string secret to they keychain in macOS, via the C++ APIs. Unfortunately, I can't get my call to SecItemAdd to work. I know it is because my value for the kSecValueRef key is the wrong type, but so far Google/Apple docs/existing StackOverflow questions have yet to reveal to me what type I should be using, and how to create it. Here's what I have so far:
CFStringRef keys[4];
keys[0] = kSecClass;
keys[1] = kSecValueRef;
keys[2] = kSecAttrAccount;
keys[3] = kSecAttrService;
CFTypeRef values[4];
values[0] = kSecClassGenericPassword;
values[1] = CFSTR("password");
values[2] = CFSTR( "account-1" );
values[3] = CFSTR( "service-1" );
CFDictionaryRef attributes = CFDictionaryCreate
(
( CFAllocatorRef )NULL,
( const void ** )keys,
( const void ** )values,
4,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks
);
CFShow(attributes);
OSStatus status = SecItemAdd(attributes, NULL);
So what should I be putting for my kSecValueRef? I've tried making a reference to a CFStringRef, but that didn't work. I also see that in the Apple docs it says:
The corresponding value, depending on the item class requested, is of type SecKeychainItem, SecKey, SecCertificate, or SecIdentity.
But I don't have a SecKeychainItem because I haven't made added the item yet, and the other types don't seem right for just a normal string.
Thoughts?
Figured it out! For simple data, such as a string, you should use the kSecValueData key. That will let you just pass in a CFStringRef.
Example:
CFStringRef keys[4];
keys[0] = kSecClass;
keys[1] = kSecAttrAccount;
keys[2] = kSecAttrService;
keys[3] = kSecValueData;
CFTypeRef values[4];
values[0] = kSecClassGenericPassword;
values[1] = CFSTR( "account-15" );
values[2] = CFSTR( "service-126" );
values[3] = CFSTR( "password" );

What wrong I have done? The function of GetDiskFreeSpaceExA didn't work at all

I tried to use GetDiskFreeSpaceExA function, but it doesn't work:
int drvNbr = PathGetDriveNumber(db7zfolderw);
if (drvNbr == -1) // fn returns -1 on error
{
const char * errmsg = "error occured during get drive number";
strcpy_s(retmsg, strlen(errmsg) + 1, errmsg);
return -3;
}
char driverletter = (char)(65 + drvNbr);
string driverstr(1, driverletter);
driverstr = driverstr + ":";
PULARGE_INTEGER freespace = 0;
PULARGE_INTEGER totalnumbtype = 0;
PULARGE_INTEGER totalnumberfreebyte = 0;
fileSize = SzArEx_GetFileSize(&db, i);
BOOL myresult=GetDiskFreeSpaceExA(
driverstr.c_str(),
freespace,
totalnumbtype,
totalnumberfreebyte
);
The value of variable freespace is 0. I have no idea why it didn't work if the value of variable which is driverstr.c_str() was D:?
Thanks for your help.
You need to supply pointers to variables that will hold the value returned. Right now you a re supplying null pointers so nothing is retured:
::ULARGE_INTEGER freespace{};
::ULARGE_INTEGER totalnumbtype{};
::ULARGE_INTEGER totalnumberfreebyte{};
::BOOL myresult
{
::GetDiskFreeSpaceExA
(
driverstr.c_str()
, &freespace
, &totalnumbtype
, &totalnumberfreebyte
)
};
It would also be a good idea to use wide char versions of these functions.

Calling a Oracle procedure with output variables using OCILIB

I have a procedure with the following signature:
procedure countryExists(iCountryName in varchar2, oCount out integer)
When I run it using OCILIB, I can't get the right value for oCount. If I register it as integer (using OCI_RegisterInt), I get the error:
ORA-03116: invalid buffer length passed to a conversion routine
If I register it as a string, it runs, but OCI_GetString returns a null pointer and OCI_GetInt returns 0 (instead of the expected result 1).
The test code is:
int init = OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT|OCI_ENV_CONTEXT);
OCI_Connection *cn = OCI_ConnectionCreate("mydb", "myuser", "mypass", OCI_SESSION_DEFAULT);
OCI_Statement *st = OCI_StatementCreate(cn);
int resultprepare = OCI_Prepare(st, "call mypackage.countryExists('BRAZIL', :oCount)");
//int registercount = OCI_RegisterString(st, ":oCount", 100);
int registercount= OCI_RegisterInt(st, ":oCount");
int executeresult = OCI_Execute(st);
OCI_Error *err1 = OCI_GetLastError();
const char *error1 = OCI_ErrorGetString(err1);
OCI_Resultset *resultset = OCI_GetResultset(st);
const wchar_t *valstr = OCI_GetString(resultset, 1);
int valint = OCI_GetInt(resultset, 1);
OCI_Error *err2 = OCI_GetLastError();
const char *error2 = OCI_ErrorGetString(err2);
Running the procedure using, for example, PL/SQL Developer works fine.
Is this the right way of calling procedures using OCILIB?
Also note that I'm using the mixed version of the library.
You're not coding in Java....
Here is the right way to do it :
OCI_Connection *cn;
OCI_Statement *st;
int count;
OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT|OCI_ENV_CONTEXT);
cn = OCI_ConnectionCreate("mydb", "myuser", "mypass", OCI_SESSION_DEFAULT);
st = OCI_StatementCreate(cn);
OCI_Prepare(st, "begin mypackage.countryExists('BRAZIL', :oCount); end;");
OCI_BindInt(st, ":oCount", &count);
OCI_Execute(st);
Check the OCILIB documentation and/or manual
Vincent