1 Star 0 Fork 4

calvinlin/vcc

forked from rain/vcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.c 6.10 KB
一键复制 编辑 原始数据 按行查看 历史
calvin 提交于 2022-04-29 21:23 +08:00 . 增加了在makefile修改默认服务器的功能
/* vcc/main.c
*
* This file is part of vcc.
*
* vcc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* vcc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with vcc. If not, see <https://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <signal.h>
#include <klist.h>
#include <vcc/vcc.h>
#include <vcc/version.h>
#include <vcc/pretty.h>
#include <vcc/defserv.h>
/* we tried to use libreadline, but after using that, we feel strange
* because... because of what? i don't know. */
#define DEFAULT_RATE 1000
int send_msg(const char *msg, const char *usrname);
int read_msg(struct vcc_request *buf);
int get_msgs(void);
int vcc_login(char *, char *);
int is_user_banned(char *);
int show_algo_info(void);
int crypt_init(void *key, void *iv);
int encrypt(char *);
int decrypt(char *);
int do_cmd(char *s);
int do_bh(struct vcc_request *);
int do_cmd_lself(char *);
int init_socket(const char *server_addr, int server_port);
int fd;
int rate;
char usrname[USRNAME_SIZE];
struct klist_node banned_people = KLIST_NODE_INIT(&banned_people);
extern int crypt_disabled;
extern int current_sid;
static char const *help_msg = {
"Usage: vcc [-up] [server]\n"
"Options: \n"
" -u --user Set the username on the server. "
"If unspecified, you must input it interatively. \n"
" -p --port Specified the port on the server. "
"Default port is 46. You must keep this as same "
"as the port on the server. \n"
" [server] Address of the server. "
"As default, server is VCC_DEFSERV. "
};
static int usage(void) {
fputs(help_msg, stderr);
return 1;
}
static int login(int got_usrname) {
char *passwd;
if (!got_usrname) {
fprintf(stderr, "login as: ");
scanf("%s", usrname);
}
passwd = getpass("password: ");
vcc_login(usrname, passwd);
do_cmd_lself(NULL);
return 0;
}
/* vos, the vcc over ssh, allows user to use vcc without install it.
* you can use 'ssh [email protected]' and you will get login just like
* using ssh but you can use vcc over that.
* */
int vos_login(void) {
char *passwd, *key, *iv, *name;
if (!(name = getenv("VOS_USRNAME")))
return 0;
strcpy(usrname, name);
if (!(passwd = getenv("VOS_PASSWD"))) {
fprintf(stderr, "Password not specified. \n");
exit(EXIT_FAILURE);
}
vcc_login(usrname, passwd);
do_cmd_lself(NULL);
show_algo_info();
/* crypt_init will copy that into a heap buffer */
if (!(key = getenv("VOS_KEY")) || !(iv = getenv("VOS_IV"))) {
fprintf(stderr, "warning: crypting disabled. \n");
crypt_disabled = 1;
return 1;
}
crypt_init(key, iv);
return 1;
}
int parse_args(char **argv, int *port, char **ip) {
int i = 1;
/*
* unknown: 0
* usrname: 1
* port: 2
*/
int type = 0;
int got_usrname = 0;
char *arg;
while (argv[i]) {
arg = argv[i];
switch (type) {
case 0:
if (!strcmp(arg, "-u") || !strcmp(arg, "--user")) {
type = 1;
} else if (!strcmp(arg, "-p") || !strcmp(arg, "--port")) {
type = 2;
} else if (arg[0] != '-') {
*ip = arg;
} else {
exit(usage());
}
break;
case 1:
printf("%s %s\n", arg, usrname);
strcpy(usrname, arg);
got_usrname = 1;
type = 0;
break;
case 2:
*port = atoi(arg);
type = 0;
break;
default:
abort();
}
++i;
}
return got_usrname;
}
int do_handle_command(char *buf) {
if (*buf == '-')
do_cmd(buf);
else if (*buf != '\n') {
send_msg(buf, usrname);
pretty_new_msg(usrname, buf, current_sid);
}
pretty_prompt(usrname);
return 0;
}
int main(int argc, char **argv) {
struct pollfd fds[2];
struct vcc_request *req;
char *buf, *msg, *ip = VCC_DEFSERV;
char key[64], iv[64];
int n, size, port = VCC_PORT, got_usrname;
(void) argc;
#ifdef _WIN32
setlocale(LC_ALL, ".UTF-8");
#else
setlocale(LC_ALL, "C.UTF-8");
#endif
printf(VCC_VERSION "\n");
init_socket(ip, port);
printf("Connected to server. \n");
if (!vos_login()) {
/* normally startup */
got_usrname = parse_args(argv, &port, &ip);
login(got_usrname);
show_algo_info();
memset(key, 0, 64);
memset(iv, 0, 64);
fprintf(stderr, "Key: ");
read(0, key, 64);
fprintf(stderr, "IV: ");
read(0, iv, 64);
crypt_init(key, iv);
}
fds[0].fd = 0;
fds[0].events = POLLIN;
fds[0].revents = 0;
fds[1].fd = fd;
fds[1].events = POLLIN;
fds[1].revents = 0;
rate = DEFAULT_RATE;
if (unlikely(!(buf = malloc(MSG_SIZE)))) {
fprintf(stderr, "*** malloc() failed\n");
return 1;
}
if (unlikely(!(req = malloc(REQ_SIZE)))) {
fprintf(stderr, "*** malloc() failed\n");
return 1;
}
for (;;) {
memset(buf, 0, MSG_SIZE);
n = poll(fds, 2, rate);
if (n == -1) {
if (likely(errno == EINTR))
continue;
perror("poll()");
break;
}
if (!n) {
/* 1 sec timed out */
get_msgs();
continue;
}
if (fds[0].revents & POLLIN) {
if (read(0, buf, MSG_SIZE) == -1)
continue;
do_handle_command(buf);
}
if (fds[1].revents & POLLIN) {
size = read(fd, req, REQ_SIZE);
if (unlikely(!size)) {
fprintf(stderr, "Server closed. \n");
break;
}
if (ntohl(req->reqtype) != REQ_MSG_NEW) {
do_bh(req);
continue;
}
msg = req->msg;
if (!strcmp(msg, "CQD")) {
pretty_cqd(req->usrname);
pretty_prompt(usrname);
continue;
}
if (unlikely(is_user_banned(req->usrname)))
continue;
if (ntohl(req->flags) & FLAG_ENCRYPTED)
decrypt(msg);
pretty_new_msg(req->usrname, msg, ntohl(req->session));
pretty_prompt(usrname);
}
}
printf("bye. \n");
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/calvin-lin/vcc.git
[email protected]:calvin-lin/vcc.git
calvin-lin
vcc
vcc
master

搜索帮助