|
@@ -52,8 +52,43 @@ static void file_output_open(const char *const log_path)
|
|
zf_log_set_output_v(ZF_LOG_PUT_STD, 0, file_output_callback);
|
|
zf_log_set_output_v(ZF_LOG_PUT_STD, 0, file_output_callback);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+// END LOGGING
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+What is the name of the actual, real Mystic executable
|
|
|
|
+that we'll be executing and mangling?
|
|
|
|
+*/
|
|
|
|
+
|
|
|
|
+#define TARGET "./mySTIC"
|
|
|
|
+// Size of our input and output buffers.
|
|
|
|
+#define BSIZE 128
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ // Don't need this, zf_log does date/time stamps on output.
|
|
|
|
+
|
|
|
|
+const char * it_is_now(void) {
|
|
|
|
+ static char buffer[100];
|
|
|
|
+ time_t timer;
|
|
|
|
+ struct tm* tm_info;
|
|
|
|
+
|
|
|
|
+ timer = time(NULL);
|
|
|
|
+ tm_info = localtime(&timer);
|
|
|
|
+ strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
|
|
|
|
+ return buffer;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void slow_write(int fd, int speed, char * buffer, int len) {
|
|
|
|
+ int x;
|
|
|
|
+ for( x = 0; x < len; x++) {
|
|
|
|
+ usleep(speed);
|
|
|
|
+ write( fd, &buffer[x], 1);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+*/
|
|
|
|
+
|
|
const char * repr( const char * data) {
|
|
const char * repr( const char * data) {
|
|
- static char buffer[1024];
|
|
|
|
|
|
+ static char buffer[4096];
|
|
char * cp;
|
|
char * cp;
|
|
|
|
|
|
strcpy( buffer, data );
|
|
strcpy( buffer, data );
|
|
@@ -109,41 +144,23 @@ const char * repr( const char * data) {
|
|
*cp = '\\'; cp++;
|
|
*cp = '\\'; cp++;
|
|
*cp = 'x'; cp++;
|
|
*cp = 'x'; cp++;
|
|
char buffer[3];
|
|
char buffer[3];
|
|
- sprintf(buffer, "%02x", (int)c);
|
|
|
|
|
|
+ sprintf(buffer, "%02x", (int)c & 0xff);
|
|
*cp = buffer[0]; cp++;
|
|
*cp = buffer[0]; cp++;
|
|
*cp = buffer[1]; cp++;
|
|
*cp = buffer[1]; cp++;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- return buffer;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// END LOGGING
|
|
|
|
-
|
|
|
|
-// What is the name of the actual, real Mystic that
|
|
|
|
-// we'll be executing and manglying?
|
|
|
|
-
|
|
|
|
-#define TARGET "./mySTIC"
|
|
|
|
-#define BSIZE 1024
|
|
|
|
-
|
|
|
|
-const char * it_is_now(void) {
|
|
|
|
- static char buffer[100];
|
|
|
|
- time_t timer;
|
|
|
|
- struct tm* tm_info;
|
|
|
|
|
|
+ /*
|
|
|
|
+ int len = strlen(buffer);
|
|
|
|
+ if (len > 100 ) {
|
|
|
|
+ ZF_LOGW("len is %d, resetting to 100.", len);
|
|
|
|
+ buffer[100] = 0;
|
|
|
|
+ };
|
|
|
|
+ */
|
|
|
|
|
|
- timer = time(NULL);
|
|
|
|
- tm_info = localtime(&timer);
|
|
|
|
- strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
|
|
|
|
return buffer;
|
|
return buffer;
|
|
}
|
|
}
|
|
|
|
|
|
-void slow_write(int fd, int speed, char * buffer, int len) {
|
|
|
|
- int x;
|
|
|
|
- for( x = 0; x < len; x++) {
|
|
|
|
- usleep(speed);
|
|
|
|
- write( fd, &buffer[x], 1);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
|
|
struct render {
|
|
struct render {
|
|
int speed;
|
|
int speed;
|
|
@@ -160,6 +177,7 @@ void reset_render(void) {
|
|
|
|
|
|
|
|
|
|
#define TRIGGER "^"
|
|
#define TRIGGER "^"
|
|
|
|
+// Max limit we'll sleep before ignoring effects/speed.
|
|
#define SLEEP_LIMIT 30
|
|
#define SLEEP_LIMIT 30
|
|
|
|
|
|
int ms_sleep(unsigned int ms) {
|
|
int ms_sleep(unsigned int ms) {
|
|
@@ -185,6 +203,7 @@ void render_sleep(void) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// This needs work.
|
|
void write_color(int fd, int color) {
|
|
void write_color(int fd, int color) {
|
|
char buffer[10];
|
|
char buffer[10];
|
|
sprintf(buffer, "\x1b[%dm", color);
|
|
sprintf(buffer, "\x1b[%dm", color);
|
|
@@ -312,7 +331,7 @@ void render_effect(int fd, char ch) {
|
|
// CHAR + SPC + BS
|
|
// CHAR + SPC + BS
|
|
render_sleep();
|
|
render_sleep();
|
|
write(fd, &ch, 1);
|
|
write(fd, &ch, 1);
|
|
- render_sleep(); // Maybe extra sleep here?
|
|
|
|
|
|
+ render_sleep(); // Maybe extra sleep here? This is hard to see.
|
|
write(fd, &space, 1);
|
|
write(fd, &space, 1);
|
|
render_sleep();
|
|
render_sleep();
|
|
write(fd, &bs, 1);
|
|
write(fd, &bs, 1);
|
|
@@ -368,7 +387,6 @@ void render( int fd, const char * string_out ) {
|
|
};
|
|
};
|
|
|
|
|
|
// ZF_LOGI( "at trigger: (%s)", cp);
|
|
// ZF_LOGI( "at trigger: (%s)", cp);
|
|
-
|
|
|
|
cp += strlen(TRIGGER);
|
|
cp += strlen(TRIGGER);
|
|
|
|
|
|
// Ok, we're pointing at the trigger -- do something.
|
|
// Ok, we're pointing at the trigger -- do something.
|
|
@@ -390,6 +408,12 @@ void render( int fd, const char * string_out ) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ These are harry "timeout" events.
|
|
|
|
+
|
|
|
|
+ These happen when we've been sitting around awhile.
|
|
|
|
+
|
|
|
|
+ */
|
|
void harry_event(int fd) {
|
|
void harry_event(int fd) {
|
|
// Make something happen
|
|
// Make something happen
|
|
char buffer[100];
|
|
char buffer[100];
|
|
@@ -425,6 +449,11 @@ It won't handle multiple writers.
|
|
char * username = NULL;
|
|
char * username = NULL;
|
|
char * fullname = NULL;
|
|
char * fullname = NULL;
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+Pascal String Copy. Copy from pascal string, to C String.
|
|
|
|
+
|
|
|
|
+First char is pascal string length. (Max 255).
|
|
|
|
+ */
|
|
void pcopy(char * pstring, char * str) {
|
|
void pcopy(char * pstring, char * str) {
|
|
int len = (int)*pstring;
|
|
int len = (int)*pstring;
|
|
strncpy( str, pstring+1, len );
|
|
strncpy( str, pstring+1, len );
|
|
@@ -432,8 +461,8 @@ void pcopy(char * pstring, char * str) {
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
-This only works for those few idiots that use SSH,
|
|
|
|
-the Mystic broken SSH!
|
|
|
|
|
|
+This only works for those few idiots that use the
|
|
|
|
+horribly broken SSH crap that Mystic uses.
|
|
*/
|
|
*/
|
|
int locate_user(const char *alias) {
|
|
int locate_user(const char *alias) {
|
|
FILE * user;
|
|
FILE * user;
|
|
@@ -464,11 +493,166 @@ int locate_user(const char *alias) {
|
|
|
|
|
|
// Buffers are BSIZE + 1, so a buffer that size can strcpy safely.
|
|
// Buffers are BSIZE + 1, so a buffer that size can strcpy safely.
|
|
|
|
|
|
-void mangle( char * buffer ) {
|
|
|
|
|
|
+
|
|
|
|
+regex_t ANSI;
|
|
|
|
+regex_t WORDS;
|
|
|
|
+regex_t WORD;
|
|
|
|
+
|
|
|
|
+int init_regex(void) {
|
|
|
|
+ int ret;
|
|
|
|
+ char ansi[] = "\x1b\[[0-9]+(;[0-9]+)*?[a-zA-Z]";
|
|
|
|
+ char words[] = "[a-zA-Z]+( [a-zA-Z]+)+";
|
|
|
|
+ char word[] = "[a-zA-Z]+";
|
|
|
|
+ char errorbuf[100];
|
|
|
|
+
|
|
|
|
+ if ( ret = regcomp( &ANSI, ansi, REG_EXTENDED|REG_NEWLINE ) ) {
|
|
|
|
+ regerror( ret, &ANSI, errorbuf, sizeof(errorbuf));
|
|
|
|
+ ZF_LOGW( "Regex %s failed to compile: %s", ansi, errorbuf);
|
|
|
|
+ return 0;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ if ( ret = regcomp( &WORDS, words, REG_EXTENDED|REG_NEWLINE ) ) {
|
|
|
|
+ regerror( ret, &WORDS, errorbuf, sizeof(errorbuf));
|
|
|
|
+ ZF_LOGW( "Regex %s failed to compile: %s", words, errorbuf);
|
|
|
|
+ return 0;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ if ( ret = regcomp( &WORD, word, REG_EXTENDED|REG_NEWLINE ) ) {
|
|
|
|
+ regerror( ret, &WORD, errorbuf, sizeof(errorbuf));
|
|
|
|
+ ZF_LOGW( "Regex %s failed to compile: %s", word, errorbuf);
|
|
|
|
+ return 0;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int regmatch( regex_t *preg, const char * string, size_t nmatch, regmatch_t pmatch[], int eflags) {
|
|
|
|
+ // returns number of matches found. (Max nmatch)
|
|
|
|
+ int matches = 0;
|
|
|
|
+ int offset = 0;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ while (matches < nmatch) {
|
|
|
|
+ ret = regexec( preg, string + offset, nmatch - matches, pmatch + matches, eflags);
|
|
|
|
+ if (!ret) {
|
|
|
|
+ int current = offset;
|
|
|
|
+ offset += pmatch[matches].rm_eo;
|
|
|
|
+ pmatch[matches].rm_so += current;
|
|
|
|
+ pmatch[matches].rm_eo += current;
|
|
|
|
+ matches++;
|
|
|
|
+ } else if (ret == REG_NOMATCH ) {
|
|
|
|
+ break;
|
|
|
|
+ } else {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return matches;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define MAX_MATCH 10
|
|
|
|
+regmatch_t rxmatch[ MAX_MATCH ];
|
|
|
|
+
|
|
|
|
+int rx_match(regex_t * regex, const char * buffer) {
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = regmatch(regex, buffer, MAX_MATCH, rxmatch, 0);
|
|
|
|
+ for( int i = 0; i < ret; i++ ) {
|
|
|
|
+ ZF_LOGI("%d : (%d-%d)", i, rxmatch[i].rm_so, rxmatch[i].rm_eo);
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mangle( int fd, char * buffer ) {
|
|
|
|
+ int x, i;
|
|
|
|
+ int m = 0;
|
|
|
|
+
|
|
// Ok, we want to look for words to:
|
|
// Ok, we want to look for words to:
|
|
// MaNGlE , or transpose (both?!)
|
|
// MaNGlE , or transpose (both?!)
|
|
// or possibly transpose words
|
|
// or possibly transpose words
|
|
|
|
+ char work[ BSIZE + 1];
|
|
|
|
+
|
|
|
|
+ ZF_LOGI("mangle: %s", repr(buffer));
|
|
|
|
+ strcpy( work, buffer );
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ NOTE: We copy the buffer, so we can clear out ANSI codes, etc.
|
|
|
|
+ Otherwise we might mess some ANSI up!
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ (random) Look for ANSI CLS and:
|
|
|
|
+
|
|
|
|
+ display random spooky texts around, with delays ... then CLS.
|
|
|
|
|
|
|
|
+ display ANSI graphic file, with delays ... then CLS
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ /* work -- clear out ANSI so we don't mangle ANSI codes. */
|
|
|
|
+ x = rx_match(&ANSI, work );
|
|
|
|
+ if ( x > 0) {
|
|
|
|
+ ZF_LOGD("found %d ANSI", x);
|
|
|
|
+ for( i = 0; i < x; i++ ) {
|
|
|
|
+ memset(work + rxmatch[i].rm_so, '-', rxmatch[i].rm_eo - rxmatch[i].rm_so);
|
|
|
|
+ ZF_LOGD( "Now %d : %s", i, repr(work));
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ZF_LOGI("mangle: %s", repr(work));
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ (random) Locate words (in work), and possibly flip them around.
|
|
|
|
+ Transpose words. Transpose case. Transpose letters.
|
|
|
|
+ */
|
|
|
|
+ x = rx_match(&WORDS, work );
|
|
|
|
+ ZF_LOGD("found %d WORDS", x );
|
|
|
|
+
|
|
|
|
+ if ( x > 0 ) {
|
|
|
|
+ for( i = 0; i < x; i++ ) {
|
|
|
|
+ // Do things here.
|
|
|
|
+ if ( i % 3 == 0 ) {
|
|
|
|
+ for( int p = rxmatch[i].rm_so; p < rxmatch[i].rm_eo; p++ ) {
|
|
|
|
+ buffer[p] = tolower(buffer[p]);
|
|
|
|
+ m++;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if ( i % 3 == 1 ) {
|
|
|
|
+ for( int p = rxmatch[i].rm_so; p < rxmatch[i].rm_eo; p++ ) {
|
|
|
|
+ buffer[p] = toupper(buffer[p]);
|
|
|
|
+ m++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ (random) Locate single words, and transpose them. Transpose case.
|
|
|
|
+ Transpose letters.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ (random) Display up to certain point. Delay.
|
|
|
|
+ Print some characters slowly. Delay.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ if (m) {
|
|
|
|
+ ZF_LOGD("HH %d : %s", m, repr(buffer));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ write(fd, buffer, strlen(buffer));
|
|
|
|
+ return m;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int harry_happens( time_t *last_event, int wakeup ) {
|
|
|
|
+ time_t now = time(NULL);
|
|
|
|
+ int elapsed = now - *last_event;
|
|
|
|
+
|
|
|
|
+ if ( elapsed > wakeup ) {
|
|
|
|
+ // Ok! It's been too long since we've done something.
|
|
|
|
+ *last_event = now;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char * argv[])
|
|
int main(int argc, char * argv[])
|
|
@@ -515,6 +699,9 @@ int main(int argc, char * argv[])
|
|
ZF_LOGD( "Username: [%s] A.K.A. [%s]", username, fullname);
|
|
ZF_LOGD( "Username: [%s] A.K.A. [%s]", username, fullname);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ( !init_regex() )
|
|
|
|
+ return 2;
|
|
|
|
+
|
|
// With IGNBRK I don't think I need this anymore. (Nope!)
|
|
// With IGNBRK I don't think I need this anymore. (Nope!)
|
|
// signal(SIGINT, SIG_IGN);
|
|
// signal(SIGINT, SIG_IGN);
|
|
|
|
|
|
@@ -545,7 +732,9 @@ int main(int argc, char * argv[])
|
|
// ICANON - raw mode. No more line buffering!
|
|
// ICANON - raw mode. No more line buffering!
|
|
struct termios tios, orig1;
|
|
struct termios tios, orig1;
|
|
struct timeval timeout;
|
|
struct timeval timeout;
|
|
- int last_event;
|
|
|
|
|
|
+ time_t last_event = 0; // time(NULL);
|
|
|
|
+
|
|
|
|
+ ZF_LOGD("starting");
|
|
|
|
|
|
tcgetattr(master, &tios);
|
|
tcgetattr(master, &tios);
|
|
tios.c_lflag &= ~(ECHO | ECHONL | ICANON );
|
|
tios.c_lflag &= ~(ECHO | ECHONL | ICANON );
|
|
@@ -583,6 +772,13 @@ int main(int argc, char * argv[])
|
|
// o descritor tem que ser unico para o programa, a documentacao
|
|
// o descritor tem que ser unico para o programa, a documentacao
|
|
// recomenda um calculo entre os descritores sendo usados + 1
|
|
// recomenda um calculo entre os descritores sendo usados + 1
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ TODO: Figure out how this would work.
|
|
|
|
+
|
|
|
|
+ I'm thinking something like timeouts 30-50 seconds?
|
|
|
|
+ And as we get closer, 15-25 seconds.
|
|
|
|
+ */
|
|
|
|
+
|
|
// we're in luck! The last parameter is time interval/timeout. :D
|
|
// we're in luck! The last parameter is time interval/timeout. :D
|
|
timeout.tv_sec = 10;
|
|
timeout.tv_sec = 10;
|
|
timeout.tv_usec = 0;
|
|
timeout.tv_usec = 0;
|
|
@@ -590,9 +786,8 @@ int main(int argc, char * argv[])
|
|
// select(master+1, &read_fd, &write_fd, &except_fd, NULL);
|
|
// select(master+1, &read_fd, &write_fd, &except_fd, NULL);
|
|
if ( select(master+1, &read_fd, &write_fd, &except_fd, &timeout) == 0 ) {
|
|
if ( select(master+1, &read_fd, &write_fd, &except_fd, &timeout) == 0 ) {
|
|
// This means timeout!
|
|
// This means timeout!
|
|
|
|
+ ZF_LOGI("TIMEOUT");
|
|
harry_event(STDOUT_FILENO);
|
|
harry_event(STDOUT_FILENO);
|
|
- ZF_LOGI( "%s : TICK", it_is_now());
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
char input[BSIZE + 1];
|
|
char input[BSIZE + 1];
|
|
@@ -607,16 +802,21 @@ int main(int argc, char * argv[])
|
|
// e escreva isso na saida padrao
|
|
// e escreva isso na saida padrao
|
|
output[total] = 0;
|
|
output[total] = 0;
|
|
|
|
|
|
- if (random() % 20 < 3) {
|
|
|
|
- mangle( output );
|
|
|
|
|
|
+ if (harry_happens( &last_event, 5)) {
|
|
|
|
+ ZF_LOGI( "harry_happens");
|
|
|
|
+ if ( mangle( STDOUT_FILENO, output ) == 0 ) {
|
|
|
|
+ // failed, so. Try again.
|
|
|
|
+ last_event = 0;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ write(STDOUT_FILENO, &output, total);
|
|
|
|
+ // This is OUTPUT from the BBS
|
|
|
|
+ // ZF_LOGI( ">> %s", repr(output));
|
|
|
|
+ ZF_LOGI( ">> %d chars", (int)strlen(output));
|
|
|
|
+ // I think repr is flipping out here. :(
|
|
|
|
+ // ZF_LOGI( ">> %d", (int)strlen(repr(output)));
|
|
}
|
|
}
|
|
|
|
|
|
- write(STDOUT_FILENO, &output, total);
|
|
|
|
-
|
|
|
|
- // This is OUTPUT from the BBS
|
|
|
|
- ZF_LOGI( ">> %s", repr(output));
|
|
|
|
- // ZF_LOGI_MEM( output, strlen(output), ">> ");
|
|
|
|
-
|
|
|
|
} else
|
|
} else
|
|
break;
|
|
break;
|
|
}
|
|
}
|