#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv){
FILE *fp = fopen("1.pass", "r");
struct {char pass[20], msg_err[20];} pwfile = {{0}};
char ptr[0];
if(!fp || argc != 2)
return -1;
fread(pwfile.pass, 1, 20, fp);
pwfile.pass[19] = 0;
ptr[atoi(argv[1])] = 0;
fread(pwfile.msg_err, 1, 19, fp);
fclose(fp);
if(!strcmp(pwfile.pass, argv[1])) {
setuid(0);
execl("/bin/sh", "sh", 0);
} else
puts(pwfile.msg_err);
return 0;
}
Hello there.
I give on input to the program a password. The program checks this password, which is in 1.pass. If all is correct - opens to me a shell, if it not correct - print ACCESS DENIED.
In my cases, it didn't open shell up to me, I don't know why. Any ideas what I missed?
char ptr[0];
ptr[atoi(argv[1])] = 0;
This is not legal C++, as there are no zero sized arrays in C++. Even if some C++ compilers offer zero sized arrays as an extension, this particular code doesn't do anything useful, and may or may not format your hard disk.
Related
It's a real-time capture system, I need to get the latest changes from a file which is occasionally edited(mostly add content) by other applications.
In other words, how can I get content that added in the period when I open it without reopening the file?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
ifstream tfile("temp.txt",ios::in);
if(!tfile){
cout<<"open failed"<<endl;
return 0;
}
string str;
while(1){
if(tfile.eof())
continue;
getline(tfile,str);
cout<<str<<endl;
}
tfile.close();
}
C++ / C Solution
If you are looking for a c++ solution you can use the following functions that I had created a while back:
#include <iostream>
#include <string>
// For sleep function
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
using namespace std;
void watchLogs(const char *FILENAME) {
FILE * f;
unsigned size = 0;
f = fopen(FILENAME , "r");
char c;
while (true) {
if (!size) { // will print content of your log file. If you just want the updates you can remove the current content except the first two lines;
fseek(f, 0, SEEK_END);
size =(unsigned long)ftell(f) ;
fseek (f, 0, SEEK_SET);
char buffer[size + 1];
fread ( buffer, 1, size, f );
buffer[size] = '\0';
cout << buffer << "\n";
}
else if ((c = (char)fgetc(f)) >= 0) {
fseek(f, 0, SEEK_END); // reach end of file
int BUFFER_SIZE =(unsigned long)ftell(f) - size; // save the length of the update to your logs
char buffer[BUFFER_SIZE + 1]; // prepare a buffer to print the characters
fseek(f,-BUFFER_SIZE,SEEK_END); // rewind BUFFER_SIZE characters before the EOF
int i = 0;
do {buffer[i++] = (char)fgetc(f);} while(i < BUFFER_SIZE); // copy to buffer
buffer[i] = '\0'; // don't forget to NULL terminate your buffer
cout << buffer << "\n";
size += i; // increment the size of the current file
}
}
sleep(3); // updates are checked every 3 seconds to avoid running the cpu at fullspeed, you could set the new logs to show up every minutes or every seconds, up to you.
fclose(f);
}
And you can test it with:
int main(int argc, char **argv) {
if (argc < 2)
return 1;
const char *FILENAME = argv[1];
watchLogs(FILENAME);
return 0;
}
./a.out mysql_binary.log
I could have used stringstreamer but I like that this version would also work with c files with some minor tweaks (can't use string).
I hope you will find it helpful!
NB: This assume that your file will only grow and that the changes will be appended to the end of your file.
NB2: This program is not segfault proof, you may want to check the return of fopen etc
Inotify
If you use Linux you could also potentially go for inotify:
Download inotify: sudo apt-get install -y inotify-tools
Then create the following script mywatch.sh
while inotifywait -e close_write $1; do ./$1; done
Give permission to execute:
add chmox +x mywatch.sh
and call it with ./watchit.sh mysql_binary.log
I made a simple C programme that demonstrates the issue. Here it is.
#include <stdio.h>
int main(int argc, const char * argv[]) {
char buffer[128];
memset(buffer, 0, sizeof(buffer));
printf("Type data:\n");
scanf("%126s", buffer);
printf("%s\n", buffer);
getchar();
return 0;
}
The problem is that when the application is waiting for user input with scanf() and user user wants to edit line he typed, and to do move caret with arrows, the caret is not moving but new ugly input is inserted.
For some reason it does not handle the keys in a way I expect. I'm not able to go to the previous typed line with the up key, as well.
Obviously I should deliberately enable this behaviour. Could you advice, how can I do that?
Use readline(). Here's a simple example:
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <ctype.h>
#define MAX_LINE_LEN 80
int main() {
char *line_buffer;
int n, i;
while (1) {
line_buffer = readline("Say something: ");
if (!line_buffer) break;
for (i=0; line_buffer[i]; i++) {
line_buffer[i] = toupper(line_buffer[i]);
}
printf("YOU SAID: %s\n",line_buffer);
}
putchar('\n');
return 0;
}
/* (Compile with cc foo.c -lreadline -o foo) */
I have written a simple program to read the content of a text file and I compiled it with cl.exe (visual studio compiler). The program compiles, and when I run it, it starts normally and the moment it goes past the reading and printing of the data it crashes brutally... Here's my code :
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <fstream>
#include <string>
int main (int argc, char *argv[])
{
char filename[256];
char d1[9];
char d2[8];
if (argc > 1) //lecture de l'argument
strcpy(filename, argv[1]);
else {
printf("Usage: read_file");
return 0;
}
FILE *f = fopen(filename, "r");
if (f == NULL) {
printf("Cannot find file \'%s\'\n", filename);
return 0;
}
printf("file opened\n");
rewind(f);
fscanf(f, "%s %s", d1, d2);
printf("%s %s",d1,d2);
fclose(f);
return 1;
}
When I compile it with gcc it works just fine however. The thing is, I need this to run with visual studio compiler...
First of all, you should have posted your input example.
Anyway, as other people have stated d1 and d2 are too small and are not storing the C-Null terminator. Just make them larger (d1[10], d2[9]).
Finally, you are programming in c++ so therefore I would recommend using the c++ libraries. Your code would be simpler and would not mix c and c++.
Best regards.
Here is my Code
This code is trying to remove special characters like ",',{,},(,) from a .txt file and replace them with blank space.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <iostream>
#include <time.h>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
int fd;
int i;
int j;
int len;
int count = 0;
int countcoma = 0;
int countquote = 0;
char buf[10];
char spec[] = {',','"',':','{','}','(',')','\''};
fd = open(argv[1],O_RDWR,0777);
while (read(fd,buf,10) != 0) {
len = strlen(buf);
for (i=0;i<len;i++) {
for (j=0;j<8;j++) {
if (buf[i]==spec[j]) {
count =1;
countquote=0;
if (j==1) {
if (countcoma == 0) {
countcoma++;
}
if (countcoma == 1) {
countcoma--;
}
}
if ((j==7) && (countcoma ==1)) {
countquote = 1;
}
break;
}
}
//cout<<countquote;
if ((count != 0) && (countquote == 0)) {
buf[i] = ' ';
}
count = 0;
}
lseek(fd, -sizeof(buf), SEEK_CUR);
write(fd,buf,sizeof(buf));
memset(buf,' ',10);
}
return 0;
}
Now i want the single quotes that are inside the double quotes in my file remain untouched, but all the special characters are replaced with space as mentioned in the code.
I want these kind of single quotes to remain untouched "what's" but after i run the file it becomes what s instead of what's
Have a look at regex and other libraries. (When on UNIX type man regex.) You don't have to code this anymore nowadays, there are a zillion libraries that can do this for you.
Ok, so the problem with your code is that you are doing one thing, that you then undo in the next section. In particular:
if (countcoma == 0) {
countcoma++;
}
if (countcoma == 1) {
countcoma--;
}
Follow the logic: We come in with countcoma as zero. So the first if is true, and it gets incremented. It is now 1. Next if says if (countcoma == 1) so it is now true, and we decrement it.
I replaced it with countcoma = !countcoma; which is a much simpler way to say "if it's 0, make it 1, if it's 1, make it 0. You could put anelseon the back of the firstif` to make the same thing.
There are also a whole bunch of stylistic things: For example hard-coded constants, writing back into the original file (means that if there is a bug, you lose the original file - good thing I didn't close the editor window with my sample file...), including half the universe in header files, and figuring which of the spec characters it is based on the index.
It seems to me that your code is suffering from a more general flaw than what has been pointed out before:
char buf[10]; /* Buffer is un-initialized here!! */
while (read(fd,buf,10) != 0) { /* read up to 10 bytes */
len = strlen(buf); /* What happens here if no \0 byte was read? */
...
lseek(fd, -sizeof(buf), SEEK_CUR); /* skip sizeof(buf) = 10 bytes anyway */
write(fd,buf,sizeof(buf)); /* write sizeof(buf) = 10 bytes anyway */
memset(buf,' ',10); /* initialize buf to contain all spaces
but no \0, so strlen will still result in
reading past the array bounds */
I am executing a system() function which returns me a file name. Now I dont want to display the output on the screen(ie the filename) or pipe to a newfile. I just want to store it in a variable. is that possible? if so, how?
thanks
A single filename? Yes. That is certainly possible, but not using system().
Use popen(). This is available in c and c++, you've tagged your question with both but are probably going to code in one or the other.
Here's an example in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *fpipe;
char *command = "ls";
char c = 0;
if (0 == (fpipe = (FILE*)popen(command, "r")))
{
perror("popen() failed.");
exit(EXIT_FAILURE);
}
while (fread(&c, sizeof c, 1, fpipe))
{
printf("%c", c);
}
pclose(fpipe);
return EXIT_SUCCESS;
}
Well,There is one more easy way by which you can store command output in a file which is called redirection method. I think redirection is quite easy and It will be useful in your case.
so For Example this is my code in c++
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int main(){
system("ls -l >> a.text");
return 0;
}
Here redirection sign easily redirect all output of that command into a.text file.
You can use popen(3) and read from that file.
FILE *popen(const char *command, const char *type);
So basically you run your command and then read from the FILE returned. popen(3) works just like system (invokes the shell) so you should be able to run anything with it.
Here is my C++ implementation, which redirects system() stdout to a logging system. It uses GNU libc's getline(). It will throw an exception if it can't run the command, but will not throw if the command runs with non-zero status.
void infoLogger(const std::string& line); // DIY logger.
int LoggedSystem(const string& prefix, const string& cmd)
{
infoLogger(cmd);
FILE* fpipe = popen(cmd.c_str(), "r");
if (fpipe == NULL)
throw std::runtime_error(string("Can't run ") + cmd);
char* lineptr;
size_t n;
ssize_t s;
do {
lineptr = NULL;
s = getline(&lineptr, &n, fpipe);
if (s > 0 && lineptr != NULL) {
if (lineptr[s - 1] == '\n')
lineptr[--s ] = 0;
if (lineptr[s - 1] == '\r')
lineptr[--s ] = 0;
infoLogger(prefix + lineptr);
}
if (lineptr != NULL)
free(lineptr);
} while (s > 0);
int status = pclose(fpipe);
infoLogger(String::Format("Status:%d", status));
return status;
}