68 lines
1.4 KiB
C
68 lines
1.4 KiB
C
#include <zinnia/alloc.h>
|
|
#include <zinnia/panic.h>
|
|
#include <zinnia/print.h>
|
|
#include <zinnia/syscall.h>
|
|
#include <zinnia/usercopy.h>
|
|
#include <stdint.h>
|
|
|
|
enum syslog_kind : uintptr_t {
|
|
SYSLOG_EMERG = 0,
|
|
SYSLOG_ALERT = 1,
|
|
SYSLOG_CRIT = 2,
|
|
SYSLOG_ERR = 3,
|
|
SYSLOG_WARNING = 4,
|
|
SYSLOG_NOTICE = 5,
|
|
SYSLOG_INFO = 6,
|
|
SYSLOG_DEBUG = 7,
|
|
};
|
|
|
|
struct syscall_ret sys_syslog(enum syslog_kind kind, __user char* message, size_t len) {
|
|
struct syscall_ret ret = {};
|
|
|
|
const size_t buf_len = MIN(len + 1, 256);
|
|
char* buf = mem_alloc(buf_len, ALLOC_NOZERO);
|
|
if (!usercopy_read(buf, message, buf_len - 1)) {
|
|
mem_free(buf);
|
|
|
|
ret.error = EFAULT;
|
|
return ret;
|
|
}
|
|
buf[buf_len - 1] = 0;
|
|
|
|
const char* log_level;
|
|
switch (kind) {
|
|
case SYSLOG_EMERG:
|
|
log_level = "emerg";
|
|
break;
|
|
case SYSLOG_ALERT:
|
|
log_level = "alert";
|
|
break;
|
|
case SYSLOG_CRIT:
|
|
log_level = "crit";
|
|
break;
|
|
case SYSLOG_ERR:
|
|
log_level = "err";
|
|
break;
|
|
case SYSLOG_WARNING:
|
|
log_level = "warning";
|
|
break;
|
|
case SYSLOG_NOTICE:
|
|
log_level = "notice";
|
|
break;
|
|
case SYSLOG_INFO:
|
|
log_level = "info";
|
|
break;
|
|
case SYSLOG_DEBUG:
|
|
log_level = "debug";
|
|
break;
|
|
default:
|
|
log_level = "invalid";
|
|
}
|
|
|
|
log("syslog(%s): %s\n", log_level, buf);
|
|
|
|
mem_free(buf);
|
|
|
|
return ret;
|
|
}
|