|
|
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <string.h>
- #include <signal.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <stdarg.h>
- #include <errno.h>
- #include <fcntl.h>
- /*我的QQ协议C实现*/
- #include "protocol.h"
- /* 你的QQ号码.*/
- static uint32_t id = 0;
- /* 你的QQ密码*/
- static char pass[36];
- /*在线状态.在protocol.h中定义*/
- static int online_status = QQ_ONLINE_NORMAL;
- /*QQ客户端实例*/
- static struct qq_client * qc = NULL;
- /*是否在后台运行*/
- static int is_daemon = 0;
- /*后台模式日志*/
- static int lfd = -1;
- /*QQ 服务器.*/
- const char *tencent_servers[] = {
- "219.133.40.173",
- "61.144.238.146",
- "61.144.238.145",
- "202.104.129.251",
- "202.104.129.254",
- "61.141.194.203",
- "61.141.194.203",
- "202.104.129.252",
- "202.104.129.253",
- "202.104.129.253",
- "202.96.170.64",
- "64.144.238.155",
- "202.104.129.254",
- "219.133.40.15",
- "218.17.209.23",
- "218.18.95.153",
- "202.104.129.251",
- "61.144.238.145",
- "202.104.129.253",
- "61.141.194.203",
- "202.104.129.254",
- "218.18.95.165",
- "61.144.238.146",
- "219.133.40.91",
- "211.248.99.252",
- "218.17.217.66",
- "61.144.238.156",
- "219.133.4.89",
- "219.133.40.115",
- "219.133.40.90",
- "219.133.40.113",
- "219.133.40.114",
- "210.22.12.126",
- "61.141.194.223",
- "61.172.249.135",
- "202.104.128.233",
- "202.96.170.164",
- "218.17.217.103",
- "218.66.59.233",
- "61.141.194.207",
- "202.96.170.163",
- "202.96.170.166",
- "202.96.140.18",
- "202.96.140.119",
- "202.96.140.8",
- "202.96.140.12"
- };
- /*帮助函数*/
- void usage(void);
- void usage(void)
- {
- fprintf(stderr,"\nqqalive usage:\n");
- fprintf(stderr,"qqalive -i <QQ> -p <Password> [-d] [-n|-o|-a|-h] \n");
- fprintf(stderr," -i your QQ number\n");
- fprintf(stderr," -p your QQ password\n");
- fprintf(stderr," -n login in normail mode\n");
- fprintf(stderr," -o login in offline mode\n");
- fprintf(stderr," -a login in away mode\n");
- fprintf(stderr," -h login in invisible mode\n");
- fprintf(stderr," -d daemon background mode\n");
- return;
- }
- /*推出hook*/
- void keepalive_exit(int signo);
- void keepalive_exit(int signo)
- {
- printf("signal %d recvied exiting ...\n",signo);
- /*登出QQ*/
- qq_logout(qc);
- /*释放资源*/
- qq_release_client(qc);
- qc = NULL;
- exit(0);
- }
- int main(int argc,char**argv)
- {
- char *ip = NULL;
- int n = 0;
- int e = 0;
- int i = 0;
- int fd = -1;
- char ch = 0;
- extern char* optarg;
- pid_t pid = 0;
- char tmp[512];
- int port = 6660;
- /*重新生成随机种子*/
- srand(time(0));
- bzero(pass,sizeof(pass));
- while( (ch=getopt(argc,argv,"i:p:dnoah")) != -1 ){
- switch(ch){
- case 'i':
- id = atol(optarg);
- break;
- case 'p':
- snprintf(pass,16,optarg);
- break;
- case 'd':
- is_daemon = 1;
- break;
- case 'n':
- online_status = QQ_ONLINE_NORMAL;
- break;
- case 'o':
- online_status = QQ_ONLINE_OFFLINE;
- case 'a':
- online_status = QQ_ONLINE_AWAY;
- case 'h':
- online_status = QQ_ONLINE_INVISIBLE;
- break;
- default:
- fprintf(stderr,"unrecognized option.\n");
- break;
- }
- }
- if(id==0||pass[0]==0){
- fprintf(stderr,"option -i and -p must be given.\n");
- usage();
- return -EFAULT;
- }
- signal(SIGINT,keepalive_exit);
- signal(SIGTERM,keepalive_exit);
- signal(SIGCHLD,SIG_IGN);
- bzero(tmp,sizeof(tmp));
- if(getenv ("HOME")){
- sprintf(tmp,"%s/oicq",getenv("HOME"));
- }
- else
- {
- sprintf(tmp,"oicq");
- }
- if(access(tmp,W_OK)){
- e = mkdir(tmp,0755);
- if(e){
- fprintf(stderr,"failed to create directory %s\n",tmp);
- return -EFAULT;
- }
- }
- printf("directory is "%s"\n",tmp);
- if(getenv("HOME")){
- sprintf(tmp,"%s/oicq/%d",getenv("HOME"),id);
- }
- else
- {
- sprintf(tmp,"oicq/%d",id);
- }
- if(is_daemon==1){
- pid = fork();
- if(pid<0){
- fprintf(stderr,"failed fork.\n");
- exit(-1);
- }
- if(pid>0){
- exit(0);
- }
- pid = fork();
- if(pid<0){
- fprintf(stderr,"failed fork.\n");
- exit(-1);
- }
- if(pid>0){
- exit(0);
- }
- lfd = open(tmp,O_RDONLY|O_WRONLY|O_CREAT,0666);
- if(lfd<0){
- fprintf(stderr,"failed to open file - "%s"\n",tmp);
- return -EFAULT;
- }
- printf("log file is - "%s"\n",tmp);
- close(0);
- close(1);
- close(2);
- dup(lfd);
- dup(lfd);
- dup(lfd);
- }
-
- //创建一个新的客户端实例
- qc = qq_create_client();
- if(qc==NULL){
- fprintf(stderr,"qq_create_client failed.\n");
- return -EFAULT;
- }
- /*开始挂机*/
- while(1){
- n = sizeof(tencent_servers)/sizeof(char*);
- /*随机选择一个服务器*/
- ip = tencent_servers[rand()%n];
- printf("select tencent server ip %s\n",ip);
- //字符形式的号码
- sprintf(tmp,"%d",id);
- /*随机选择一个本地UDP倾听端口*/
- port = 1234+rand()%(65535-1234);
- //
- // -EINVAL 密码错误
- // -EFAULT 其他错误
- // 0 成功
- e = qq_login( qc, /*qc*/
- tmp,pass,
- QQ_LOGIN_MODE_NORMAL,
- "0.0.0.0", /*本地地址..一般填0.0.0.0*/
- port, /*本地服务端口.*/
- ip,8000); /*服务器地址和端口*/
- if(e==0){
- //成功啦.
- while(1){
- int tcount = 0;
- int alive_error = 0;
- sleep(5);
- qc->online_status = online_status;
- qq_change_status(qc);
- sleep(5);
- e = qq_keep_alive(qc);
- if(e){
- alive_error++;
- }
- tcount++;
- if( alive_error>4 || tcount>100 ){
- qq_change_status(qc);
- tcount = 0;
- qq_logout(qc);
- break;
- }
- }
- }
- else
- {
- fprintf(stderr,"login failed . retry ...\n");
- sleep(1);
- }
- }
- return 0;
- }
复制代码 |
|