250 lines
8.5 KiB
C
250 lines
8.5 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/types.h>
|
|
#include <pty.h>
|
|
#include <fcntl.h>
|
|
#include <sysexits.h>
|
|
|
|
#define BUFCHUNKSIZE 4096
|
|
#define BUFSAFEPAD 8
|
|
#define KNRM "\x1B[0m"
|
|
#define KRED "\x1B[31m"
|
|
#define KGRN "\x1B[32m"
|
|
#define KYEL "\x1B[33m"
|
|
#define KBLU "\x1B[34m"
|
|
#define KMAG "\x1B[35m"
|
|
#define KCYN "\x1B[36m"
|
|
#define KWHT "\x1B[37m"
|
|
|
|
|
|
|
|
char* substr_add_color(const char *orig, const char *word_to_match, const char *color) {
|
|
//printf("INPUT::%s\n", orig);
|
|
char* output_string = malloc(BUFCHUNKSIZE+ 10); //malloc first so free in other code doesn't break
|
|
strncpy(output_string, orig, BUFCHUNKSIZE); //copy the orig into the buffer so if need return early, we can
|
|
//if (strlen(orig) > 16) memcpy(output_string + (strlen(orig)-15), "testing", 7);
|
|
//return output_string;
|
|
char* instances[BUFCHUNKSIZE] = {0};
|
|
char* pickup_point = (char *)orig; //pointer into orig where we need to start checking again; init to start of orig
|
|
|
|
int instance_count = 0;
|
|
while (1) {
|
|
char* nxt_found = strstr(pickup_point, word_to_match);
|
|
if (nxt_found == NULL) break;
|
|
pickup_point = nxt_found + strlen(word_to_match);
|
|
instances[instance_count] = nxt_found;
|
|
instance_count++;
|
|
}
|
|
if (instance_count == 0) return output_string; // <===
|
|
|
|
|
|
/*printf("FUNC: %d\n", instance_count);
|
|
for (int i =0; i<instance_count; i++){
|
|
printf("[*]DEBUG: %d: %p, %s\n", i, instances[i], instances[i]);
|
|
}*/
|
|
|
|
// we know we need to actually do shit now
|
|
int outbufsize = strlen(orig) + ( strlen(color) + strlen(KNRM) * instance_count); //Calculate length of buffer needed
|
|
output_string = realloc(output_string, outbufsize + BUFSAFEPAD); //this padding is not really needed
|
|
if (output_string == NULL) return (char *)orig;
|
|
memset(output_string, '\0', outbufsize+BUFSAFEPAD);
|
|
|
|
|
|
int orig_read_index, buf_write_index;
|
|
orig_read_index = buf_write_index = (instances[0] - orig); //these are for the loop, initalized to the part where we need to start writing
|
|
//-rw-r--r--. 1 user group 0 Sep 19 20:05
|
|
// write_index=^
|
|
strncpy(output_string, orig, orig_read_index);
|
|
|
|
//printf("count: %d, insize: %d, outbufsize: %d\n", instance_count, strlen(orig), outbufsize);
|
|
for (int i = 0; i<instance_count; i++){
|
|
int wlen = strlen(word_to_match);
|
|
int clen = strlen(color);
|
|
int rlen = strlen(KNRM);
|
|
//printf("wlen: %d, clen: %d, rlen: %d\n", wlen, clen, rlen);
|
|
strncpy(output_string + buf_write_index, (char *)color, clen);
|
|
buf_write_index = buf_write_index + clen;
|
|
strncpy(output_string + buf_write_index, (char *)word_to_match, wlen);
|
|
buf_write_index += wlen;
|
|
orig_read_index += wlen;
|
|
strncpy(output_string + buf_write_index, (char *)KNRM, rlen);
|
|
buf_write_index += rlen;
|
|
strncpy(output_string + buf_write_index, (char *)orig + orig_read_index, outbufsize-buf_write_index);
|
|
break;
|
|
if (i == instance_count - 1) break;
|
|
//strncpy(output_string + buf_write_index, orig + orig_read_index, (instances[i+1] - (instances[i]+ wlen)));
|
|
//buf_write_index += (instances[i+1] - instances[i] + wlen);
|
|
//orig_read_index += (instances[i+1] - instances[i] + wlen);
|
|
}
|
|
//printf("orig_read_index: %d, buf_write_index: %d\n", orig_read_index, buf_write_index);
|
|
//output_string[buf_write_index] = '\n';
|
|
//strncpy(output_string + buf_write_index, orig + orig_read_index, outbufsize - buf_write_index);
|
|
/*for (int i = 0; i<instance_count; i++){
|
|
//strncpy(output_string+ write_index, orig, read_index);
|
|
strncpy(write_point, (char*)color, strlen(color));
|
|
write_point += strlen(color);
|
|
strncpy(write_point, word_to_match, strlen(word_to_match));
|
|
write_point += strlen(word_to_match);
|
|
read_point += strlen(word_to_match);
|
|
strncpy(write_point, KNRM, strlen(KNRM));
|
|
write_point += strlen(KNRM);
|
|
if (i != instance_count - 1) break;
|
|
strncpy(output_string+(write_point - orig), read_point, (read_point - orig));
|
|
}*/
|
|
|
|
|
|
|
|
//char *nxt_found = strstr(orig, word);
|
|
//if (nxt_found == NULL) return output_string;
|
|
//int len2first = nxt_found - orig;
|
|
//printf("FUNC: %d, %c\n", len2first, output_string[len2first]);
|
|
//char first_part[len2first + 1];
|
|
//strncpy(first_part, orig, len2first);
|
|
//return first_part;
|
|
return output_string;
|
|
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
int master;
|
|
struct winsize win = {
|
|
.ws_col = 80, .ws_row = 24,
|
|
.ws_xpixel = 480, .ws_ypixel = 192,
|
|
};
|
|
pid_t child;
|
|
|
|
if (argc < 2) {
|
|
printf("Usage: %s cmd [args...]\n", argv[0]);
|
|
exit(EX_USAGE);
|
|
}
|
|
|
|
child = forkpty(&master, NULL, NULL, &win);
|
|
if (child == -1) {
|
|
perror("forkpty failed");
|
|
exit(EX_OSERR);
|
|
}
|
|
if (child == 0) {
|
|
execl(argv[1], argv[1], NULL);
|
|
perror("exec failed");
|
|
exit(EX_OSERR);
|
|
}
|
|
|
|
/* now the child is attached to a real pseudo-TTY instead of a pipe,
|
|
* while the parent can use "master" much like a normal pipe */
|
|
char childoutbuffer[BUFCHUNKSIZE] = {0};
|
|
//fcntl(master, F_SETFL, O_NONBLOCK);
|
|
FILE* thein = fdopen(master, "rw");
|
|
while(1){
|
|
//ssize_t count = read(catchout[0], childoutbuffer, BUFCHUNKSIZE);
|
|
//ssize_t count = read(catchout[0], childoutbuffer, sizeof(childoutbuffer));
|
|
// ideally I would want to read from the pipe and buffer the output, rewriting the line on change
|
|
// whenever it sees a newline, it should send it to the processor and print to stdout, with that newline
|
|
//
|
|
memset(childoutbuffer, 0, BUFCHUNKSIZE);
|
|
//ssize_t inc = read(master, childoutbuffer, BUFCHUNKSIZE);
|
|
//ssize_t theint = read(STDIN_FILENO, childoutbuffer, BUFCHUNKSIZE);
|
|
fgets(childoutbuffer, BUFCHUNKSIZE, stdin);
|
|
printf("%s\n", childoutbuffer);
|
|
write(master, childoutbuffer, strlen(childoutbuffer));
|
|
|
|
memset(childoutbuffer, 0, BUFCHUNKSIZE);
|
|
//ssize_t count = strlen(childoutbuffer);
|
|
ssize_t count = read(master, childoutbuffer, BUFCHUNKSIZE);
|
|
if (count == 0 ){
|
|
break;
|
|
} else if(count > 0){
|
|
//childoutbuffer[count] = '\0';
|
|
//char* added = substr_add_color(childoutbuffer, "alpine", KRED);
|
|
//memset(childoutbuffer, '\0', BUFCHUNKSIZE);
|
|
//strncpy(childoutbuffer, added, strlen(added));
|
|
|
|
write(STDOUT_FILENO, childoutbuffer, count);
|
|
//write(STDOUT_FILENO, childoutbuffer, strlen(added));
|
|
//free(added);
|
|
//printf("%s", childoutbuffer);
|
|
}
|
|
count = read(master, childoutbuffer, BUFCHUNKSIZE);
|
|
if (count == 0 ){
|
|
break;
|
|
} else if(count > 0){
|
|
//childoutbuffer[count] = '\0';
|
|
//char* added = substr_add_color(childoutbuffer, "alpine", KRED);
|
|
//memset(childoutbuffer, '\0', BUFCHUNKSIZE);
|
|
//strncpy(childoutbuffer, added, strlen(added));
|
|
|
|
write(STDOUT_FILENO, childoutbuffer, count);
|
|
//write(STDOUT_FILENO, childoutbuffer, strlen(added));
|
|
//free(added);
|
|
//printf("%s", childoutbuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/*int main ( int argc, char *argv[] ){
|
|
if (argc != 2) return 1;
|
|
//int catchin[2];
|
|
int catchout[2];
|
|
//if ( pipe(catchin) == -1 ) {
|
|
// perror("pipe");
|
|
// exit(1);
|
|
//}
|
|
if ( pipe(catchout) == -1 ) {
|
|
perror("pipe");
|
|
exit(1);
|
|
}
|
|
//setup new process
|
|
pid_t child_shell = fork();
|
|
if ( child_shell == 0 ){
|
|
//child
|
|
//dup2( catchin[0], STDIN_FILENO );
|
|
//close(catchin[0]);
|
|
//close(catchin[1]);
|
|
//close(catchout[1]);
|
|
dup2( catchout[1], STDOUT_FILENO );
|
|
//dup2( catchout[1], STDERR_FILENO );
|
|
close(catchout[0]);
|
|
execl(argv[1], argv[1], NULL);
|
|
} else if ( child_shell > 0 ){
|
|
//parent
|
|
//close(catchin[0]);
|
|
//FILE* pipeout = fdopen(catchin[1], "w");
|
|
//char childinbuffer[BUFCHUNKSIZE] = {0};
|
|
close(catchout[1]);
|
|
FILE* pipein = fdopen(catchout[0], "r");
|
|
char childoutbuffer[BUFCHUNKSIZE] = {0};
|
|
while(1){
|
|
//ssize_t count = read(catchout[0], childoutbuffer, BUFCHUNKSIZE);
|
|
//ssize_t count = read(catchout[0], childoutbuffer, sizeof(childoutbuffer));
|
|
// ideally I would want to read from the pipe and buffer the output, rewriting the line on change
|
|
// whenever it sees a newline, it should send it to the processor and print to stdout, with that newline
|
|
//
|
|
memset(childoutbuffer, 0, BUFCHUNKSIZE);
|
|
//fgets(childoutbuffer, BUFCHUNKSIZE, pipein);
|
|
//ssize_t count = strlen(childoutbuffer);
|
|
ssize_t count = read(catchout[0], childoutbuffer, BUFCHUNKSIZE);
|
|
if (count == 0 ){
|
|
break;
|
|
} else if(count > 0){
|
|
//childoutbuffer[count] = '\0';
|
|
//char* added = substr_add_color(childoutbuffer, "alpine", KRED);
|
|
//memset(childoutbuffer, '\0', BUFCHUNKSIZE);
|
|
//strncpy(childoutbuffer, added, strlen(added));
|
|
|
|
write(STDOUT_FILENO, childoutbuffer, count);
|
|
//write(STDOUT_FILENO, childoutbuffer, strlen(added));
|
|
//free(added);
|
|
//printf("%s", childoutbuffer);
|
|
}
|
|
}
|
|
close(catchout[0]);
|
|
}
|
|
return 0;
|
|
}*/
|