mirror of
https://github.com/GOSTSec/sgminer
synced 2025-09-01 00:31:51 +00:00
make all statline overflow safe
This commit is contained in:
parent
805672fb51
commit
385a70bea7
35
cgminer.c
35
cgminer.c
@ -1944,15 +1944,6 @@ static bool curses_active_locked(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void tailsprintf(char *f, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(f + strlen(f), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert a uint64_t value into a truncated string for displaying with its
|
/* Convert a uint64_t value into a truncated string for displaying with its
|
||||||
* associated suitable for Mega, Giga etc. Buf array needs to be long enough */
|
* associated suitable for Mega, Giga etc. Buf array needs to be long enough */
|
||||||
static void suffix_string(uint64_t val, char *buf, int sigdigits)
|
static void suffix_string(uint64_t val, char *buf, int sigdigits)
|
||||||
@ -2010,7 +2001,7 @@ static void suffix_string(uint64_t val, char *buf, int sigdigits)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_statline(char *buf, struct cgpu_info *cgpu)
|
static void get_statline(char *buf, size_t bufsiz, struct cgpu_info *cgpu)
|
||||||
{
|
{
|
||||||
char displayed_hashes[16], displayed_rolling[16];
|
char displayed_hashes[16], displayed_rolling[16];
|
||||||
uint64_t dh64, dr64;
|
uint64_t dh64, dr64;
|
||||||
@ -2035,8 +2026,8 @@ static void get_statline(char *buf, struct cgpu_info *cgpu)
|
|||||||
suffix_string(dr64, displayed_rolling, 4);
|
suffix_string(dr64, displayed_rolling, 4);
|
||||||
|
|
||||||
sprintf(buf, "%s%d ", cgpu->drv->name, cgpu->device_id);
|
sprintf(buf, "%s%d ", cgpu->drv->name, cgpu->device_id);
|
||||||
cgpu->drv->get_statline_before(buf, cgpu);
|
cgpu->drv->get_statline_before(buf, bufsiz, cgpu);
|
||||||
tailsprintf(buf, "(%ds):%s (avg):%sh/s | A:%.0f R:%.0f HW:%d WU:%.1f/m",
|
tailsprintf(buf, bufsiz, "(%ds):%s (avg):%sh/s | A:%.0f R:%.0f HW:%d WU:%.1f/m",
|
||||||
opt_log_interval,
|
opt_log_interval,
|
||||||
displayed_rolling,
|
displayed_rolling,
|
||||||
displayed_hashes,
|
displayed_hashes,
|
||||||
@ -2044,7 +2035,7 @@ static void get_statline(char *buf, struct cgpu_info *cgpu)
|
|||||||
cgpu->diff_rejected,
|
cgpu->diff_rejected,
|
||||||
cgpu->hw_errors,
|
cgpu->hw_errors,
|
||||||
wu);
|
wu);
|
||||||
cgpu->drv->get_statline(buf, cgpu);
|
cgpu->drv->get_statline(buf, bufsiz, cgpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_print_status(int thr_id)
|
static void text_print_status(int thr_id)
|
||||||
@ -2054,7 +2045,7 @@ static void text_print_status(int thr_id)
|
|||||||
|
|
||||||
cgpu = get_thr_cgpu(thr_id);
|
cgpu = get_thr_cgpu(thr_id);
|
||||||
if (cgpu) {
|
if (cgpu) {
|
||||||
get_statline(logline, cgpu);
|
get_statline(logline, sizeof(logline), cgpu);
|
||||||
printf("%s\n", logline);
|
printf("%s\n", logline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2143,7 +2134,7 @@ static void curses_print_devstatus(struct cgpu_info *cgpu, int count)
|
|||||||
wmove(statuswin,devcursor + count, 0);
|
wmove(statuswin,devcursor + count, 0);
|
||||||
wprintw(statuswin, " %s %*d: ", cgpu->drv->name, dev_width, cgpu->device_id);
|
wprintw(statuswin, " %s %*d: ", cgpu->drv->name, dev_width, cgpu->device_id);
|
||||||
logline[0] = '\0';
|
logline[0] = '\0';
|
||||||
cgpu->drv->get_statline_before(logline, cgpu);
|
cgpu->drv->get_statline_before(logline, sizeof(logline), cgpu);
|
||||||
wprintw(statuswin, "%s", logline);
|
wprintw(statuswin, "%s", logline);
|
||||||
|
|
||||||
dh64 = (double)cgpu->total_mhashes / dev_runtime * 1000000ull;
|
dh64 = (double)cgpu->total_mhashes / dev_runtime * 1000000ull;
|
||||||
@ -2179,7 +2170,7 @@ static void curses_print_devstatus(struct cgpu_info *cgpu, int count)
|
|||||||
wuwidth + 2, wu);
|
wuwidth + 2, wu);
|
||||||
|
|
||||||
logline[0] = '\0';
|
logline[0] = '\0';
|
||||||
cgpu->drv->get_statline(logline, cgpu);
|
cgpu->drv->get_statline(logline, sizeof(logline), cgpu);
|
||||||
wprintw(statuswin, "%s", logline);
|
wprintw(statuswin, "%s", logline);
|
||||||
|
|
||||||
wclrtoeol(statuswin);
|
wclrtoeol(statuswin);
|
||||||
@ -2642,7 +2633,7 @@ static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit)
|
|||||||
if (!want_per_device_stats) {
|
if (!want_per_device_stats) {
|
||||||
char logline[256];
|
char logline[256];
|
||||||
|
|
||||||
get_statline(logline, cgpu);
|
get_statline(logline, sizeof(logline), cgpu);
|
||||||
applog(LOG_INFO, "%s", logline);
|
applog(LOG_INFO, "%s", logline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4693,7 +4684,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|||||||
|
|
||||||
cgpu->last_message_tv = now;
|
cgpu->last_message_tv = now;
|
||||||
|
|
||||||
get_statline(logline, cgpu);
|
get_statline(logline, sizeof(logline), cgpu);
|
||||||
if (!curses_active) {
|
if (!curses_active) {
|
||||||
printf("%s \r", logline);
|
printf("%s \r", logline);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -6643,7 +6634,7 @@ static void log_print_status(struct cgpu_info *cgpu)
|
|||||||
{
|
{
|
||||||
char logline[255];
|
char logline[255];
|
||||||
|
|
||||||
get_statline(logline, cgpu);
|
get_statline(logline, sizeof(logline), cgpu);
|
||||||
applog(LOG_WARNING, "%s", logline);
|
applog(LOG_WARNING, "%s", logline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7023,12 +7014,12 @@ static void noop_reinit_device(struct cgpu_info __maybe_unused *cgpu)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void blank_get_statline_before(char *buf, struct cgpu_info __maybe_unused *cgpu)
|
void blank_get_statline_before(char *buf, size_t bufsiz, struct cgpu_info __maybe_unused *cgpu)
|
||||||
{
|
{
|
||||||
tailsprintf(buf, " | ");
|
tailsprintf(buf, bufsiz, " | ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void noop_get_statline(char __maybe_unused *buf, struct cgpu_info __maybe_unused *cgpu)
|
static void noop_get_statline(char __maybe_unused *buf, size_t __maybe_unused bufsiz, struct cgpu_info __maybe_unused *cgpu)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1146,7 @@ static void avalon_update_temps(struct cgpu_info *avalon, struct avalon_info *in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_avalon_statline_before(char *buf, struct cgpu_info *avalon)
|
static void get_avalon_statline_before(char *buf, size_t bufsiz, struct cgpu_info *avalon)
|
||||||
{
|
{
|
||||||
struct avalon_info *info = avalon->device_data;
|
struct avalon_info *info = avalon->device_data;
|
||||||
int lowfan = 10000;
|
int lowfan = 10000;
|
||||||
@ -1157,7 +1157,7 @@ static void get_avalon_statline_before(char *buf, struct cgpu_info *avalon)
|
|||||||
if (info->fan2 >= 0 && info->fan2 < lowfan)
|
if (info->fan2 >= 0 && info->fan2 < lowfan)
|
||||||
lowfan = info->fan2;
|
lowfan = info->fan2;
|
||||||
|
|
||||||
tailsprintf(buf, "%2d/%3dC %04dR | ", info->temp0, info->temp2, lowfan);
|
tailsprintf(buf, bufsiz, "%2d/%3dC %04dR | ", info->temp0, info->temp2, lowfan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We use a replacement algorithm to only remove references to work done from
|
/* We use a replacement algorithm to only remove references to work done from
|
||||||
|
@ -1235,7 +1235,7 @@ static void bflsc_detect(void)
|
|||||||
usb_detect(&bflsc_drv, bflsc_detect_one);
|
usb_detect(&bflsc_drv, bflsc_detect_one);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_bflsc_statline_before(char *buf, struct cgpu_info *bflsc)
|
static void get_bflsc_statline_before(char *buf, size_t bufsiz, struct cgpu_info *bflsc)
|
||||||
{
|
{
|
||||||
struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_data);
|
struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_data);
|
||||||
float temp = 0;
|
float temp = 0;
|
||||||
@ -1253,7 +1253,7 @@ static void get_bflsc_statline_before(char *buf, struct cgpu_info *bflsc)
|
|||||||
}
|
}
|
||||||
rd_unlock(&(sc_info->stat_lock));
|
rd_unlock(&(sc_info->stat_lock));
|
||||||
|
|
||||||
tailsprintf(buf, " max%3.0fC %4.2fV | ", temp, vcc1);
|
tailsprintf(buf, bufsiz, " max%3.0fC %4.2fV | ", temp, vcc1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_one_dev(struct cgpu_info *bflsc, int dev)
|
static void flush_one_dev(struct cgpu_info *bflsc, int dev)
|
||||||
|
@ -294,15 +294,16 @@ static void bitforce_detect(void)
|
|||||||
usb_detect(&bitforce_drv, bitforce_detect_one);
|
usb_detect(&bitforce_drv, bitforce_detect_one);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce)
|
static void get_bitforce_statline_before(char *buf, size_t bufsiz, struct cgpu_info *bitforce)
|
||||||
{
|
{
|
||||||
float gt = bitforce->temp;
|
float gt = bitforce->temp;
|
||||||
|
|
||||||
if (gt > 0)
|
if (gt > 0)
|
||||||
tailsprintf(buf, "%5.1fC ", gt);
|
tailsprintf(buf, bufsiz, "%5.1fC ", gt);
|
||||||
else
|
else
|
||||||
tailsprintf(buf, " ", gt);
|
tailsprintf(buf, bufsiz, " ");
|
||||||
tailsprintf(buf, " | ");
|
|
||||||
|
tailsprintf(buf, bufsiz, " | ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bitforce_thread_prepare(struct thr_info *thr)
|
static bool bitforce_thread_prepare(struct thr_info *thr)
|
||||||
|
@ -741,16 +741,12 @@ static bool modminer_fpga_init(struct thr_info *thr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_modminer_statline_before(char *buf, struct cgpu_info *modminer)
|
static void get_modminer_statline_before(char *buf, size_t bufsiz, struct cgpu_info *modminer)
|
||||||
{
|
{
|
||||||
char info[64];
|
tailsprintf(buf, bufsiz, " %s%.1fC %3uMHz | ",
|
||||||
|
|
||||||
sprintf(info, " %s%.1fC %3uMHz | ",
|
|
||||||
(modminer->temp < 10) ? " " : "",
|
(modminer->temp < 10) ? " " : "",
|
||||||
modminer->temp,
|
modminer->temp,
|
||||||
(unsigned int)(modminer->clock));
|
(unsigned int)(modminer->clock));
|
||||||
|
|
||||||
strcat(buf, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modminer_start_work(struct thr_info *thr, struct work *work)
|
static bool modminer_start_work(struct thr_info *thr, struct work *work)
|
||||||
|
@ -52,7 +52,6 @@ extern bool have_opencl;
|
|||||||
|
|
||||||
extern void *miner_thread(void *userdata);
|
extern void *miner_thread(void *userdata);
|
||||||
extern int dev_from_id(int thr_id);
|
extern int dev_from_id(int thr_id);
|
||||||
extern void tailsprintf(char *f, const char *fmt, ...);
|
|
||||||
extern void decay_time(double *f, double fadd);
|
extern void decay_time(double *f, double fadd);
|
||||||
|
|
||||||
/**********************************************/
|
/**********************************************/
|
||||||
@ -667,24 +666,24 @@ retry:
|
|||||||
if (temp != -1)
|
if (temp != -1)
|
||||||
sprintf(logline, "%.1f C ", temp);
|
sprintf(logline, "%.1f C ", temp);
|
||||||
if (fanspeed != -1 || fanpercent != -1) {
|
if (fanspeed != -1 || fanpercent != -1) {
|
||||||
tailsprintf(logline, "F: ");
|
tailsprintf(logline, sizeof(logline), "F: ");
|
||||||
if (fanpercent != -1)
|
if (fanpercent != -1)
|
||||||
tailsprintf(logline, "%d%% ", fanpercent);
|
tailsprintf(logline, sizeof(logline), "%d%% ", fanpercent);
|
||||||
if (fanspeed != -1)
|
if (fanspeed != -1)
|
||||||
tailsprintf(logline, "(%d RPM) ", fanspeed);
|
tailsprintf(logline, sizeof(logline), "(%d RPM) ", fanspeed);
|
||||||
tailsprintf(logline, " ");
|
tailsprintf(logline, sizeof(logline), " ");
|
||||||
}
|
}
|
||||||
if (engineclock != -1)
|
if (engineclock != -1)
|
||||||
tailsprintf(logline, "E: %d MHz ", engineclock);
|
tailsprintf(logline, sizeof(logline), "E: %d MHz ", engineclock);
|
||||||
if (memclock != -1)
|
if (memclock != -1)
|
||||||
tailsprintf(logline, "M: %d Mhz ", memclock);
|
tailsprintf(logline, sizeof(logline), "M: %d Mhz ", memclock);
|
||||||
if (vddc != -1)
|
if (vddc != -1)
|
||||||
tailsprintf(logline, "V: %.3fV ", vddc);
|
tailsprintf(logline, sizeof(logline), "V: %.3fV ", vddc);
|
||||||
if (activity != -1)
|
if (activity != -1)
|
||||||
tailsprintf(logline, "A: %d%% ", activity);
|
tailsprintf(logline, sizeof(logline), "A: %d%% ", activity);
|
||||||
if (powertune != -1)
|
if (powertune != -1)
|
||||||
tailsprintf(logline, "P: %d%%", powertune);
|
tailsprintf(logline, sizeof(logline), "P: %d%%", powertune);
|
||||||
tailsprintf(logline, "\n");
|
tailsprintf(logline, sizeof(logline), "\n");
|
||||||
_wlog(logline);
|
_wlog(logline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1271,7 +1270,7 @@ static void reinit_opencl_device(struct cgpu_info *gpu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
static void get_opencl_statline_before(char *buf, struct cgpu_info *gpu)
|
static void get_opencl_statline_before(char *buf, size_t bufsiz, struct cgpu_info *gpu)
|
||||||
{
|
{
|
||||||
if (gpu->has_adl) {
|
if (gpu->has_adl) {
|
||||||
int gpuid = gpu->device_id;
|
int gpuid = gpu->device_id;
|
||||||
@ -1280,25 +1279,25 @@ static void get_opencl_statline_before(char *buf, struct cgpu_info *gpu)
|
|||||||
int gp;
|
int gp;
|
||||||
|
|
||||||
if (gt != -1)
|
if (gt != -1)
|
||||||
tailsprintf(buf, "%5.1fC ", gt);
|
tailsprintf(buf, bufsiz, "%5.1fC ", gt);
|
||||||
else
|
else
|
||||||
tailsprintf(buf, " ", gt);
|
tailsprintf(buf, bufsiz, " ", gt);
|
||||||
if (gf != -1)
|
if (gf != -1)
|
||||||
// show invalid as 9999
|
// show invalid as 9999
|
||||||
tailsprintf(buf, "%4dRPM ", gf > 9999 ? 9999 : gf);
|
tailsprintf(buf, bufsiz, "%4dRPM ", gf > 9999 ? 9999 : gf);
|
||||||
else if ((gp = gpu_fanpercent(gpuid)) != -1)
|
else if ((gp = gpu_fanpercent(gpuid)) != -1)
|
||||||
tailsprintf(buf, "%3d%% ", gp);
|
tailsprintf(buf, bufsiz, "%3d%% ", gp);
|
||||||
else
|
else
|
||||||
tailsprintf(buf, " ");
|
tailsprintf(buf, bufsiz, " ");
|
||||||
tailsprintf(buf, "| ");
|
tailsprintf(buf, bufsiz, "| ");
|
||||||
} else
|
} else
|
||||||
gpu->drv->get_statline_before = &blank_get_statline_before;
|
gpu->drv->get_statline_before = &blank_get_statline_before;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void get_opencl_statline(char *buf, struct cgpu_info *gpu)
|
static void get_opencl_statline(char *buf, size_t bufsiz, struct cgpu_info *gpu)
|
||||||
{
|
{
|
||||||
tailsprintf(buf, " I:%2d", gpu->intensity);
|
tailsprintf(buf, bufsiz, " I:%2d", gpu->intensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct opencl_thread_data {
|
struct opencl_thread_data {
|
||||||
|
@ -362,11 +362,11 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
|
|||||||
return noncecnt;
|
return noncecnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ztex_statline_before(char *buf, struct cgpu_info *cgpu)
|
static void ztex_statline_before(char *buf, size_t bufsiz, struct cgpu_info *cgpu)
|
||||||
{
|
{
|
||||||
if (cgpu->deven == DEV_ENABLED) {
|
if (cgpu->deven == DEV_ENABLED) {
|
||||||
tailsprintf(buf, "%s-%d | ", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1);
|
tailsprintf(buf, bufsiz, "%s-%d | ", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1);
|
||||||
tailsprintf(buf, "%0.1fMHz | ", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1));
|
tailsprintf(buf, bufsiz, "%0.1fMHz | ", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
miner.h
19
miner.h
@ -294,7 +294,7 @@ struct gpu_adl {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void blank_get_statline_before(char *buf, struct cgpu_info __maybe_unused *cgpu);
|
extern void blank_get_statline_before(char *buf, size_t bufsiz, struct cgpu_info __maybe_unused *cgpu);
|
||||||
|
|
||||||
struct api_data;
|
struct api_data;
|
||||||
struct thr_info;
|
struct thr_info;
|
||||||
@ -311,8 +311,8 @@ struct device_drv {
|
|||||||
|
|
||||||
// Device-specific functions
|
// Device-specific functions
|
||||||
void (*reinit_device)(struct cgpu_info *);
|
void (*reinit_device)(struct cgpu_info *);
|
||||||
void (*get_statline_before)(char *, struct cgpu_info *);
|
void (*get_statline_before)(char *, size_t, struct cgpu_info *);
|
||||||
void (*get_statline)(char *, struct cgpu_info *);
|
void (*get_statline)(char *, size_t, struct cgpu_info *);
|
||||||
struct api_data *(*get_api_stats)(struct cgpu_info *);
|
struct api_data *(*get_api_stats)(struct cgpu_info *);
|
||||||
bool (*get_stats)(struct cgpu_info *);
|
bool (*get_stats)(struct cgpu_info *);
|
||||||
void (*identify_device)(struct cgpu_info *); // e.g. to flash a led
|
void (*identify_device)(struct cgpu_info *); // e.g. to flash a led
|
||||||
@ -1272,6 +1272,18 @@ struct modminer_fpga_state {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TAILBUFSIZ 64
|
||||||
|
|
||||||
|
#define tailsprintf(buf, bufsiz, fmt, ...) do { \
|
||||||
|
char tmp13[TAILBUFSIZ]; \
|
||||||
|
size_t len13, buflen = strlen(buf); \
|
||||||
|
snprintf(tmp13, sizeof(tmp13), fmt, ##__VA_ARGS__); \
|
||||||
|
len13 = strlen(tmp13); \
|
||||||
|
if ((buflen + len13) >= bufsiz) \
|
||||||
|
quit(1, "tailsprintf buffer overflow in %s %s line %d", __FILE__, __func__, __LINE__); \
|
||||||
|
strcat(buf, tmp13); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
extern void get_datestamp(char *, struct timeval *);
|
extern void get_datestamp(char *, struct timeval *);
|
||||||
extern void inc_hw_errors(struct thr_info *thr);
|
extern void inc_hw_errors(struct thr_info *thr);
|
||||||
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
||||||
@ -1280,7 +1292,6 @@ extern struct work *__find_work_bymidstate(struct work *que, char *midstate, siz
|
|||||||
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
||||||
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
|
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
|
||||||
extern void hash_queued_work(struct thr_info *mythr);
|
extern void hash_queued_work(struct thr_info *mythr);
|
||||||
extern void tailsprintf(char *f, const char *fmt, ...);
|
|
||||||
extern void _wlog(const char *str);
|
extern void _wlog(const char *str);
|
||||||
extern void _wlogprint(const char *str);
|
extern void _wlogprint(const char *str);
|
||||||
extern int curses_int(const char *query);
|
extern int curses_int(const char *query);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user