I am trying to compare a encrypted string that is taken from each line of a file to AAAA-ZZZZ until it finds its match of the password. I am guaranteed that the user password is of 4 characters. What I am trying to do is take in the file using LowLevel IO and output to a new file with the decrypted passwords of each line. I am not the best at C programming yet so please be gentle. I need direction on how to create an array or list going from AAAA all the way to ZZZZ and then comparing each to the decrypted version of the file line.
How to decrypt the file line by line and save it to a char []
How to compare each line to another char [] until password is found
For Example:
if the line is $1$6gMKIopE$I.zkP2EvrXHDmApzYoV.B. and the next line is $1$pkMKIcvE$WQfqzTNmcQr7fqsNq7K2p0. Assuming the resulting password after decryption is ABSZ and TAZE the new file will result it ABSZ on the first line and TAZE for the second line.
This is what I have so far:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void pdie(const char *);
void die(const char *);
#define BUFFER_SIZE 1024
int main(void)
{
char *pass;
int rfd;
int wfd;
char buffer[BUFFER_SIZE];
char *bp;
int bufferChars;
int writtenChars;
if ((rfd = open("pass.txt", O_RDONLY, 0)) < 0)
pdie("Open failed");
if ((wfd = open("passout.txt", O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
pdie("Open failed");
while (1)
{
if ((bufferChars = read(rfd, buffer, BUFFER_SIZE)) > 0)
{
printf("%s", buffer);
bp = buffer;
pass = crypt(getpass(all(4,4,'a','z')), *bp);
printf(pass);
while (bufferChars > 0)
{
if ((writtenChars = write(wfd, bp, bufferChars)) < 0)
pdie("Write failed");
bufferChars -= writtenChars;
bp += writtenChars;
}
}
else if (bufferChars == 0)
break;
else
pdie("Read failed");
}
close(rfd);
close(wfd);
return 0;
}
void pdie(const char *mesg) {
perror(mesg);
exit(1);
}
void die(const char *mesg) {
fputs(mesg, stderr);
fputc('\n', stderr);
exit(1);
}
int inc(char *c,char begin, char end){
if(c[0]==0) return 0;
if(c[0] == end){ // This make the algorithm to stop at char 'f'
c[0]=begin; // but you can put any other char
return inc(c+sizeof(char), begin, end);
}
c[0]++;
return 1;
}
int all(int a, int n,char begin, char end){
int i,j;
char *c = malloc((n+1)*sizeof(char));
for(i=a;i<=n;i++){
for(j=0;j<i;j++) c[j]=begin;
c[i]=0;
do {
printf("%s\n",c);
} while(inc(c,begin,end));
}
free(c);
}
here is the file:
$1$6gMKIopE$I.zkP2EvrXHDmApzYoV.B.
$1$pkMKIcvE$WQfqzTNmcQr7fqsNq7K2p0
$1$0lMKIuvE$7mOnlu6RZ/cUFRBidK7PK.
Related
The problem I'm running into is that when the file tries to copy, it only copies part of the file and the other part is a bunch of unreadable characters. This is for an academic assignment that wants us to use barrier synchronization so we need to use open, write, and read.
I've reworked the thread function many times but if it's the problem I can change it again, I haven't changed the for loop in main at all so even that might be the problem but I don't know what it could be. Lastly, I don't really know what to do with the barrier; my professor was very vague and I can't really ask him questions, maybe the barrier is the part that I'm truly missing.
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
typedef struct args {
int fd;
int copy;
long int start;
long int size;
}threadarg;
int barrier = 0;
int main(int argc, char *argv[])
{
void usage(char *progname);
int chkdst(char **argv);
void die(char *why);
long int filesize(char *srcpath);
void buildpath(char *src, char *dst, char **dstpath);
int isvalid(char *path, char *dst);
void *dowork(void *arg);
if (argc < 4) usage("a8");
int workers, i;
char *check;
workers = strtol(argv[3], &check, 10);
if (!check) usage("a8");
else if (!chkdst(&argv[2])) die ("DST not valid!");
long int size = filesize(argv[1]);
if (size == -1) die ("Could not find file size");
char *dstpath; buildpath(argv[1], argv[2], &dstpath);
if (!isvalid(argv[1], dstpath)) die ("scr not valid!");
long int chunksize = size / workers;
long int remainder = size % workers;
int fd = open(argv[1], O_RDONLY);
int copy = open(dstpath, O_CREAT | O_RDWR, 0644);
if (fd < 0 || copy < 0) die("Fail to access or create files");
barrier = workers;
threadarg threadargs[workers];
pthread_t threads[workers];
for (i = 0; i < workers; i++)
{
threadargs[i].fd = fd;
threadargs[i].copy = copy;
threadargs[i].start = i * chunksize;
if (i == workers - 1)
threadargs[i].size = chunksize + remainder;
else
threadargs[i].size = chunksize;
if (pthread_create(&threads[i], NULL, dowork, (void *) &threadargs[i]))
die("Thread Creation Failure");
}
for (i = 0; i < workers; i++)
pthread_join(threads[i], NULL);
}
void usage(char *progname)
{
fprintf(stderr, "./%s srcpath dstpath workercount\n", progname);
exit(0);
}
void die(char *why)
{
fprintf(stderr, "Program Killed...\nReason: %s\n", why);
exit(1);
}
long int filesize(char *srcpath)
{
struct stat st;
if(stat(srcpath, &st) != 0) return 0;
return st.st_size;
}
/*
void domd5(char *path)
{
}
*/
void *dowork(void *arg)
{
threadarg *args = (threadarg *)arg;
int fd = args->fd,
copy = args->copy, rd;
long int start = args->start,
size = args->size;
char bufs[2048], *remains;
lseek(fd, start, SEEK_SET);
lseek(copy, start, SEEK_SET);
printf("%d thread with offset %ldKB, reached barrier\n", (int) pthread_self(), start);
barrier--;
while (barrier > 0);
long int count = 0, remainder = 0, i;
for (i = 0; i < size; i += 2048)
{
if (i + 2048 > size)
{
remainder = size - count;
remains = malloc(remainder * sizeof(char));
rd = read (fd, remains, sizeof(remains));
if (write(copy, remains, rd) != rd)
die("Error accessing files during copy");
count += remainder;
}
else
{
rd = read(fd, bufs, sizeof(bufs));
if (write(copy, bufs, rd) != rd)
die("Error accessing files during copy");
count += 2048;
}
}
pthread_exit(NULL);
}
/* Takes a single pointer, *argv, and passes it to isdir()
to check if the directory exists. If isdir returns a 1 a
1 is returned from this module. Otherwise, an error message
is printed and a 0 is returned.
Calls isdir().
Called by main().
*/
int chkdst(char **argv)
{
int isdir(char *path);
if (isdir(*argv)) return 1;
return 0;
}
/* Uses the Stat struct to construct a struct, sbuf,
and uses stat() to obtain information from the file and
write it to sbuf. Uses S_ISDIR() on sbuf.st_mode to see
the mode of the file. A 1 is returned if the file is a
directory otherwise a 0 is returned.
Called by isvalid().
*/
int isdir(char *path)
{
struct stat sbuf;
if (stat(path, &sbuf)) return 0;
return S_ISDIR(sbuf.st_mode);
}
/* Uses the Stat struct to construct a struct, sbuf,
and uses stat() to obtain information from the file and
write it to sbuf. Uses S_ISREG on sbuf.st_mode to see if
the file is regular. A 1 is returned if the S_ISREG is true
otherwise a 0 is returned.
Called by isvalid().
*/
int isregular(char *path)
{
struct stat sbuf;
if (stat(path, &sbuf)) return 0;
return S_ISREG(sbuf.st_mode);
}
/* Checks if the source path is a directory first, then if its
a regular file return 0 if it is dir and if it isn't a regular
file, then checks if the destionation path was created or if
the file exist at the destination if either return 0, if none
of these return 1.
Calls isdir() and isregular().
Called by copyfiles().
*/
int isvalid(char *path, char *dst)
{
if (isdir(path))
{
return 0;
}
else if (!isregular(path))
{
return 0;
}
else if (dst == NULL)
{
return 0;
}
else if (isregular(dst))
{
return 0;
}
return 1;
}
/* Builds destination-path using strrchr() function from library,
dstpath is null on error and defined otherwise. The src file has
its original destination removed and replaced with the new one if
it has a original destination on it otherwise it is just added to
the end of the existing name of the file.
Called by copyfiles().
*/
void buildpath(char *src, char *dst, char **dstpath)
{
char *ptr;
int n;
ptr = strrchr(src, '/');
if (ptr) n = strlen(dst) + strlen(ptr) + 2;
else n = strlen(dst) + strlen(src) + 2;
*dstpath = malloc(n);
if (!dstpath) return;
if (ptr)
{
strcpy(*dstpath, dst);
strcat(*dstpath, ptr);
}
else
{
strcpy(*dstpath, dst);
strcat(*dstpath, "/");
strcat(*dstpath, src);
}
}
So I want to make a file named genData.c that when executed for example: ./genData filename.txt will write 1 character to that file 1000 times.
In essence creating a 1kb file.
I would like to be able to modify the for loop, say 100000 times, to generate a 1MB file and so on.
Here is what I have tried and it compiles but when executed causes a segmentation fault.
Any suggestions? Sorry C is a language I've never dabbled in.
#include <stdio.h>
int main (int argc, char *argv) {
char ch = 'A';
FILE *fp;
fp = fopen(argv[1], "wb");
int i;
for (i = 0; i < 1000; i++) {
fwrite(&ch, sizeof(char), 1, fp);
}
fclose(fp);
return 0;
}
If you compile with warnings, you get a hint as to the exact problem:
test.c:3:5: warning: second argument of ‘main’ should be ‘char **’ [-Wmain]
int main (int argc, char *argv) {
^
All your troubles start downstream of this error. Fix this argument, and your code will work.
In the future, get into the habit of compiling with warnings turned on:
$ gcc -Wall foo.c
...
This will help catch typos and other oddities that will cause problems.
Since you tagged it Linux, this is how you can do it with the system-level functions (this should be a correct, most efficient way to do it):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <fcntl.h>
#include <string.h>
ssize_t /* Write "n" bytes to a descriptor */
writen(int fd, const void *ptr, size_t n);
int
main (int argc, char** argv) {
char buf[1000];
memset(buf, 'A', sizeof(buf));
int fd;
if((fd = open(argv[1], O_WRONLY|O_CREAT, 0666))<0){
perror(argv[1]);
exit(EX_NOPERM);
}
ssize_t left = writen(fd, buf, sizeof(buf));
if(left)
perror("write error\n");
return !!left;
}
ssize_t /* Write "n" bytes to a descriptor */
writen(int fd, const void *ptr, size_t n) {
size_t nleft;
ssize_t nwritten;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) < 0) {
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount written so far */
} else if (nwritten == 0) {
break;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n - nleft); /* return >= 0 */
}
#include <stdio.h>
#include <stdlib.h>
#define SIZE_OF_FILE 1024
int main(int argc, char *argv[])
{
FILE *fdest;
char ch = '\n';
if(argc != 2)
exit(EXIT_FAILURE);
fdest = fopen(argv[1], "wb");
if (fdest == NULL)
exit(EXIT_FAILURE);
fseek(fdest, SIZE_OF_FILE - 1, SEEK_CUR);
fwrite(&ch, sizeof(char), 1, fdest);
fclose(fdest);
return 0;
}
In essence creating a 1kb file
if the only purpose is creating a file with sizeof x, it is more simple i belive.
I am trying to read data from 2 named pipe and write it to another named pipe concatenating the content from 2 inputs. But why my output only shows the string from first input?
Here is my code:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#define MAX_REC_SIZE 1024
int open_fifo(char *name, int mode) {
mode = mode == O_RDONLY ? (O_RDONLY | O_NONBLOCK): mode;
int fd;
if (access(name, F_OK) == -1) {
if(mkfifo(name, 0777) != 0) {
fprintf(stderr, "Could not create fifo %s\n", name);
exit(EXIT_FAILURE);
}
}
fd = open(name, mode);;
return fd;
}
void read_fifo(int fd, char *out_r) {
memset (out_r, '\0', MAX_REC_SIZE);
do {
if(read(fd, out_r, MAX_REC_SIZE) > 0) {
out_r = strtok(out_r, "\n");
return;
}
} while (1);
}
void write_fifo(int fd, char *out_w) {
write(fd, out_w, sizeof(out_w));
}
int main()
{
int pipe_fd[3], i;
char *pipe_nm[] = {"./in_pipe_1", "./in_pipe_2", "./out_pipe_1"};
int read_mode = O_RDONLY;
int write_mode = O_WRONLY;
char out[MAX_REC_SIZE];
char out_store[MAX_REC_SIZE];
for(i=0; i<3; i++) {
pipe_fd[i] = open_fifo(pipe_nm[i], i == 2 ? write_mode : read_mode);
}
read_fifo(pipe_fd[0], out);
strcpy(out_store, out);
read_fifo(pipe_fd[1], out);
strcat(out_store, out);
strcat(out_store, "\n");
write_fifo(pipe_fd[2], out_store);
return 0;
}
A suspicious part of your code is:
write(fd, out_w, sizeof(out_w))
Here, out_w is not an array, and the sizeof operator would yield the size of a char * pointer, not the length of the block.
You should pass the length of out_store to your write_fifo function.
Also, I'm not really sure what your intent is when using the strtok function.
I have a problem at my C-lecture skill practice. My exercise is to read a text document (which is in the same directory like the program) char by char and write it reversed (so from the end to the beginning, char by char) at the Terminal (i have to work at Ubuntu).
Unfortunately it doesn't work - "read" only reads newline-chars (\n).
Can you find my mistake?
#include <sys/stat.h> //mode_t: accessing rights for the file
#include <fcntl.h> //for I/O
#include <unistd.h> //for file descriptors
#include <string.h> //for strlen
short const EXIT_FAILURE = 1;
short const EXIT_SUCCESS = 0;
char const* USAGE_CMD = "usage: write_file filename string_to_write\n";
char const* ERR_OPEN = "error in open\n";
char const* ERR_READ = "error in reading\n";
char const* ERR_CLOSE = "error in close\n";
char const* ERR_WRITE = "error in write\n";
int main(int argc, char** argv){
int fd = open(argv[1], O_RDONLY);
if(fd == -1){
write(STDERR_FILENO, ERR_OPEN, strlen(ERR_OPEN));
return EXIT_FAILURE;
}
int two_char_back = (-1)*sizeof(char); //shift-value for char
int one_back = -1; //shift-value for "no shift"
int length = lseek(fd, one_back, SEEK_END);//setting to one before oef
int i = 0; //for the loop
char buffer;
char* pbuffer = &buffer; //buffer for writing
while (i < length){
if (read(fd, pbuffer, sizeof(buffer)) == -1){ //READING
write(STDERR_FILENO, ERR_READ, strlen(ERR_READ));
return EXIT_FAILURE;
}
if(write(STDOUT_FILENO, pbuffer, sizeof(buffer)) == -1){ //WRITING
write(STDERR_FILENO, ERR_WRITE, strlen(ERR_WRITE));
return EXIT_FAILURE;
}
lseek(fd, two_char_back, SEEK_CUR); //STEPPING
i++;
}
if(close(fd) == -1){ //CLOSING
write(STDERR_FILENO, ERR_CLOSE, strlen(ERR_CLOSE));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
This is wrong:
int two_char_back = (-1)*sizeof(char);
sizeof(char) is 1, you need -2
Haven't tried running it, but looks like two_char_back should be -2. The read advances the cursor, so -1 keeps reading the same one.
Also, just an option, you could make it more efficient by reading the whole file in then reversing it, then writing.
You have a typo in following line:
int two_char_back = (-1)*sizeof(char);
It must be:
int two_char_back = (-2)*sizeof(char);
As read() increments a cursor, you are actually reading the same character all the time e.g:
example text
^
|
After reading:
example text
^
|
After seeking:
example text
^
|
Thanks for your advices a lot!
& Thanks to my colleagues!
Now it works but I created kind of a new version, here it is:
#include <sys/stat.h> //mode_t: accessing rights for the file
#include <fcntl.h> //for I/O
#include <unistd.h> //for file descriptors
#include <string.h> //for strlen
short const EXIT_FAILURE = 1;
short const EXIT_SUCCESS = 0;
char const* USAGE_CMD = "usage: write_file filename string_to_write\n";
char const* ERR_OPEN = "error in open\n";
char const* ERR_READ = "error in reading\n";
char const* ERR_CLOSE = "error in close\n";
char const* ERR_WRITE = "error in write\n";
int main(int argc, char** argv){
int fd = open(argv[1], O_RDONLY); //OPENING
if(fd == -1){
write(STDERR_FILENO, ERR_OPEN, strlen(ERR_OPEN));
return EXIT_FAILURE;
}
int file_size = lseek(fd, 0, SEEK_END); //setting to eof
int i = file_size-1; //for the loop, runs from the end to the start
char buffer;
//the files runs from the end to the back
do{
i--;
lseek(fd, i, SEEK_SET); //STEPPING from the start
if (read(fd, &buffer, sizeof(buffer)) != sizeof(buffer)){ //READING
write(STDERR_FILENO, ERR_READ, strlen(ERR_READ));
return EXIT_FAILURE;
}
if(write(STDOUT_FILENO, &buffer, sizeof(buffer)) != sizeof(buffer)){ //WRITING
write(STDERR_FILENO, ERR_WRITE, strlen(ERR_WRITE));
return EXIT_FAILURE;
}
}while (i != 0);
buffer = '\n';
write(STDOUT_FILENO, &buffer, sizeof(buffer));//no error-det. due to fixed value
if(close(fd) == -1){ //CLOSING
write(STDERR_FILENO, ERR_CLOSE, strlen(ERR_CLOSE));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
need some advice on this one as im struggling abit and cannot figure it out.
i have a file that gets updated on a PC to indicate a system ran and what time it ran. i am writing a very simple linux console app (will eventually be a nagios plugin). that reads this file and responds depending on what it found within the file.
i am a total newbie to programming on Linux and using C so please be patient and if you would explain any answers it would really be appreciated.
basically i want to convert a char array containing 5 characters into an integer, however the 5th char in the array is always a letter. so technically all i want to-do is convert the first 4 chars in the array to a integer... how?? ive tried multiple ways with no success, my problem is that presently i do not have a good grasp of the language so have no real ideas on what it can and cannot do.
here is the source to my program.
basically the buf array will be holding a string taken from the file that will look something like this
3455Y (the number will be random but always 4 chars long).
Sorry for the poor formatting of the code, but i cannot get this stupid window for love nor money to format it correctly....
include <fcntl.h>
include <unistd.h>
include <stdio.h>
include <stdlib.h>
include <time.h>
include <string.h>
define COPYMODE 0644
int main(int argc, char *argv[])
{
int i, nRead, fd;
int source;
int STATE_OK = 0;
int STATE_WARNING = 1;
int STATE_CRITICAL = 2;
int STATE_UNKNOWN = 3;
int system_paused = 0;
char buf[5];
int testnumber;
if((fd = open(argv[1], O_RDONLY)) == -1)
{
printf("failed open : %s", argv[1]);
return STATE_UNKNOWN;
}
else
{
nRead = read(fd, buf, 5);
}
close(source);
if (buf[4] == 'P')
{
printf("Software Paused");
return STATE_WARNING;
}
else
{
return STATE_OK;
}
time_t ltime; /* calendar time */
struct tm *Tm;
ltime=time(NULL); /* get current cal time */
Tm=localtime(<ime);
int test;
test = Tm->tm_hour + Tm->tm_min;
printf("%d", test);
printf("%d", strtoi(buf));
}
You can use sscanf to do the job:
int num = 0;
sscanf(buf, "%4d", &num);
Then num should hold the number from the line in the file.
You can use atoi
atoi requires one char * argument and returns an int.
If the string is empty, or first character isn't a number or a minus sign, then atoi returns 0.If atoi encounters a non-number character, it returns the number formed up until that point
int num = atoi(buf);
if you want to convert the first four characters of a string to an integer do this:
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
uint8_t convertFirstFourChars(char * str, uint32_t *value){
char tmp[5] = {0};
strncpy((char *) tmp, str, 4);
*value = strtoul(tmp);
return errno;
}
then call / test this function like this
#include <stdint.h>
#include <stdio.h>
int main(int argc, char **argv){
char test1[5] = "1234A";
char test2[5] = "ABCDE";
uint32_t val = 0;
if(convertFirstFourChars((char *) test1, &val) == 0){
printf("conversion of %s succeeded, value = %ld\n", test1, val);
}
else{
printf("conversion of %s failed!\n", test1);
}
if(convertFirstFourChars((char *) test2, &val) == 0){
printf("conversion succeeded of %s, value = %ld\n", test2, val);
}
else{
printf("conversion of %s failed!\n", test2);
}
return 0;
}
FWIW, don't use atoi(...) because it converts any string to an integer regardless of its validity as a number. atoi("foo") === 0.
this is as much of your code as I was able to recover from the formatting:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#define COPYMODE 0644
int main(int argc, char *argv[])
{
int i, nRead, fd;
int source;
int STATE_OK = 0;
int STATE_WARNING = 1;
int STATE_CRITICAL = 2;
int STATE_UNKNOWN = 3;
int system_paused = 0;
char buf[5];
int testnumber;
if((fd = open(argv[1], O_RDONLY)) == -1)
{
printf("failed open : %s", argv[1]);
return STATE_UNKNOWN;
}
else
{
nRead = read(fd, buf, 5);
}
close(source);
if (buf[4] == 'P')
{
printf("Software Paused");
return STATE_WARNING;
} else {
return STATE_OK;
}
time_t ltime; /* calendar time /
struct tm Tm;
ltime=time(NULL); / get current cal time */
Tm=localtime(<ime);
int test;
test = Tm->tm_hour + Tm->tm_min;
printf("%d", test);
printf("%d", strtoi(buf));
}
this is the version that does what you specified:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#define COPYMODE 0644
int main(int argc, char *argv[])
{
int i, nRead, fd;
int source;
int STATE_OK = 0;
int STATE_WARNING = 1;
int STATE_CRITICAL = 2;
int STATE_UNKNOWN = 3;
int system_paused = 0;
char buf[5];
int testnumber;
if((fd = open(argv[1], O_RDONLY)) == -1)
{
printf("failed open : %s", argv[1]);
return STATE_UNKNOWN;
}
else
{
nRead = read(fd, buf, 5);
}
close(source);
if (buf[4] == 'P')
{
printf("Software Paused");
return STATE_WARNING;
}/* else {
return STATE_OK;
buf[4] = 0;
} */
time_t ltime; /* calendar time */
struct tm *Tm;
ltime=time(NULL); /* get current cal time */
Tm=localtime(<ime);
int test;
test = Tm->tm_hour + Tm->tm_min;
printf("%d\n", test);
printf("%d\n", atoi(buf));
}
The biggest problem with your code was the if statement with the returns in each branch, insuring that nothing after the if statement was ever executed.