mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-10-31 07:26:52 +01:00 
			
		
		
		
	Compare commits
	
		
			12 Commits
		
	
	
		
			new_versio
			...
			line_break
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 310cf464d0 | ||
|  | 0c11b3121a | ||
|  | 1bdf0041bc | ||
|  | 6a203fd7bf | ||
|  | 93b3bbd5f6 | ||
|  | e122c5dbca | ||
|  | f6f41a510b | ||
|  | 05dbc626e2 | ||
|  | ceb175e3f1 | ||
|  | 4bd1d9bfee | ||
|  | 55944aa5a9 | ||
|  | b71c6a3792 | 
| @@ -1,7 +1,7 @@ | ||||
| --- | ||||
| cirrus-ci_task: | ||||
| bazel-opt_task: | ||||
|   container: | ||||
|     image: toxchat/toktok-stack:0.0.31-third_party | ||||
|     image: toxchat/toktok-stack:latest-release | ||||
|     cpu: 2 | ||||
|     memory: 2G | ||||
|   configure_script: | ||||
| @@ -9,5 +9,4 @@ cirrus-ci_task: | ||||
|   test_all_script: | ||||
|     - cd /src/workspace && bazel test -k | ||||
|         --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST | ||||
|         --config=release | ||||
|         //toxic/... | ||||
|   | ||||
							
								
								
									
										3
									
								
								.github/settings.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/settings.yml
									
									
									
									
										vendored
									
									
								
							| @@ -12,7 +12,8 @@ branches: | ||||
|       required_status_checks: | ||||
|         contexts: | ||||
|           - build | ||||
|           - cirrus-ci | ||||
|           - build-static | ||||
|           - bazel-opt | ||||
|           - Codacy Static Code Analysis | ||||
|           - code-review/reviewable | ||||
|           - infer | ||||
|   | ||||
							
								
								
									
										19
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -18,6 +18,7 @@ jobs: | ||||
|             libalut-dev | ||||
|             libconfig-dev | ||||
|             libcurl4-gnutls-dev | ||||
|             libmsgpack-dev | ||||
|             libnotify-dev | ||||
|             libopenal-dev | ||||
|             libopus-dev | ||||
| @@ -37,6 +38,22 @@ jobs: | ||||
|       - name: Build toxic | ||||
|         run: make -j4 | ||||
|  | ||||
|   build-static: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|       - name: Build minimal static toxic binary | ||||
|         run: docker run --rm | ||||
|           -v /tmp/artifact:/artifact | ||||
|           -v $PWD:/toxic | ||||
|           amd64/alpine:latest | ||||
|           sh -c 'yes | /toxic/script/build-minimal-static-toxic.sh' | ||||
|       - name: Display binary checksum | ||||
|         run: | | ||||
|           tar Jxf /tmp/artifact/toxic-minimal-static-musl_linux_x86-64.tar.xz | ||||
|           sha256sum toxic-minimal-static-musl_linux_x86-64/toxic | ||||
|  | ||||
|   infer: | ||||
|     runs-on: ubuntu-latest | ||||
|     container: toxchat/infer | ||||
| @@ -56,6 +73,7 @@ jobs: | ||||
|             libalut-dev | ||||
|             libconfig-dev | ||||
|             libcurl4-gnutls-dev | ||||
|             libmsgpack-dev | ||||
|             libncurses-dev | ||||
|             libnotify-dev | ||||
|             libopenal-dev | ||||
| @@ -87,6 +105,7 @@ jobs: | ||||
|               libnotify | ||||
|               libpng | ||||
|               libqrencode | ||||
|               msgpack | ||||
|               ncurses | ||||
|               openal | ||||
|               python3 | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| load("@rules_cc//cc:defs.bzl", "cc_binary") | ||||
| load("//tools/project:build_defs.bzl", "project") | ||||
|  | ||||
| package(features = ["layering_check"]) | ||||
|  | ||||
| project() | ||||
|  | ||||
| cc_binary( | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| # MIT License | ||||
| # | ||||
| # Copyright (c) 2021 Maxim Biro <nurupo.contributions@gmail.com> | ||||
| # Copyright (c) 2021-2022 Maxim Biro <nurupo.contributions@gmail.com> | ||||
| # | ||||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| # of this software and associated documentation files (the "Software"), to deal | ||||
| @@ -36,8 +36,19 @@ | ||||
| # | ||||
| # that would use Toxic code from /home/jfreegman/git/toxic and place the build | ||||
| # artifact at /tmp/artifact. | ||||
| # You can change between amd64/alpine:latest and i386/alpine:latest, for 64-bit | ||||
| # and 32-bit builds. | ||||
| # | ||||
| # You can change between: | ||||
| #   amd64/alpine:latest, | ||||
| #   i386/alpine:latest, | ||||
| #   arm64v8/alpine:latest, | ||||
| #   arm32v7/alpine:latest, | ||||
| #   arm32v6/alpine:latest, | ||||
| #   ppc64le/alpine:latest, | ||||
| #   s390x/alpine:latest, | ||||
| #   etc. | ||||
| # as long as your system can run foreign architecture binaries, e.g. via qemu | ||||
| # static bins and binfmt (install qemu-user-static package on Debian/Ubuntu). | ||||
| # | ||||
| # | ||||
| # To debug, run: | ||||
| # | ||||
| @@ -53,13 +64,6 @@ set -eu | ||||
| ARTIFACT_DIR="/artifact" | ||||
| TOXIC_SRC_DIR="/toxic" | ||||
|  | ||||
| # Make sure we run in the expected environment | ||||
| if ! grep -q 'docker' /proc/1/cgroup | ||||
| then | ||||
|   echo "Error: This script should be run inside a disposable Docker container as it might modify system files in ways that would break a real system." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| if [ ! -f /etc/os-release ] || ! grep -qi 'Alpine Linux' /etc/os-release | ||||
| then | ||||
|   echo "Error: This script expects to be run on Alpine Linux." | ||||
| @@ -110,6 +114,7 @@ apk add \ | ||||
|     libsodium-dev \ | ||||
|     libsodium-static \ | ||||
|     linux-headers \ | ||||
|     msgpack-c-dev \ | ||||
|     ncurses-dev \ | ||||
|     ncurses-static \ | ||||
|     ncurses-terminfo \ | ||||
| @@ -132,10 +137,10 @@ mkdir -p "$BUILD_DIR" | ||||
| cd "$BUILD_DIR" | ||||
|  | ||||
| # The git hash of the c-toxcore version we're using | ||||
| TOXCORE_VERSION="v0.2.13" | ||||
| TOXCORE_VERSION="v0.2.16" | ||||
|  | ||||
| # The sha256sum of the c-toxcore tarball for TOXCORE_VERSION | ||||
| TOXCORE_HASH="67114fa57504c58b695f5dce8ef85124d555f2c3c353d0d2615e6d4845114ab8" | ||||
| TOXCORE_HASH="653aa42654b607f0940cecfac873e9ce55605119a90d1dc454d1090ff6ca29c0" | ||||
|  | ||||
| TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz" | ||||
|  | ||||
| @@ -164,8 +169,8 @@ cmake --build _build --target install | ||||
| # location with SSL_CERT_FILE env variable. | ||||
| cd "$BUILD_DIR" | ||||
|  | ||||
| CURL_VERSION="7.80.0" | ||||
| CURL_HASH="dab997c9b08cb4a636a03f2f7f985eaba33279c1c52692430018fae4a4878dc7" | ||||
| CURL_VERSION="7.81.0" | ||||
| CURL_HASH="ac8e1087711084548d788ef18b9b732c8de887457b81f616fc681d1044b32f98" | ||||
| CURL_FILENAME="curl-$CURL_VERSION.tar.gz" | ||||
|  | ||||
| wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME" | ||||
| @@ -186,7 +191,8 @@ cd curl* | ||||
|   --with-openssl | ||||
| make | ||||
| make install | ||||
| sed -i 's|-lbrotlidec |-lbrotlidec-static -lbrotlicommon-static |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc | ||||
| sed -i 's|-lbrotlidec |-lbrotlidec -lbrotlicommon |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc | ||||
|  | ||||
|  | ||||
| # Build Toxic | ||||
| cd "$BUILD_DIR" | ||||
| @@ -301,4 +307,3 @@ mv "$PREPARE_ARTIFACT_DIR" "$PREPARE_ARTIFACT_DIR/../$ARTIFACT_NAME" | ||||
| tar -cJf "$ARTIFACT_NAME.tar.xz" "$ARTIFACT_NAME" | ||||
| mv "$ARTIFACT_NAME.tar.xz" "$ARTIFACT_DIR" | ||||
| chmod 777 -R "$ARTIFACT_DIR" | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								src/chat.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/chat.c
									
									
									
									
									
								
							| @@ -676,8 +676,10 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ | ||||
|     FILE *filecheck = NULL; | ||||
|     int count = 1; | ||||
|  | ||||
|     while ((filecheck = fopen(file_path, "r"))) { | ||||
|     while ((filecheck = fopen(file_path, "r")) || file_transfer_recv_path_exists(file_path)) { | ||||
|         if (filecheck) { | ||||
|             fclose(filecheck); | ||||
|         } | ||||
|  | ||||
|         file_path[path_len] = '\0'; | ||||
|         char d[5]; | ||||
| @@ -1383,7 +1385,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | ||||
|     self->x = x2; | ||||
|  | ||||
|     /* Truncate note if it doesn't fit in statusbar */ | ||||
|     size_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6; | ||||
|     size_t maxlen = x2 - getcurx(statusbar->topline) - KEY_IDENT_BYTES - 6; | ||||
|  | ||||
|     pthread_mutex_lock(&Winthread.lock); | ||||
|     size_t statusmsg_len = statusbar->statusmsg_len; | ||||
| @@ -1414,10 +1416,10 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | ||||
|     int s_x; | ||||
|     getyx(statusbar->topline, s_y, s_x); | ||||
|  | ||||
|     mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - (KEY_IDENT_DIGITS * 2) - 3); | ||||
|     mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - KEY_IDENT_BYTES  - 3); | ||||
|     wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); | ||||
|  | ||||
|     wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3); | ||||
|     wmove(statusbar->topline, 0, x2 - KEY_IDENT_BYTES  - 3); | ||||
|  | ||||
|     wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); | ||||
|     wprintw(statusbar->topline, "{"); | ||||
| @@ -1425,7 +1427,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | ||||
|  | ||||
|     wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT)); | ||||
|  | ||||
|     for (size_t i = 0; i < KEY_IDENT_DIGITS; ++i) { | ||||
|     for (size_t i = 0; i < KEY_IDENT_BYTES / 2; ++i) { | ||||
|         wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -45,9 +45,8 @@ extern FriendsList Friends; | ||||
| void init_progress_bar(char *progline) | ||||
| { | ||||
|     strcpy(progline, "0% ["); | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0; i < NUM_PROG_MARKS; ++i) { | ||||
|     for (size_t i = 0; i < NUM_PROG_MARKS; ++i) { | ||||
|         strcat(progline, "-"); | ||||
|     } | ||||
|  | ||||
| @@ -397,3 +396,26 @@ void kill_all_file_transfers(Tox *m) | ||||
|         kill_all_file_transfers_friend(m, Friends.list[i].num); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool file_transfer_recv_path_exists(const char *path) | ||||
| { | ||||
|     for (size_t friendnumber = 0; friendnumber < Friends.max_idx; ++friendnumber) { | ||||
|         if (!Friends.list[friendnumber].active) { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         for (size_t i = 0; i < MAX_FILES; ++i) { | ||||
|             FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i]; | ||||
|  | ||||
|             if (ft->state == FILE_TRANSFER_INACTIVE) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (strcmp(path, ft->file_path) == 0) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|   | ||||
| @@ -145,4 +145,7 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber); | ||||
|  | ||||
| void kill_all_file_transfers(Tox *m); | ||||
|  | ||||
| /* Return true if any pending or active file receiver has the path `path`. */ | ||||
| bool file_transfer_recv_path_exists(const char *path); | ||||
|  | ||||
| #endif /* FILE_TRANSFERS_H */ | ||||
|   | ||||
							
								
								
									
										128
									
								
								src/line_info.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								src/line_info.c
									
									
									
									
									
								
							| @@ -20,6 +20,10 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _GNU_SOURCE | ||||
| #define _GNU_SOURCE    /* needed for wcswidth() */ | ||||
| #endif | ||||
|  | ||||
| #include <stdarg.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdlib.h> | ||||
| @@ -137,13 +141,13 @@ static struct line_info *line_info_ret_queue(struct history *hst) | ||||
|  * Return 0 if string does not contain a newline byte. | ||||
|  * Return -1 if printing was aborted. | ||||
|  */ | ||||
| static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y) | ||||
| static int print_n_chars(WINDOW *win, const wchar_t *s, size_t n, int max_y) | ||||
| { | ||||
|     bool newline = false; | ||||
|     char ch; | ||||
|     wchar_t ch; | ||||
|  | ||||
|     for (size_t i = 0; i < n && (ch = s[i]); ++i) { | ||||
|         if (ch == '\n') { | ||||
|         if (ch == L'\n') { | ||||
|             newline = true; | ||||
|  | ||||
|             int x; | ||||
| @@ -159,7 +163,17 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y) | ||||
|         } | ||||
|  | ||||
|         if (win) { | ||||
|             wprintw(win, "%c", ch); | ||||
| #ifdef HAVE_WIDECHAR | ||||
|             waddnwstr(win, &ch, 1); | ||||
| #else | ||||
|             char b; | ||||
|  | ||||
|             if (wcstombs(&b, &ch, sizeof(char)) != 1) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             wprintw(win, "%c", b); | ||||
| #endif  // HAVE_WIDECHAR | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -169,10 +183,10 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y) | ||||
| /* Returns the index of the last space character in `s` found before `limit`. | ||||
|  * Returns -1 if no space is found. | ||||
|  */ | ||||
| static int rspace_index(const char *s, int limit) | ||||
| static int rspace_index(const wchar_t *s, int limit) | ||||
| { | ||||
|     for (int i = limit; i >= 0; --i) { | ||||
|         if (s[i] == ' ') { | ||||
|         if (s[i] == L' ') { | ||||
|             return i; | ||||
|         } | ||||
|     } | ||||
| @@ -183,12 +197,12 @@ static int rspace_index(const char *s, int limit) | ||||
| /* Returns the first index in `s` containing a newline byte found before `limit`. | ||||
|  * Returns -1 if no newline  is found. | ||||
|  */ | ||||
| static int newline_index(const char *s, int limit) | ||||
| static int newline_index(const wchar_t *s, int limit) | ||||
| { | ||||
|     char ch; | ||||
|     wchar_t ch; | ||||
|  | ||||
|     for (int i = 0; i < limit && (ch = s[i]); ++i) { | ||||
|         if (ch == '\n') { | ||||
|         if (ch == L'\n') { | ||||
|             return i; | ||||
|         } | ||||
|     } | ||||
| @@ -197,13 +211,13 @@ static int newline_index(const char *s, int limit) | ||||
| } | ||||
|  | ||||
| /* Returns the number of newline bytes in `s` */ | ||||
| static unsigned int newline_count(const char *s) | ||||
| static unsigned int newline_count(const wchar_t *s) | ||||
| { | ||||
|     char ch; | ||||
|     wchar_t ch; | ||||
|     unsigned int count = 0; | ||||
|  | ||||
|     for (size_t i = 0; (ch = s[i]); ++i) { | ||||
|         if (ch == '\n') { | ||||
|         if (ch == L'\n') { | ||||
|             ++count; | ||||
|         } | ||||
|     } | ||||
| @@ -226,10 +240,10 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | ||||
|     int y; | ||||
|     UNUSED_VAR(y); | ||||
|  | ||||
|     const char *msg = line->msg; | ||||
|     uint16_t length = line->msg_len; | ||||
|     const wchar_t *msg = line->msg; | ||||
|     uint16_t length = line->msg_width; | ||||
|     uint16_t lines = 0; | ||||
|     const int x_start = line->len - line->msg_len - 1;  // manually keep track of x position because ncurses sucks | ||||
|     const int x_start = line->len - line->msg_width - 1;  // manually keep track of x position because ncurses sucks | ||||
|     int x_limit = max_x - x_start; | ||||
|  | ||||
|     if (x_limit <= 1) { | ||||
| @@ -246,7 +260,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | ||||
|         } | ||||
|  | ||||
|         if (length < x_limit) { | ||||
|             int p_ret = print_n_chars(win, msg, length, max_y); | ||||
|             const int p_ret = print_n_chars(win, msg, length, max_y); | ||||
|  | ||||
|             if (p_ret == 1) { | ||||
|                 lines += newline_count(msg); | ||||
| @@ -258,7 +272,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         int newline_idx = newline_index(msg, x_limit - 1); | ||||
|         const int newline_idx = newline_index(msg, x_limit - 1); | ||||
|  | ||||
|         if (newline_idx >= 0) { | ||||
|             if (print_n_chars(win, msg, newline_idx + 1, max_y) == -1) { | ||||
| @@ -272,7 +286,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         int space_idx = rspace_index(msg, x_limit - 1); | ||||
|         const int space_idx = rspace_index(msg, x_limit - 1); | ||||
|  | ||||
|         if (space_idx >= 1) { | ||||
|             if (print_n_chars(win, msg, space_idx, max_y) == -1) { | ||||
| @@ -321,6 +335,37 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Converts `msg` into a widechar string and puts the result in `buf`. | ||||
|  * | ||||
|  * Returns the widechar width of the string. | ||||
|  */ | ||||
| static uint16_t line_info_add_msg(wchar_t *buf, size_t buf_size, const char *msg) | ||||
| { | ||||
|     if (msg == NULL || msg[0] == '\0') { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     const wint_t wc_msg_len = mbs_to_wcs_buf(buf, msg, buf_size); | ||||
|  | ||||
|     if (wc_msg_len > 0 && wc_msg_len < buf_size) { | ||||
|         buf[wc_msg_len] = L'\0'; | ||||
|         int width = wcswidth(buf, wc_msg_len); | ||||
|  | ||||
|         if (width == -1) {  // the best we can do on failure is to fall back to strlen | ||||
|             width = strlen(msg); | ||||
|         } | ||||
|  | ||||
|         return (uint16_t)width; | ||||
|     } else { | ||||
|         fprintf(stderr, "Failed to convert string '%s' to widechar\n", msg); | ||||
|         const wchar_t *err = L"Failed to parse message"; | ||||
|         uint16_t width = (uint16_t)wcslen(err); | ||||
|         wmemcpy(buf, err, width); | ||||
|         buf[width] = L'\0'; | ||||
|         return width; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void line_info_init_line(ToxWindow *self, struct line_info *line) | ||||
| { | ||||
|     int y2; | ||||
| @@ -409,13 +454,8 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     uint16_t msg_len = 0; | ||||
|  | ||||
|     if (frmt_msg[0]) { | ||||
|         snprintf(new_line->msg, sizeof(new_line->msg), "%s", frmt_msg); | ||||
|         msg_len = strlen(new_line->msg); | ||||
|         len += msg_len; | ||||
|     } | ||||
|     const uint16_t msg_width = line_info_add_msg(new_line->msg, sizeof(new_line->msg), frmt_msg); | ||||
|     len += msg_width; | ||||
|  | ||||
|     if (show_timestamp) { | ||||
|         get_time_str(new_line->timestr, sizeof(new_line->timestr)); | ||||
| @@ -434,7 +474,7 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const | ||||
|  | ||||
|     new_line->id = (hst->line_end->id + 1 + hst->queue_size) % INT_MAX; | ||||
|     new_line->len = len; | ||||
|     new_line->msg_len = msg_len; | ||||
|     new_line->msg_width = msg_width; | ||||
|     new_line->type = type; | ||||
|     new_line->bold = bold; | ||||
|     new_line->colour = colour; | ||||
| @@ -518,9 +558,8 @@ void line_info_print(ToxWindow *self) | ||||
|     const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT; | ||||
|     const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2; | ||||
|     uint16_t numlines = line->format_lines; | ||||
|     int print_ret = 0; | ||||
|  | ||||
|     while (line && numlines++ <= max_y && print_ret == 0) { | ||||
|     while (line && numlines++ <= max_y) { | ||||
|         int y; | ||||
|         int x; | ||||
|         getyx(win, y, x); | ||||
| @@ -557,22 +596,22 @@ void line_info_print(ToxWindow *self) | ||||
|                 wprintw(win, "%s %s: ", user_settings->line_normal, line->name1); | ||||
|                 wattroff(win, COLOR_PAIR(nameclr)); | ||||
|  | ||||
|                 if (line->msg[0] == 0) { | ||||
|                 if (line->msg[0] == L'\0') { | ||||
|                     waddch(win, '\n'); | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 if (line->msg[0] == '>') { | ||||
|                 if (line->msg[0] == L'>') { | ||||
|                     wattron(win, COLOR_PAIR(GREEN)); | ||||
|                 } else if (line->msg[0] == '<') { | ||||
|                 } else if (line->msg[0] == L'<') { | ||||
|                     wattron(win, COLOR_PAIR(RED)); | ||||
|                 } | ||||
|  | ||||
|                 print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 print_wrap(win, line, max_x, max_y); | ||||
|  | ||||
|                 if (line->msg[0] == '>') { | ||||
|                 if (line->msg[0] == L'>') { | ||||
|                     wattroff(win, COLOR_PAIR(GREEN)); | ||||
|                 } else if (line->msg[0] == '<') { | ||||
|                 } else if (line->msg[0] == L'<') { | ||||
|                     wattroff(win, COLOR_PAIR(RED)); | ||||
|                 } | ||||
|  | ||||
| @@ -592,7 +631,7 @@ void line_info_print(ToxWindow *self) | ||||
|  | ||||
|                 wattron(win, COLOR_PAIR(YELLOW)); | ||||
|                 wprintw(win, "%s %s ", user_settings->line_normal, line->name1); | ||||
|                 print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 print_wrap(win, line, max_x, max_y); | ||||
|                 wattroff(win, COLOR_PAIR(YELLOW)); | ||||
|  | ||||
|                 waddch(win, '\n'); | ||||
| @@ -613,7 +652,7 @@ void line_info_print(ToxWindow *self) | ||||
|                     wattron(win, COLOR_PAIR(line->colour)); | ||||
|                 } | ||||
|  | ||||
|                 print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 print_wrap(win, line, max_x, max_y); | ||||
|                 waddch(win, '\n'); | ||||
|  | ||||
|                 if (line->bold) { | ||||
| @@ -631,8 +670,8 @@ void line_info_print(ToxWindow *self) | ||||
|                 wprintw(win, "$ "); | ||||
|                 wattroff(win, COLOR_PAIR(GREEN)); | ||||
|  | ||||
|                 if (line->msg[0]) { | ||||
|                     print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 if (line->msg[0] != L'\0') { | ||||
|                     print_wrap(win, line, max_x, max_y); | ||||
|                 } | ||||
|  | ||||
|                 waddch(win, '\n'); | ||||
| @@ -650,7 +689,7 @@ void line_info_print(ToxWindow *self) | ||||
|                 wprintw(win, "%s ", line->name1); | ||||
|                 wattroff(win, A_BOLD); | ||||
|  | ||||
|                 print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 print_wrap(win, line, max_x, max_y); | ||||
|                 waddch(win, '\n'); | ||||
|  | ||||
|                 wattroff(win, COLOR_PAIR(line->colour)); | ||||
| @@ -669,7 +708,7 @@ void line_info_print(ToxWindow *self) | ||||
|                 wprintw(win, "%s ", line->name1); | ||||
|                 wattroff(win, A_BOLD); | ||||
|  | ||||
|                 print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 print_wrap(win, line, max_x, max_y); | ||||
|                 waddch(win, '\n'); | ||||
|  | ||||
|                 wattroff(win, COLOR_PAIR(line->colour)); | ||||
| @@ -687,7 +726,7 @@ void line_info_print(ToxWindow *self) | ||||
|                 wprintw(win, "%s", line->name1); | ||||
|                 wattroff(win, A_BOLD); | ||||
|  | ||||
|                 print_ret = print_wrap(win, line, max_x, max_y); | ||||
|                 print_wrap(win, line, max_x, max_y); | ||||
|  | ||||
|                 wattron(win, A_BOLD); | ||||
|                 wprintw(win, "%s\n", line->name2); | ||||
| @@ -749,10 +788,9 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg) | ||||
|  | ||||
|     while (line) { | ||||
|         if (line->id == id) { | ||||
|             size_t new_len = strlen(msg); | ||||
|             line->len = line->len - line->msg_len + new_len; | ||||
|             line->msg_len = new_len; | ||||
|             snprintf(line->msg, sizeof(line->msg), "%s", msg); | ||||
|             const uint16_t new_width = line_info_add_msg(line->msg, sizeof(line->msg), msg); | ||||
|             line->len = line->len - line->msg_width + new_width; | ||||
|             line->msg_width = new_width; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ struct line_info { | ||||
|     char    timestr[TIME_STR_SIZE]; | ||||
|     char    name1[TOXIC_MAX_NAME_LENGTH + 1]; | ||||
|     char    name2[TOXIC_MAX_NAME_LENGTH + 1]; | ||||
|     char msg[MAX_LINE_INFO_MSG_SIZE]; | ||||
|     wchar_t msg[MAX_LINE_INFO_MSG_SIZE]; | ||||
|     time_t  timestamp; | ||||
|     uint8_t type; | ||||
|     uint8_t bold; | ||||
| @@ -58,7 +58,7 @@ struct line_info { | ||||
|     bool    read_flag;     /* true if a message has been flagged as read */ | ||||
|     uint32_t id; | ||||
|     uint16_t len;        /* combined length of entire line */ | ||||
|     uint16_t msg_len;    /* length of the message */ | ||||
|     uint16_t msg_width;    /* width of the message */ | ||||
|     uint16_t format_lines;  /* number of lines the combined string takes up (dynamically set) */ | ||||
|  | ||||
|     struct line_info *prev; | ||||
|   | ||||
| @@ -62,21 +62,21 @@ static int get_log_path(char *dest, int destsize, const char *name, const char * | ||||
|  | ||||
|     /* first 6 bytes of selfkey */ | ||||
|     char self_id[32] = {0}; | ||||
|     path_len += KEY_IDENT_DIGITS * 2; | ||||
|     path_len += KEY_IDENT_BYTES; | ||||
|     sprintf(&self_id[0], "%02X", selfkey[0] & 0xff); | ||||
|     sprintf(&self_id[2], "%02X", selfkey[1] & 0xff); | ||||
|     sprintf(&self_id[4], "%02X", selfkey[2] & 0xff); | ||||
|     self_id[KEY_IDENT_DIGITS * 2] = '\0'; | ||||
|     self_id[KEY_IDENT_BYTES] = '\0'; | ||||
|  | ||||
|     char other_id[32] = {0}; | ||||
|  | ||||
|     if (otherkey) { | ||||
|         /* first 6 bytes of otherkey */ | ||||
|         path_len += KEY_IDENT_DIGITS * 2; | ||||
|         path_len += KEY_IDENT_BYTES; | ||||
|         sprintf(&other_id[0], "%02X", otherkey[0] & 0xff); | ||||
|         sprintf(&other_id[2], "%02X", otherkey[1] & 0xff); | ||||
|         sprintf(&other_id[4], "%02X", otherkey[2] & 0xff); | ||||
|         other_id[KEY_IDENT_DIGITS * 2] = '\0'; | ||||
|         other_id[KEY_IDENT_BYTES] = '\0'; | ||||
|     } | ||||
|  | ||||
|     if (path_len >= destsize) { | ||||
|   | ||||
| @@ -477,10 +477,9 @@ on_error: | ||||
|    returns length of msg, which will be no larger than size-1 */ | ||||
| size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length) | ||||
| { | ||||
|     size_t i; | ||||
|     size_t j = 0; | ||||
|  | ||||
|     for (i = 0; (i < length) && (j < size - 1); ++i) { | ||||
|     for (size_t i = 0; (i < length) && (j < size - 1); ++i) { | ||||
|         if (data[i] != '\r') { | ||||
|             msg[j++] = data[i]; | ||||
|         } | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/prompt.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/prompt.c
									
									
									
									
									
								
							| @@ -175,9 +175,7 @@ static int add_friend_request(const char *public_key, const char *data) | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0; i <= FrndRequests.max_idx; ++i) { | ||||
|     for (int i = 0; i <= FrndRequests.max_idx; ++i) { | ||||
|         if (!FrndRequests.request[i].active) { | ||||
|             FrndRequests.request[i].active = true; | ||||
|             memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE); | ||||
| @@ -526,6 +524,26 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Return true is the first 3 bytes of `key` are identical to any other contact in the contact list. | ||||
|  */ | ||||
| static bool key_is_similar(const char *key) | ||||
| { | ||||
|     for (size_t i = 0; i < Friends.max_idx; ++i) { | ||||
|         const ToxicFriend *friend = &Friends.list[i]; | ||||
|  | ||||
|         if (!friend->active) { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         if (memcmp(friend->pub_key, key, KEY_IDENT_BYTES / 2) == 0) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length) | ||||
| { | ||||
|     UNUSED_VAR(m); | ||||
| @@ -536,6 +554,13 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con | ||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data); | ||||
|     write_to_log("Friend request with the message '%s'", "", ctx->log, true); | ||||
|  | ||||
|     if (key_is_similar(key)) { | ||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, | ||||
|                       "WARNING: This contact's public key is suspiciously similar to that of another contact "); | ||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, | ||||
|                       "in your list. This may be an impersonation attempt, or it may have occurred by chance."); | ||||
|     } | ||||
|  | ||||
|     int n = add_friend_request(key, data); | ||||
|  | ||||
|     if (n == -1) { | ||||
|   | ||||
| @@ -23,6 +23,10 @@ | ||||
| #ifndef TOXIC_H | ||||
| #define TOXIC_H | ||||
|  | ||||
| #ifndef NCURSES_WIDECHAR | ||||
| #define NCURSES_WIDECHAR 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef TOXICVER | ||||
| #define TOXICVER "NOVERS"    /* Use the -D flag to set this */ | ||||
| #endif | ||||
| @@ -46,7 +50,7 @@ | ||||
| #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH    /* must be >= TOX_MAX_MESSAGE_LENGTH */ | ||||
| #define MAX_CMDNAME_SIZE 64 | ||||
| #define TOXIC_MAX_NAME_LENGTH 32   /* Must be <= TOX_MAX_NAME_LENGTH */ | ||||
| #define KEY_IDENT_DIGITS 3    /* number of hex digits to display for the pub-key based identifier */ | ||||
| #define KEY_IDENT_BYTES 6    /* number of hex digits to display for the public key identifier */ | ||||
| #define TIME_STR_SIZE 32 | ||||
| #define COLOR_STR_SIZE 10 /* should fit every color option */ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user