Remove too deep folders in bash on OSX - directory

a program created folders recursively. it is too deep, the full path string length is longer than the MAX (getconf ARG_MAX), for example:
/A/B/C/A/B/C/A/B/C//A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C/A/B/C
……
so "sudo rm -fr /A" says "Bad address".
How to create a script to deal with it?
Thanks,

Interesting problem.
I guess you could create a command line tool with Xcode (file -> new project -> command line tool, insert code, then click the "run" toolbar button).
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSURL *url = [NSURL fileURLWithPath:#"/a/b/c/d/..."];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:url error:&error];
if (error) {
NSLog(#"%#", error);
}
}
return 0;
}

If it's a separate disk with its own filesystem mounted at /A, unmount it and reformat it.
If not, run something like this (very untested):
cd /A
then
cd A || cd B || cd C && rm -rf A* B* C*
and keep executing it, hitting up arrow to repeat and executing again till it works...
Good luck!

Related

using Qt's QProcess as popen (with ffmpeg rawvideo)

I inserted some code in a video application to export using ffmpeg
with stdin (rawideo rgba format), to quickly test that it worked I
used popen(), the tests went well and since the application is
written using Qt I thought of modify the patch using QProcess and
->write().
The application shows no errors and works properly but the generated
video files are not playable neither with vlc nor with mplayer while
those generated with popen() work perfectly with both. I have the
feeling that ->close() or ->terminate() does not properly close
ffmpeg and consequently the file, but I don't know how to verify it
nor I found alternative ways to end the executed command, beside
->waitForBytesWritten() should wait for the data to be written,
suggestions? Am I doing something wrong?
(Obviously I can't prepare a testable example it would take me more
time than the patch took)
Below is the code I entered, in the case #else the Qt code
Initialization
#if defined(EXPORT_POPEN) && EXPORT_POPEN == 1
pipe_frame.file = popen("/tmp/ffmpeg-rawpipe.sh", "w");
if (pipe_frame.file == NULL) {
return false;
}
#else
pipe_frame.qproc = new QProcess;
pipe_frame.qproc->start("/tmp/ffmpeg-rawpipe.sh", QIODevice::WriteOnly);
if(!pipe_frame.qproc->waitForStarted()) {
return false;
}
#endif
Writing a frame
#if defined(EXPORT_POPEN) && EXPORT_POPEN == 1
fwrite(pipe_frame.data, pipe_frame.width*4*pipe_frame.height , 1, pipe_frame.file);
#else
qint64 towrite = pipe_frame.width*4*pipe_frame.height,
written = 0, partial;
while(written < towrite) {
partial = pipe_frame.qproc->write(&pipe_frame.data[written], towrite-written);
pipe_frame.qproc->waitForBytesWritten(-1);
written += partial;
}
#endif
Termination
#if defined(EXPORT_POPEN) && EXPORT_POPEN == 1
pclose(pipe_frame.file);
#else
pipe_frame.qproc->terminate();
//pipe_frame.qproc->close();
#endif
edit
ffmpeg-rawpipe.sh
#!/bin/sh
exec ffmpeg-cuda -y -f rawvideo -s 1920x1080 -pix_fmt rgba -r 25 -i - -an -c:v h264_nvenc \
-cq:v 19 \
-profile:v high /tmp/test.mp4
I made some changes, I added the unbuffered flag to the open
pipe_frame.qproc->start("/tmp/ffmpeg-rawpipe.sh", QIODevice::WriteOnly|QIODevice::Unbuffered);
And therefore simplified the write
qint64 towrite = pipe_frame.width*4*pipe_frame.height;
pipe_frame.qproc->write(pipe_frame.data, towrite);
pipe_frame.qproc->waitForBytesWritten(-1);
I added a closeWriteChannel before closing the application (hoping that stopping the stdin ffmpeg pipe ends properly, just in case, I'm not sure it doesn't)
pipe_frame.qproc->waitForBytesWritten(-1);
pipe_frame.qproc->closeWriteChannel();
//pipe_frame.qproc->terminate();
pipe_frame.qproc->close();
But nothing changes, the mp4 file is created and contains data but from the mplayer log I see that it is misinterpreted, the video format is not recognized and it looks for an audio that is not there.
Fixed, adding waitForFinished() after closeWriteChannel(), closes stdin and wait for ffmpeg to terminate on its own.
pipe_frame.qproc->waitForBytesWritten(-1); // perhaps not necessary
pipe_frame.qproc->closeWriteChannel();
pipe_frame.qproc->waitForFinished();
pipe_frame.qproc->close();
edit
Note, even if initialized with the unbuffered flag, QProcess and QIODevice seem to buffer quite a lot, it seems as if waitForBytesWritten () is not working, and if you are feeding HD video you will go out of memory very quickly.

Qt copy file with sudo right

I handle the normal copying of files with Qt like this:
QFile::copy("/path/file", "/path/copy-of-file");
How can I now copy a file for which Sudo rights are required.
You can use QProcess and pkexec to execute a command as another user
pkexec allows an authorized user to execute PROGRAM as another user. If username is not specified, then the program will be executed as the administrative super user, root.
https://www.freedesktop.org/software/polkit/docs/0.105/pkexec.1.html
QProcess *proc = new QProcess(this);
proc->waitForFinished();
QString cmd = "pkexec /bin/cp /path/file /path/copy-of-file";
proc->start(cmd);
if(!proc->waitForStarted()) //default wait time 30 sec
{
qDebug() << "Cannot execute:" << cmd;
}
proc->waitForFinished();
proc->setProcessChannelMode(QProcess::MergedChannels);
if(proc->exitStatus() == QProcess::NormalExit
&& proc->exitCode() == QProcess::NormalExit){
qDebug() << "Success";
} else {
qDebug() << "Cannot copy file" << cmd;
}
run shell command, like this
sudo cp /path/file /path/copy-of-file
Set a password if necessary.:
$echo <password> | sudo -S <command>

SCP always returns the same error code

I have a problem copying files with scp. I use Qt and copy my files with scp using QProcess. And when something bad happens I always get exitCode=1. It always returns 1. I tried copying files with a terminal. The first time I got the error "Permission denied" and the exit code was 1. Then I unplugged my Ethernet cable and got the error "Network is unreachable". And the return code was still 1. It confuses me very much cause in my application I have to distinct these types of errors.
Any help is appreciated. Thank you so much!
See this code as a working example:
bool Utility::untarScript(QString filename, QString& statusMessages)
{
// Untar tar-bzip2 file, only extract script to temp-folder
QProcess tar;
QStringList arguments;
arguments << "-xvjf";
arguments << filename;
arguments << "-C";
arguments << QDir::tempPath();
arguments << "--strip-components=1";
arguments << "--wildcards";
arguments << "*/folder.*";
// tar -xjf $file -C $tmpDir --strip-components=1 --wildcards
tar.start("tar", arguments);
// Wait for tar to finish
if (tar.waitForFinished(10000) == true)
{
if (tar.exitCode() == 0)
{
statusMessages.append(tar.readAllStandardError());
return true;
}
}
statusMessages.append(tar.readAllStandardError());
statusMessages.append(tar.readAllStandardOutput());
statusMessages.append(QString("Exitcode = %1\n").arg(tar.exitCode()));
return false;
}
It gathers all available process output for you to analyse. Especially look at readAllStandardError().

Unix If file exists, rename

I am working on a UNIX task where i want check if a particular log file is present in the directory or not. If it is present, i would like to rename it by appending a timestamp at the end. The format of the file name is as such: ServiceFileName_0.log
This is what i have so far but it wouldn't rename when i run the script, even though there is a file with the name ServiceFileName_0.log present.
renameLogs()
{
#If a ServiceFileName log exists, rename it
if [ -f $MY_DIR/logs/ServiceFileName_0.log ];
then
mv ServiceFileName_0.log ServiceFileName_0.log.%M%H%S
fi
}
Pls Help!
Thanks
renameLogs()
{
if [ -f $MY_DIR/logs/ServiceFileName_0.log ]
then mv $MY_DIR/ServiceFileName_0.log $MY_DIR/ServiceFileName_0.log.$(date +%M%H%S)
fi
}
Use the directory prefix consistently. Also you need to specify the time properly, as shown.
Better, though (less repetition):
renameLogs()
{
logfile="$MY_DIR/logs/ServiceFileName_0.log"
if [ -f "$logfile" ]
then mv "$logfile" "$logfile.$(date +%H%M%S)"
fi
}
NB: I've reordered the format from MMHHSS to the more conventional HHMMSS order. If you work with date components too, you should seriously consider using the ordering recommended by ISO 8601, which is [YYYY]mmdd. It groups all the log files for a month together in an ls listing, which is usually helpful. Using ddmm order means that the files for the first of each month are grouped together, then the files for the second of each month, etc. This is usually less desirable.
You might need to prefix the file name with the $MY_DIR path, just like you did in the test.
You could replace this:
mv ServiceFileName_0.log ServiceFileName_0.log.%M%H%S
with this
mv $MY_DIR/logs/ServiceFileName_0.log $MY_DIR/logs/ServiceFileName_0.log.%M%H%S
This isn't your apparent immediate problem, but the if construct is wrong: it introduces a time-of-check to time-of-use race condition. In between the if [ -f check and the mv, some other process could come along and change things so you can't move the file anymore even though the check succeeded.
To avoid this class of bugs, always write code that starts by attempting the operation you want to do, then if it failed, figure out why. In this case, what you want is to do nothing if the source file didn't exist, but report an error if the operation failed for any other reason. There is no good way to do that in portable shell, you need something that lets you inspect errno. I'd probably write this C helper:
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "usage: %s source destination\n", argv[0]);
return 2;
}
if (rename(argv[1], argv[2]) && errno != ENOENT) {
fprintf(stderr, "rename '%s' to '%s': %s\n",
argv[1], argv[2], strerror(errno));
return 1;
}
return 0;
}
and then use it like so:
renameLogs()
{
( cd "$MY_DIR/logs"
rename_if_exists ServiceFileName_0.log ServiceFileName_0.log.$(date +%M%H%S)
)
}
The ( cd construct fixes your immediate problem, and unlike the other suggestions, avoids another race in which some other process comes along and messes with the logs directory or its parent directories.
Obligatory shell scripting addendum: Always enclose variable expansions in double quotes, except in the rare cases where you want the expansion to be subject to word splitting.

how can i password protect my sqlite db in C. is it possible to partition the sqlite db?

I am working on embedded system and the device has linux kernel with sqlite database. Wanted to know if the sqlite database can be partitioned with secure and normal partitions.
How can the encryption be achieved for sqlite database file in linux.
Maybe I am too late to answer this question, but I was facing this issue from couple of days and couldn't find any solid solution online. I have found solution hence I am sharing it.
//Steps to make sqlite database authenticated
download sqlite3 amalgamation zip file
unzip the file. The file should contain shell.c, sqlite3.c, sqlite3.h, sqlite3ext.h
click on find the link here
3a. Open userauth.c and copy the entire code and paste it at the end of your sqlite3.c file.
3b. Open sqlite3userauth.h and copy the entire code and pase it at the end of your sqlite3.h file.
create a output file for executing the command in shell
command: gcc -o sqlite3Exe shell.c sqlite3.c -DSQLITE_USER_AUTHENTICATION -ldl -lpthread
4a. Youll get error no such file "sqlite3userauth.h" in your shell.c file:
solution: go to that file and comment th line.(this is because youve already included the necessary code when you copied sqlite3auth.h into sqlite3.h)
4b. Test your output file by running ./sqlite3Exe (this is the name youve given to the output file generated in previous step). you'll get sqlite console.
4c. Create a database and on the authentication flag:
command1: .open dbname.db
command2: .auth on
command3: .exit//command 3 is optional
Building the library
5a: creating object file
//Compiling sqlite3.c to create object after appending our new code
command: gcc -o sqlite3.o -c sqlite3.c -DSQLITE_USER_AUTHENTICATION
With this command, we generate object file which we can use to compile our c file.
Create c file to authenticate your database:
//authUser.c
#include "stdio.h"
#include "stdlib.h"
#include "sqlite3.h"
int main(int argc,char * argv[]){
int a = 10;
int rtn, rtn2;
sqlite3 *db;
char *sql, *zErMsg;
rtn = sqlite3_open("dbname.db", &db);
rtn = sqlite3_user_add(db,"username","password",2, 1);//last but one param is for number of bytes for password, last param is for weather the user is admin or not
if(rtn){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Protected database successfully\n");
}
sqlite3_close(db);
return 0;
}
Compiling the program
//Compiling the program
command1: gcc authUser.c sqlite3.o -lpthread -ldl
command2: ./a.out //Output:protected database successfully
create c file to create table if the user is authenticated
//createTable.c
#include "stdio.h"
#include "stdlib.h"
#include "sqlite3.h"
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i less then argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc,char * argv[]){
int a = 10;
int rtn, rtn2;
sqlite3 *db;
char *sql, *zErMsg;
rtn = sqlite3_open("dbname.db", &db);
rtn = sqlite3_user_authenticate(db, "user","password",2);
if(rtn){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
sql = "create table newtable(id int not null primary key, name varchar(100) not null)";
//sql = "insert into newtable values(5, 'ishwar')";
rtn = sqlite3_exec(db, sql, callback, 0, &zErMsg);
if(rtn != SQLITE_OK){
sqlite3_free(zErMsg);
}else{
fprintf(stdout, "Table created successfully \n");
//fprintf(stdout, "inserted successfully \n");
}
sqlite3_close(db);
return 0;
}`
compiling the program
//Compiling the program
command1: gcc createTable.c sqlite3.o -lpthread -ldl
command2: ./a.out //Output:Table created successfully
Create c file to add values in table
from the previous code, you can see two sql variable and two fprintf inside else, now uncomment the commented line and comment the other one. and runt the same command as above
output: Inserted successfully
And youre done, try experimenting with the code, change the values of sqlite3_user_authenticate function you wont be able to do these operations,at max you may be able to open database(when you comment the sqlite3_user_authenticate functon.nothing else)
Testing it with shell
Run the command: ./sqlite3Exe (the output file we created in step 4)
command1: .open dbname.db
command2: .tables //you should get error, user_auth
Thank you(please feel free to mail me in case of any problem: ishwar.rimal#gmail.com)
for encryption to be achieved with SQLite, you need to license some extensions from the SQLite author.
http://www.sqlite.org/support.html
David Segleau here, Director of Product Management for Berkeley DB.
The recent 5.1 release of Oracle Berkeley DB (5.1.7) integrates the Berkeley DB encryption feature with the SQLite-based SQL API. You can read about it here.

Resources