Guest User

Untitled

a guest
Feb 12th, 2019
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.28 KB | None | 0 0
  1. 【程序名】小涵QQ自动回复机器人 【编辑制作】涵仔 【QQ】747577328
  2. PS:怕有人盗用,我只段取了副程序的源码,如需要主程序的源码,请联系本人,售价10元,谢谢!本程序为出售程序,30元/1年,50元/2年,100元/5年,300元永久!
  3.  
  4. /*
  5. * buddy.c
  6. *
  7. * Buddy management
  8. *
  9. * Copyright (C) 2008 Huang Guan
  10. *
  11. * 2008-7-12 Created.
  12. *
  13. * Description: This file mainly includes the functions about
  14. *
  15. */
  16.  
  17. #include <time.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #ifdef __WIN32__
  21. #include <winsock.h>
  22. #include <wininet.h>
  23. #else
  24. #include <sys/socket.h>
  25. #include <arpa/inet.h>
  26. #endif
  27. #include "qqclient.h"
  28. #include "memory.h"
  29. #include "debug.h"
  30. #include "protocol.h"
  31. #include "list.h"
  32. #include "buddy.h"
  33. #include "packetmgr.h"
  34.  
  35.  
  36. //按qq号码进行升序排序
  37. static int buddy_comp(const void *p, const void *q)
  38. {
  39. return ( (*(qqbuddy **)p)->number - (*(qqbuddy **)q)->number );
  40. }
  41.  
  42. static int searcher( const void* p, const void* v )
  43. {
  44. return ( ((qqbuddy*)p)->number == (int)v );
  45. }
  46.  
  47. qqbuddy* buddy_get( qqclient* qq, uint number, int create )
  48. {
  49. if( !number )
  50. return NULL;
  51. // if( create && number != qq->number ) return NULL;
  52. qqbuddy* b;
  53. b = list_search( &qq->buddy_list, (void*)number, searcher );
  54. //if not found, b must be NULL
  55. if( b==NULL && create ){
  56. NEW( b, sizeof( qqbuddy ) );
  57. if( !b ) return b;
  58. b->number = number;
  59. sprintf( b->nickname, "%u", number );
  60. if( list_append( &qq->buddy_list, (void*)b )<0 ){
  61. DEL( b );
  62. }
  63. }
  64. return b;
  65. }
  66.  
  67. void buddy_remove( qqclient* qq, uint number )
  68. {
  69. qqbuddy* b;
  70. b = list_search( &qq->buddy_list, (void*)number, searcher );
  71. if( b ){
  72. list_remove( &qq->buddy_list, b );
  73. }
  74. }
  75.  
  76. void buddy_sort_list( qqclient* qq )
  77. {
  78. list_sort( &qq->buddy_list, buddy_comp );
  79. }
  80.  
  81. static int buddyoff_searcher( const void* p, const void* v )
  82. {
  83. ((qqbuddy*)p)->status = QQ_OFFLINE;
  84. return 0;
  85. }
  86. void buddy_set_all_off( struct qqclient* qq )
  87. {
  88. list_search( &qq->buddy_list, NULL, buddyoff_searcher );
  89. }
  90.  
  91. void buddy_update_list( qqclient* qq )
  92. {
  93. prot_buddy_update_list( qq, 0 );
  94. prot_buddy_update_online( qq, 0 );
  95. }
  96.  
  97. void buddy_update_info( qqclient* qq, qqbuddy* b )
  98. {
  99. prot_buddy_get_info( qq, b->number );
  100. }
  101.  
  102.  
  103. int buddy_send_message( qqclient* qq, uint number, char* msg )
  104. {
  105. prot_im_send_msg( qq, number, msg );
  106. return 0;
  107. }
  108.  
  109. char* buddy_status_string( int st )
  110. {
  111. switch( st ){
  112. case QQ_ONLINE:
  113. return "Online";
  114. case QQ_OFFLINE:
  115. return "Offline";
  116. case QQ_AWAY:
  117. return "Away";
  118. case QQ_HIDDEN:
  119. return "Hidden";
  120. case QQ_BUSY:
  121. return "Busy";
  122. case QQ_KILLME:
  123. return "KillMe";
  124. case QQ_QUIET:
  125. return "Quiet";
  126. default:
  127. return "Unknown";
  128. }
  129. }
  130.  
  131. //buddy_put_event的函数在登录之后调用比较频繁,
  132. //在获取好友列表,获取好友在线列表,获取好友签名,获取好友备注
  133. void buddy_put_event( qqclient* qq )
  134. {
  135. char *temp;
  136. int i;
  137. qqbuddy* b;
  138. NEW( temp, KB(128) );
  139. if( !temp ) return;
  140. strcpy( temp, "buddylist^$" );
  141. pthread_mutex_lock( &qq->buddy_list.mutex );
  142. struct in_addr addr;
  143. for( i=0; i<qq->buddy_list.count; i++ ){
  144. b = (qqbuddy*)qq->buddy_list.items[i];
  145. addr.s_addr = htonl( b->ip );
  146. sprintf( temp, "%s%u\t%s\t%s\t%s\t%d\t%s\t%s\t%d^@", temp, b->number, buddy_status_string(b->status), b->nickname,
  147. b->signature, b->sex, inet_ntoa( addr ), b->alias, b->gid );
  148. }
  149. pthread_mutex_unlock( &qq->buddy_list.mutex );
  150. qqclient_put_event( qq, temp );
  151. DEL( temp );
  152. }
  153. #ifndef _BUDDY_H
  154. #define _BUDDY_H
  155.  
  156. #include "qqdef.h"
  157.  
  158. typedef struct qqbuddy{
  159. uint number;
  160. char nickname[NICKNAME_LEN];
  161. uint ip;
  162. ushort port;
  163. ushort face;
  164. uchar age;
  165. uchar sex;
  166. uchar gid;
  167. uchar qqshow;
  168. uchar flag;
  169. uchar session_key[16];
  170. uchar status;
  171. ushort version;
  172. uchar verify_flag; //00 允许 01 验证 02 拒绝 03 问题
  173.  
  174. uint sign_time;
  175. uchar account_flag;
  176. #ifndef NO_BUDDY_DETAIL_INFO
  177. char signature[SIGNITURE_LEN];
  178. char account[ACCOUNT_LEN]; //email account
  179. char alias[ALIAS_LEN];
  180. char post_code[32];
  181. char address[64];
  182. char homephone[32];
  183. char mobilephone[32];
  184. char email[32];
  185. char occupation[32];
  186. char homepage[64];
  187. char brief[256];
  188. char school[32];
  189. char birth[16];
  190. char province[16];
  191. char city[16];
  192. char country[16];
  193. #else
  194. char signiture[1];
  195. char account[1];
  196. char alias[1];
  197. char post_code[1];
  198. char address[1];
  199. char homephone[1];
  200. char mobilephone[1];
  201. char email[1];
  202. char occupation[1];
  203. char homepage[1];
  204. char brief[1];
  205. char school[1];
  206. char birth[1];
  207. char province[1];
  208. char city[1];
  209. char country[1];
  210. #endif
  211.  
  212. }qqbuddy;
  213.  
  214. struct qqclient;
  215. qqbuddy* buddy_get( struct qqclient* qq, uint number, int create );
  216. void buddy_remove( struct qqclient* qq, uint number );
  217. void buddy_update_list( struct qqclient* qq );
  218. void buddy_update_info( struct qqclient* qq, qqbuddy* b );
  219. void buddy_sort_list( struct qqclient* qq );
  220. int buddy_send_message( struct qqclient* qq, uint number, char* msg );
  221. void buddy_set_all_off( struct qqclient* qq );
  222. void buddy_put_event( struct qqclient* qq );
  223. char* buddy_status_string( int st );
  224.  
  225. #endif
  226. /*
  227. * coinfig.c
  228. *
  229. * Configuration Procedures
  230. *
  231. * Copyright (C) 2008 Huang Guan
  232. *
  233. * 2008-7-9 15:40:05 Created.
  234. * 2009-7-5 23:32:00 Patched a chars memory bug in parse().
  235. *
  236. * Description: This file mainly includes the functions about
  237. * reading configuration file.
  238. *
  239. */
  240.  
  241. #include <stdio.h>
  242. #include <string.h>
  243. #include <stdlib.h>
  244.  
  245. #include "debug.h"
  246. #include "qqdef.h"
  247. #include "memory.h"
  248. #include "config.h"
  249.  
  250. #ifndef __WIN32__
  251. #define stricmp strcasecmp
  252. #endif
  253.  
  254. typedef config_item item;
  255.  
  256. enum PARSING{
  257. NAME,
  258. VALUE
  259. };
  260.  
  261. static void add( config* c, char* name, char* value )
  262. {
  263. if( c->item_count >= 1024 ){
  264. DBG("failed to add config item: too many.");
  265. return;
  266. }
  267. int i = c->item_count ++;
  268. c->items[i] = (config_item*)malloc( sizeof(config_item) );
  269. strncpy( c->items[i]->name, name, CONFIG_NAME_LEN );
  270. strncpy( c->items[i]->value, value, CONFIG_VALUE_LEN );
  271. // printf("added item '%s':'%s'\n", name, value );
  272. }
  273.  
  274. static void parse( config*conf, char* buf, int len )
  275. {
  276. enum PARSING state;
  277. state = NAME;
  278. int i, j;
  279. char c;
  280. char name[CONFIG_NAME_LEN+1], value[CONFIG_VALUE_LEN+1];
  281. i = j = 0;
  282. buf[len] = '\0';
  283. while( i <= len ){
  284. c = buf[i];
  285. switch( state ){
  286. case NAME:
  287. if( c == '\r' ){
  288. break;
  289. }else if( c == '\n' ){ //not found =, but found \n
  290. j = 0;
  291. }else if( c == '=' ){
  292. state = VALUE;
  293. while( j>0 && name[j-1] == ' ' )
  294. j--;
  295. name[j] = '\0'; //add end
  296. j = 0;
  297. }else if( c == '\\' ){
  298. i ++;
  299. }else{
  300. if( j==0 && c == ' ' ) //do not add front space
  301. break;
  302. if( j<CONFIG_NAME_LEN )
  303. name[j++] = c;
  304. }
  305. break;
  306. case VALUE:
  307. if( c == '\r' ){
  308. break;
  309. }else if( c == '\n' || c == '\0' ){
  310. state = NAME;
  311. while( j>0 && value[j-1] == ' ' )
  312. j--;
  313. value[j] = '\0'; //add end
  314. if( name[0] != '#' ){ //comment?? do not add it.
  315. add( conf, name, value );
  316. }
  317. j = 0;
  318. }else if( c == '\\' ){
  319. i ++;
  320. }else{
  321. if( j==0 && c == ' ' ) //do not add front space
  322. break;
  323. if( j<CONFIG_VALUE_LEN )
  324. value[j++] = c;
  325. }
  326. break;
  327. default:
  328. break;
  329. }
  330. i ++;
  331. }
  332. }
  333.  
  334. static char default_configs[]="### Default Configuration ###\n"
  335. "QQPacketLog = 0\n"
  336. "QQTerminalLog = 0\n"
  337. "# 日志目录,删除下面一条将不记录日志。\n"
  338. "QQLogDir = ./log\n"
  339. "# 验证码目录\n"
  340. "QQVerifyDir = ./verify\n"
  341. "# 登录方式 UDP or TCP or PROXY_HTTP\n"
  342. "QQNetwork = UDP\n"
  343. "NO_COLOR = 0\n"
  344. "下面为QQ服务器列表,每个服务器用|来隔开,IP和端口用:来给开。\n"
  345. "电信服务器\n"
  346. "#QQTcpServerList = 219.133.60.173:80|219.133.38.232:80|219.133.40.177:80\n"
  347. "最多允许添加16个\n"
  348. "QQTcpServerList = 219.133.60.173:443|219.133.49.125:443|58.60.15.33:443\n"
  349. "QQUdpServerList = 219.133.49.171:8000|58.60.14.37:8000|219.133.60.36:8000|58.60.15.39:8000|sz6.tencent.com:8000|sz7.tencent.com:8000\n"
  350. "QQHttpProxyServerList = \n"
  351. ;
  352.  
  353. int config_open( config* c, char* filename )
  354. {
  355. FILE* fp;
  356. fp = fopen ( filename, "r" );
  357. if( fp == NULL ){
  358. DBG("failed to open file %s", filename );
  359. fp = fopen( filename, "w" );
  360. if( fp == NULL )
  361. return -1;
  362. fputs( default_configs, fp );
  363. fclose( fp );
  364. fp = fopen( filename, "r" );
  365. if( fp == NULL )
  366. return -1;
  367. }
  368. char* buf;
  369. buf = (char*) malloc( KB(32) );
  370. int len = fread( buf, 1, KB(32), fp );
  371. if( len > 0 ){
  372. memset( c, 0, sizeof(config) );
  373. parse( c, buf, len );
  374. }else{
  375. DBG("failed to read file %s", filename );
  376. fclose( fp );
  377. return -2;
  378. }
  379. free( buf );
  380. fclose( fp );
  381. return 0;
  382. }
  383.  
  384. int config_readint( config*c, char* name )
  385. {
  386. int i;
  387. for( i=0; i<c->item_count; i++ )
  388. {
  389. if( strcmp( c->items[i]->name, name ) == 0 )
  390. {
  391. if( stricmp( c->items[i]->value, "1" ) == 0 )
  392. return 1;
  393. else if( stricmp( c->items[i]->value, "0" ) == 0 )
  394. return 0;
  395. //else
  396. return atol( c->items[i]->value );
  397. }
  398. }
  399. // DBG("config item not found.");
  400. return 0;
  401. }
  402.  
  403. char* config_readstr( config*c, char* name )
  404. {
  405. int i;
  406. for( i=0; i<c->item_count; i++ )
  407. {
  408. if( strcmp( c->items[i]->name, name ) == 0 )
  409. {
  410. return c->items[i]->value;
  411. }
  412. }
  413. // DBG("config item not found.");
  414. return NULL;
  415. }
  416.  
  417. void config_close( config* c )
  418. {
  419. int i;
  420. if( !c ) return;
  421. for( i=0; i<c->item_count; i++ )
  422. free( c->items[i] );
  423. c->item_count = 0;
  424. }
  425.  
  426.  
  427. config *g_conf;
  428. void config_init()
  429. {
  430. NEW( g_conf, sizeof(config) );
  431. if( !g_conf ) return;
  432. if( config_open( g_conf, "./qqconfig.txt" ) < 0 ){
  433. perror("can't not open qqconfig.txt file.");
  434. exit(-1);
  435. }
  436. char* log_dir = config_readstr( g_conf, "QQLogDir" );
  437. uint log_terminal = config_readint( g_conf, "QQTerminalLog" );
  438. if( log_terminal ){
  439. debug_term_on();
  440. }else{
  441. debug_term_off();
  442. }
  443. if( log_dir == NULL ){
  444. debug_file_off();
  445. }else{
  446. debug_set_dir( log_dir );
  447. debug_file_on();
  448. }
  449. }
  450.  
  451. void config_end()
  452. {
  453. config_close( g_conf );
  454. DEL( g_conf );
  455. }
  456.  
  457.  
  458. //test
  459. /*
  460. int main()
  461. {
  462. config* c = (config*)malloc( sizeof( config) );
  463. config_open( c, "./server.txt" );
  464. MSG("port: %d", config_readint( c, "ServerPort" ) );
  465. config_close( c );
  466. free( c );
  467. system("pause");
  468. return 0;
  469. }
  470. */
  471. //config.h
  472. #ifndef _CONFIG_H
  473. #define _CONFIG_H
  474.  
  475. #define CONFIG_NAME_LEN 64
  476. #define CONFIG_VALUE_LEN 256
  477.  
  478.  
  479. typedef struct config_item{
  480. char name[CONFIG_NAME_LEN];
  481. char value[CONFIG_VALUE_LEN];
  482. }config_item;
  483.  
  484. typedef struct cconfig{
  485. int item_count;
  486. config_item *items[1024];
  487. }config;
  488.  
  489. int config_open( config* c, char* filename );
  490. int config_readint( config*c, char* name );
  491. char* config_readstr( config*c, char* name );
  492. void config_close( config* c );
  493.  
  494. //
  495. void config_init();
  496. void config_end();
  497. extern config *g_conf;
  498.  
  499. #endif
  500. /*
  501. * crc32.c
  502. *
  503. * CRC32
  504. *
  505. * Copyright (C) 2008 Huang Guan
  506. *
  507. * 2008-7-12 Created.
  508. *
  509. * Description: This file mainly includes the functions about
  510. * Hash
  511. *
  512. */
  513.  
  514. #include <stdio.h>
  515. #include "qqdef.h"
  516.  
  517. static uint CRC32[256];
  518. static char init = 0;
  519.  
  520. static void init_table()
  521. {
  522. int i,j;
  523. uint crc;
  524. for(i = 0;i < 256;i++)
  525. {
  526. crc = i;
  527. for(j = 0;j < 8;j++)
  528. {
  529. if(crc & 1){
  530. crc = (crc >> 1) ^ 0xEDB88320;
  531. }else{
  532. crc = crc >> 1;
  533. }
  534. }
  535. CRC32[i] = crc;
  536. }
  537. }
  538.  
  539. uint crc32( uchar *buf, int len)
  540. {
  541. uint ret = 0xFFFFFFFF;
  542. int i;
  543. if( !init ){
  544. init_table();
  545. init = 1;
  546. }
  547. for(i = 0; i < len;i++)
  548. {
  549. ret = CRC32[((ret & 0xFF) ^ buf[i])] ^ (ret >> 8);
  550. }
  551. ret = ~ret;
  552. return ret;
  553. }
  554.  
  555. # include "db.h" ;
  556.  
  557.  
  558. void db_connect(MYSQL * pDBConn)
  559. {
  560. char *db_server = "localhost";
  561. char *db_user = "**db user name**";
  562. char *db_password = "**db password**";
  563. char *db_database = "**db name**";
  564. if (!mysql_real_connect(pDBConn, db_server, db_user, db_password, db_database, 0, 0, 0))
  565. {
  566. fprintf(stderr, "%s\n", mysql_error(pDBConn));
  567. exit(1);
  568. }
  569. mysql_query(pDBConn,"SET NAMES UTF8 ;") ;
  570. }
  571.  
  572. MYSQL * db_init()
  573. {
  574. MYSQL * pDBConn = mysql_init(0);
  575. db_connect(pDBConn) ;
  576. return pDBConn ;
  577. }
  578.  
  579. int _db_query(char * psSQL,MYSQL * pDBConn,char * psFile,char * psFunc, int nLine)
  580. {
  581. int nTry = 0 ;
  582.  
  583. while(1)
  584. {
  585. int nRes = mysql_query(pDBConn, psSQL) ;
  586.  
  587. if(nRes>0)
  588. {
  589. int nErr = mysql_errno(pDBConn) ;
  590. char * psErr = mysql_error(pDBConn) ;
  591.  
  592. printf("[mysql error:%d][call: %s:%d %s()]%s\n%s\n]",nErr,psFile,nLine,psFunc,psErr,psSQL) ;
  593.  
  594. if( nErr==2013 || nErr==2006 )
  595. {
  596. nTry ++ ;
  597. printf("%d秒后 重新连接 mysql ...\n",nTry) ;
  598.  
  599. sleep(nTry) ;
  600. db_connect(pDBConn) ;
  601. }
  602. else
  603. {
  604. return nRes ;
  605. }
  606. }
  607.  
  608. else
  609. {
  610. return nRes ;
  611. }
  612. }
  613. }
  614.  
  615. /*
  616. * debug.c
  617. *
  618. * MyQQ debugger.
  619. *
  620. * Copyright (C) 2008 Huang Guan
  621. *
  622. * 2008-01-31 Created.
  623. *
  624. */
  625.  
  626. #include <stdio.h>
  627. #include <stdarg.h>
  628. #include <fcntl.h>
  629. #include <string.h>
  630. #ifdef __WIN32__
  631. #include <io.h>
  632. #endif
  633. #include <time.h>
  634. #include "debug.h"
  635. #include "util.h"
  636. #include "qqdef.h"
  637. #include "utf8.h"
  638.  
  639. static int dbg_term = 0, dbg_file = 0, log_day = 0;
  640. static FILE* fp_log = NULL;
  641. static char dir[128]={0,}, filename[160];
  642.  
  643. void print_error(char* file, char* function, int line, const char *fmt, ...)
  644. {
  645. va_list args;
  646. char printbuf[512];
  647. int i;
  648. if( !dbg_term && !dbg_file )
  649. return;
  650. va_start(args, fmt);
  651. i=vsprintf( printbuf, fmt, args );
  652. printbuf[i] = 0;
  653. va_end(args);
  654. #ifdef __WIN32__
  655. utf8_to_gb( printbuf, printbuf, i );
  656. #endif
  657. if( dbg_term ){
  658. printf("%s(%d): %s\n", function, line, printbuf);
  659. }
  660. if( dbg_file ){
  661. time_t t = time( NULL );
  662. struct tm* tm1 = localtime(&t);
  663. if( !tm1 ) return;
  664. if( tm1->tm_mday != log_day ){
  665. init_file_path(0);
  666. }
  667. char tmp[16];
  668. strftime( tmp, 15, "%X", tm1 );
  669. fprintf( fp_log, "%s [%s]%s(%d): %s\n", tmp, file, function, line, printbuf);
  670. fflush( fp_log );
  671. }
  672. }
  673.  
  674. static char* hex_str(unsigned char *buf, int len, char* outstr )
  675. {
  676.  
  677. const char *set = "0123456789abcdef";
  678. char *tmp;
  679. unsigned char *end;
  680. if (len > 1024)
  681. len = 1024;
  682. end = buf + len;
  683. tmp = &outstr[0];
  684. while (buf < end)
  685. {
  686. *tmp++ = set[ (*buf) >> 4 ];
  687. *tmp++ = set[ (*buf) & 0xF ];
  688. *tmp++ = ' ';
  689. buf ++;
  690. }
  691. *tmp = '\0';
  692. return outstr;
  693. }
  694.  
  695. void hex_dump( unsigned char * buf, int len )
  696. {
  697. char str[KB(4)];
  698. if( dbg_term )
  699. puts( hex_str( buf, len, str ) );
  700. if( dbg_file ){
  701. fputs( hex_str( buf, len, str ), fp_log );
  702. fprintf( fp_log, "\n" );
  703. fflush( fp_log );
  704. }
  705. //fprintf( stderr, hex_str( buf, len ) );
  706. }
  707.  
  708. void debug_term_on()
  709. {
  710. dbg_term = 1;
  711. }
  712.  
  713. void debug_term_off()
  714. {
  715. dbg_term = 0;
  716. }
  717.  
  718. void init_file_path(int nQQAcount)
  719. {
  720. char tmp[64] ;
  721. char tmp2[64] = {0,} ;
  722.  
  723. sprintf(tmp2,"/%d-",nQQAcount) ;
  724.  
  725. time_t t = time( NULL );
  726. struct tm* tm1 = localtime(&t);
  727. if( !tm1 ){
  728. perror("log.c init_file_path: ERROR GETTING SYSTEM TIME.");
  729. }
  730. log_day = tm1->tm_mday;
  731. strftime( tmp, 64, "%Y.%m.%d.log", tm1 );
  732.  
  733. if( access( dir, 0 )!=0 ){
  734. mkdir_recursive( dir );
  735. }
  736. strcpy( filename, dir );
  737. strcat( filename, tmp2 );
  738. strcat( filename, tmp );
  739. if( fp_log )
  740. {
  741. fclose( fp_log );
  742. }
  743. fp_log = fopen( filename, "aw" );
  744. // fp_log = fopen( filename, "w" );
  745. }
  746.  
  747. void debug_file_on()
  748. {
  749. if( dbg_file )
  750. return;
  751. init_file_path(0);
  752. dbg_file = 1;
  753. }
  754.  
  755. void debug_file_off()
  756. {
  757. if( !dbg_file )
  758. return;
  759. dbg_file = 0;
  760. if( fp_log )
  761. fclose( fp_log );
  762. }
  763.  
  764. void debug_set_dir(char* str)
  765. {
  766. strcpy( dir, str );
  767. }
  768.  
  769. /*
  770. * group.c
  771. *
  772. * Group Operations
  773. *
  774. * Copyright (C) 2008 Huang Guan
  775. *
  776. * 2008-7-12 Created.
  777. *
  778. * Description: This file mainly includes the functions about
  779. *
  780. */
  781.  
  782. #include <time.h>
  783. #include <stdlib.h>
  784. #include <string.h>
  785. #include "qqclient.h"
  786. #include "memory.h"
  787. #include "debug.h"
  788. #include "protocol.h"
  789. #include "list.h"
  790. #include "group.h"
  791.  
  792. static int searcher( const void* p, const void* v )
  793. {
  794. return ( ((qqgroup*)p)->number == (int)v );
  795. }
  796.  
  797. qqgroup* group_get( struct qqclient* qq, uint number, int create )
  798. {
  799. if( !number )
  800. return NULL;
  801. qqgroup* g;
  802. g = list_search( &qq->group_list, (void*)number, searcher );
  803. //if not found, g must be NULL
  804. if( !g && create ){
  805. NEW( g, sizeof( qqgroup ) );
  806. if( !g ){
  807. DBG("Fatal error: group not allocated");
  808. return g;
  809. }
  810. g->number = number;
  811. sprintf( g->name, "%u", number );
  812. if( list_append( &qq->group_list, (void*)g )<0 ){
  813. DEL( g );
  814. DBG("group list is full.");
  815. }
  816. }
  817. return g;
  818. }
  819.  
  820. void group_remove( struct qqclient* qq, uint number )
  821. {
  822. qqgroup* g;
  823. g = list_search( &qq->group_list, (void*)number, searcher );
  824. if( g ){
  825. list_remove( &qq->group_list, g );
  826. }
  827. }
  828.  
  829. void group_update_list( struct qqclient* qq )
  830. {
  831. // prot_group_download_list( qq, 0 ); 不知道这个09还能不能用。
  832. prot_group_download_labels( qq, 0 );
  833. }
  834.  
  835. void group_update_info( qqclient* qq, qqgroup* g )
  836. {
  837. }
  838.  
  839.  
  840. void group_put_event( qqclient* qq )
  841. {
  842. char *temp;
  843. int i;
  844. qqgroup* g;
  845. NEW( temp, KB(1) );
  846. if( !temp ) return;
  847. strcpy( temp, "grouplist^$" );
  848. pthread_mutex_lock( &qq->group_list.mutex );
  849. for( i=0; i<qq->group_list.count; i++ ){
  850. g = (qqgroup*)qq->group_list.items[i];
  851. sprintf( temp, "%s%u\t%s^@", temp, g->number, g->name );
  852. }
  853. pthread_mutex_unlock( &qq->group_list.mutex );
  854. qqclient_put_event( qq, temp );
  855. DEL( temp );
  856. }
  857. /*
  858. * libqq.c
  859. *
  860. * LibQQ Program
  861. *
  862. * Copyright (C) 2009 Huang Guan
  863. *
  864. * 2009-5-6 23:23:51 Created.
  865. *
  866. * Description: This file mainly includes the functions about
  867. *
  868. */
  869.  
  870. #define LIBQQLIB
  871.  
  872. #include <stdio.h>
  873. #include <string.h>
  874. #include <stdlib.h>
  875. #include <unistd.h>
  876. #include <pthread.h>
  877. #ifdef __WIN32__
  878. #include <winsock.h>
  879. #include <wininet.h>
  880. #else
  881. #include <sys/socket.h>
  882. #include <arpa/inet.h>
  883. #endif
  884.  
  885. #include "debug.h"
  886. #include "memory.h"
  887. #include "qqclient.h"
  888. #include "libqq.h"
  889. #include "loop.h"
  890. #include "buddy.h"
  891. #include "qun.h"
  892. #include "group.h"
  893. #include "config.h"
  894. #include "qqsocket.h"
  895. #include "utf8.h"
  896.  
  897. #define MAX_USERS 1000
  898.  
  899. static int if_init = 0;
  900.  
  901. static void* login_ex( void* data )
  902. {
  903. qqclient* qq = (qqclient*) data;
  904. pthread_detach(pthread_self());
  905. DBG("login: %u", qq->number );
  906. qqclient_login( qq );
  907. return NULL;
  908. }
  909.  
  910. EXPORT void libqq_init()
  911. {
  912. config_init();
  913. if_init = 1;
  914. qqsocket_init();
  915. }
  916.  
  917. EXPORT void libqq_cleanup()
  918. {
  919. config_end();
  920. qqsocket_end();
  921. }
  922.  
  923. EXPORT qqclient* libqq_create( uint number, char* pass )
  924. {
  925. qqclient* qq;
  926. if( !if_init )
  927. libqq_init();
  928. NEW( qq, sizeof(qqclient) );
  929. if( !qq ){
  930. DEL( qq );
  931. return NULL;
  932. }
  933. qqclient_create( qq, number, pass );
  934. qq->auto_accept = 1; //temporarily do this
  935. return qq;
  936. }
  937.  
  938. EXPORT int libqq_login( qqclient* qq )
  939. {
  940. int ret;
  941. pthread_t ptr;
  942. ret = pthread_create( &ptr, NULL, login_ex, (void*)qq );
  943. if( ret != 0 ){
  944. DBG("thread creation failed. ret=%d", ret );
  945. }
  946. return ret;
  947. }
  948.  
  949. EXPORT int libqq_logout( qqclient* qq )
  950. {
  951. DBG("logout %u", qq->number );
  952. qqclient_logout( qq );
  953. return 0;
  954. }
  955.  
  956. EXPORT int libqq_detach( qqclient* qq )
  957. {
  958. DBG("detach %u", qq->number );
  959. qqclient_detach( qq );
  960. return 0;
  961. }
  962.  
  963. EXPORT int libqq_getmessage( qqclient* qq, char* buf, int size, int wait )
  964. {
  965. int ret;
  966. ret = qqclient_get_event( qq, buf, size, wait );
  967. utf8_to_gb( buf, buf, size );
  968. return ret;
  969. }
  970.  
  971. EXPORT int libqq_sendmessage( qqclient* qq, uint to, char* buf, char qun_msg )
  972. {
  973. char* tmp;
  974. int len = strlen(buf);
  975. if( len<1 ) return -2;
  976. NEW( tmp, len*2 );
  977. gb_to_utf8( buf, tmp, len*2-1 );
  978. if( qun_msg ){
  979. qqqun* q = qun_get_by_ext( qq, to );
  980. if( q )
  981. qun_send_message( qq, q->number, tmp );
  982. }else{
  983. buddy_send_message( qq, to, tmp );
  984. }
  985. DEL( tmp );
  986. return 0;
  987. }
  988.  
  989. EXPORT void libqq_updatelist( qqclient* qq )
  990. {
  991. buddy_update_list( qq );
  992. group_update_list( qq );
  993. }
  994.  
  995. // 090622 by Huang Guan. change the type of code from uint to const char*
  996. EXPORT void libqq_verify( qqclient* qq, const char* code )
  997. {
  998. if( code ){
  999. qqclient_verify( qq, *(uint*)code );
  1000. }else{
  1001. qqclient_verify( qq, 0x00000000 ); //this will make the server change another png
  1002. }
  1003. }
  1004.  
  1005.  
  1006. EXPORT void libqq_remove( qqclient* qq )
  1007. {
  1008. qqclient_cleanup( qq ); //will call qqclient_logout if necessary
  1009. DEL( qq );
  1010. }
  1011.  
  1012. EXPORT void libqq_status( qqclient* qq, int st, uchar has_camera )
  1013. {
  1014. qq->has_camera = has_camera;
  1015. qqclient_change_status( qq, st );
  1016. }
  1017.  
  1018. EXPORT void libqq_addbuddy( qqclient* qq, uint uid, char* msg )
  1019. {
  1020. qqclient_add( qq, uid, msg );
  1021. }
  1022.  
  1023. EXPORT void libqq_delbuddy( qqclient* qq, uint uid )
  1024. {
  1025. qqclient_del( qq, uid );
  1026. }
  1027.  
  1028.  
  1029. void buddy_msg_callback ( qqclient* qq, uint uid, time_t t, char* msg, qqmessage* pMsg )
  1030. {
  1031. char timestr[24];
  1032. struct tm * timeinfo;
  1033. char* str;
  1034. int len;
  1035. timeinfo = localtime ( &t );
  1036. strftime( timestr, 24, "%Y-%m-%d %H:%M:%S", timeinfo );
  1037. len = strlen( msg );
  1038. NEW( str, len+64 );
  1039. if( uid == 10000 ){
  1040. sprintf( str, "broadcast^$System^$%s", msg );
  1041. }else{
  1042. sprintf( str, "buddymsg^$%u^$%s^$%s", uid, timestr, msg );
  1043. }
  1044. qqclient_put_message( qq, str );
  1045. }
  1046.  
  1047. void qun_msg_callback ( qqclient* qq, uint uid, uint int_uid,
  1048. time_t t, char* msg )
  1049. {
  1050. qqqun* q;
  1051. char timestr[24];
  1052. struct tm * timeinfo;
  1053. char* str;
  1054. int len;
  1055. timeinfo = localtime ( &t );
  1056. strftime( timestr, 24, "%Y-%m-%d %H:%M:%S", timeinfo );
  1057. q = qun_get( qq, int_uid, 1 );
  1058. if( !q ){
  1059. DBG("error: q=NULL");
  1060. return;
  1061. }
  1062. len = strlen( msg );
  1063. NEW( str, len+64 );
  1064. sprintf( str, "clustermsg^$%u^$%u^$%s^$%s", q->ext_number, uid, timestr, msg );
  1065. qqclient_put_message( qq, str );
  1066. }
  1067.  
  1068. EXPORT uint libqq_refresh( qqclient* qq )
  1069. {
  1070. char event[16];
  1071. qqclient_set_process( qq, qq->process );
  1072. sprintf( event, "status^$%d", qq->mode );
  1073. qqclient_put_event( qq, event );
  1074. buddy_put_event( qq );
  1075. group_put_event( qq );
  1076. qun_put_event( qq );
  1077. qqclient_set_process( qq, qq->process );
  1078. return qq->number;
  1079. }
  1080.  
  1081. EXPORT void libqq_getqunname( qqclient* qq, uint ext_id, char* buf )
  1082. {
  1083. qqqun* q = qun_get_by_ext( qq, ext_id );
  1084. if( q ){
  1085. strncpy( buf, q->name, 15 );
  1086. }else{
  1087. if( ext_id != 0 ){
  1088. sprintf( buf, "%u" , ext_id );
  1089. }
  1090. }
  1091. }
  1092.  
  1093. EXPORT void libqq_getqunmembername( qqclient* qq, uint ext_id, uint uid, char* buf )
  1094. {
  1095. qqqun* q = qun_get_by_ext( qq, ext_id );
  1096. if( q ){
  1097. qunmember* m = qun_member_get( qq, q, uid, 0 );
  1098. if( m ){
  1099. strncpy( buf, m->nickname, 15 );
  1100. return;
  1101. }
  1102. }
  1103. if( uid != 0 ){
  1104. sprintf( buf, "%u" , uid );
  1105. }
  1106. }
  1107.  
  1108. EXPORT void libqq_getbuddyname( qqclient* qq, uint uid, char* buf )
  1109. {
  1110. qqbuddy* b = buddy_get( qq, uid, 0 );
  1111. if( b ){
  1112. strncpy( buf, b->nickname, 15 );
  1113. }else{
  1114. if( uid != 0 ){
  1115. sprintf( buf, "%u" , uid );
  1116. }
  1117. }
  1118. }
  1119.  
  1120. // 090706 by HG
  1121. EXPORT void libqq_sethttpproxy( struct qqclient* qq, char* ip, ushort port )
  1122. {
  1123. struct sockaddr_in addr;
  1124. qq->network = PROXY_HTTP;
  1125. netaddr_set( ip, &addr );
  1126. qq->proxy_server_ip = ntohl( addr.sin_addr.s_addr );
  1127. qq->proxy_server_port = port;
  1128. }
  1129.  
  1130.  
  1131. EXPORT void libqq_getextrainfo( struct qqclient* qq, uint uid )
  1132. {
  1133. prot_buddy_get_extra_info( qq, uid );
  1134. }
  1135. #ifndef _libQQ_H
  1136. #define _libQQ_H
  1137.  
  1138. #include <time.h>
  1139.  
  1140. #ifdef __WIN32__
  1141.  
  1142. #define STDCALL __stdcall
  1143. #ifdef LIBQQLIB
  1144. #define EXPORT __declspec(dllexport) STDCALL
  1145. #else
  1146. #define EXPORT __declspec(dllimport) STDCALL
  1147. #endif
  1148.  
  1149. #else
  1150. #define EXPORT
  1151. #endif
  1152.  
  1153. struct qqclient;
  1154.  
  1155. EXPORT void libqq_init();
  1156. EXPORT void libqq_cleanup();
  1157. EXPORT struct qqclient* libqq_create( uint number, char* pass );
  1158. EXPORT int libqq_login( struct qqclient* qq );
  1159. EXPORT int libqq_logout( struct qqclient* qq );
  1160. EXPORT int libqq_detach( struct qqclient* qq );
  1161. EXPORT int libqq_getmessage( struct qqclient* qq, char* buf, int size, int wait );
  1162. EXPORT int libqq_sendmessage( struct qqclient* qq, uint to, char* buf, char qun_msg );
  1163. EXPORT void libqq_updatelist( struct qqclient* qq );
  1164. EXPORT void libqq_verify( struct qqclient* qq, const char* code );
  1165. EXPORT void libqq_remove( struct qqclient* qq );
  1166. EXPORT void libqq_status( struct qqclient* qq, int st, uchar has_camera );
  1167. EXPORT uint libqq_refresh( struct qqclient* qq );
  1168. EXPORT void libqq_getqunname( struct qqclient* qq, uint ext_id, char* buf );
  1169. EXPORT void libqq_getqunmembername( struct qqclient* qq, uint ext_id, uint uid, char* buf );
  1170. EXPORT void libqq_getbuddyname( struct qqclient* qq, uint uid, char* buf );
  1171. EXPORT void libqq_getextrainfo( struct qqclient* qq, uint uid );
  1172. EXPORT void libqq_addbuddy( struct qqclient* qq, uint uid, char* msg );
  1173. EXPORT void libqq_delbuddy( struct qqclient* qq, uint uid );
  1174. EXPORT void libqq_sethttpproxy( struct qqclient* qq, char* ip, ushort port );
  1175.  
  1176. #endif
  1177. /*
  1178. * list.c
  1179. *
  1180. * List
  1181. *
  1182. * Copyright (C) 2008 Huang Guan
  1183. *
  1184. * 2008-7-12 Created.
  1185. *
  1186. * Description: This file mainly includes the functions about
  1187. *
  1188. */
  1189.  
  1190. #include <string.h>
  1191. #include <stdlib.h>
  1192. #include <pthread.h>
  1193. #include "qqdef.h"
  1194. #include "debug.h"
  1195. #include "memory.h"
  1196. #include "list.h"
  1197.  
  1198.  
  1199. int list_create( list* l, int size )
  1200. {
  1201. l->size = size;
  1202. l->count = 0;
  1203. pthread_mutex_init( &l->mutex, NULL );
  1204. NEW( l->items, l->size*sizeof(void*) );
  1205. assert( l->items );
  1206. return 0;
  1207. }
  1208.  
  1209. int list_append( list* l, void* data )
  1210. {
  1211. int i, ret = 0;
  1212. pthread_mutex_lock( &l->mutex );
  1213. if( l->count >= l->size ){
  1214. DBG("list is full. count:%d", l->count);
  1215. ret = -1;
  1216. }else{
  1217. i = l->count ++;
  1218. l->items[i] = data;
  1219. }
  1220. pthread_mutex_unlock( &l->mutex );
  1221. return ret;
  1222. }
  1223.  
  1224. int list_remove( list* l, void* data )
  1225. {
  1226. int i;
  1227. pthread_mutex_lock( &l->mutex );
  1228. for( i=0; i<l->count; i++ ){
  1229. if( l->items[i] == data ){
  1230. l->count --;
  1231. if( i != l->count )
  1232. l->items[i] = l->items[l->count];
  1233. break;
  1234. }
  1235. }
  1236. pthread_mutex_unlock( &l->mutex );
  1237. return 0;
  1238. }
  1239.  
  1240. void* list_search( list* l, void* v, search_func search )
  1241. {
  1242. int i;
  1243. pthread_mutex_lock( &l->mutex );
  1244. for( i=0; i<l->count; i++ ){
  1245. if( search( l->items[i], v ) )
  1246. break;
  1247. }
  1248. pthread_mutex_unlock( &l->mutex );
  1249. if( i < l->count )
  1250. return l->items[i];
  1251. return NULL;
  1252. }
  1253.  
  1254. void list_sort( list* l, comp_func comp )
  1255. {
  1256. pthread_mutex_lock( &l->mutex );
  1257. if( l->count == 0 )
  1258. return;
  1259. qsort( l->items, l->count, sizeof(void*), comp );
  1260. pthread_mutex_unlock( &l->mutex );
  1261. }
  1262.  
  1263. void list_cleanup( list* l )
  1264. {
  1265. int i;
  1266. pthread_mutex_lock( &l->mutex );
  1267. if( l->count > 0 ){
  1268. // DBG("list count = %d", l->count );
  1269. for( i=0; i<l->count; i++ ){
  1270. DEL( l->items[i] );
  1271. }
  1272. }
  1273. DEL( l->items );
  1274. pthread_mutex_unlock( &l->mutex );
  1275. pthread_mutex_destroy( &l->mutex );
  1276. }
  1277.  
  1278.  
  1279. /*
  1280. * memory.c
  1281. *
  1282. * Memory Management
  1283. *
  1284. * Copyright (C) 2008 Huang Guan
  1285. *
  1286. * 2008-7-9 15:40:05 Created.
  1287. *
  1288. * Description: This file mainly includes the functions about
  1289. * allocating/releasing memory.
  1290. *
  1291. */
  1292.  
  1293. #include <stdio.h>
  1294. #include <string.h>
  1295. #include <stdlib.h>
  1296. #include <time.h>
  1297.  
  1298. #include "debug.h"
  1299. #include "memory.h"
  1300.  
  1301. mem_detail* g_md;
  1302.  
  1303. void memory_init()
  1304. {
  1305. if( !g_md ){
  1306. g_md = (mem_detail*)malloc(sizeof(mem_detail));
  1307. memset( g_md, 0, sizeof(mem_detail) );
  1308. pthread_mutex_init( &g_md->mutex_mem, NULL );
  1309. }
  1310. }
  1311.  
  1312. void memory_new_detail( void** p, int size, char* file, char* function, int line, char* name )
  1313. {
  1314. char temp[128];
  1315. sprintf( temp, "[%s]%s(%d) %s", file, function, line, name );
  1316. memory_new( p, size, temp );
  1317. }
  1318.  
  1319. void memory_new( void** p, int size, char* memo )
  1320. {
  1321. if( !g_md )
  1322. memory_init();
  1323. *p = NULL;
  1324. if( g_md->item_count >= MAX_ALLOCATION )
  1325. {
  1326. DBG("no more allocations."); return;
  1327. }
  1328. *p = malloc(size);
  1329. memset( *p, 0, size );
  1330. if( *p == NULL ){
  1331. DBG("no enough memory.");
  1332. exit(-1);
  1333. }
  1334. pthread_mutex_lock( &g_md->mutex_mem );
  1335. int i = g_md->item_count ++;
  1336. g_md->items[i] = (allocation*)malloc(sizeof(allocation));
  1337. //zero
  1338. g_md->items[i]->pointer = *p;
  1339. g_md->items[i]->size = size;
  1340. strncpy( g_md->items[i]->memo, memo, MEMO_LEN );
  1341. g_md->items[i]->time_alloc = time( NULL );
  1342. pthread_mutex_unlock( &g_md->mutex_mem );
  1343. //ok
  1344. }
  1345.  
  1346. //a piece of very lazy code
  1347. void memory_delete( void* p )
  1348. {
  1349. int i;
  1350. if( p == NULL ) return;
  1351. pthread_mutex_lock( &g_md->mutex_mem );
  1352. for( i=0; i<g_md->item_count; i++ )
  1353. {
  1354. if( g_md->items[i]->pointer == p )
  1355. {
  1356. free( p );
  1357. free( g_md->items[i] );
  1358. g_md->item_count --;
  1359. if( i!=g_md->item_count )
  1360. g_md->items[i] = g_md->items[g_md->item_count];
  1361. g_md->items[g_md->item_count] = NULL;
  1362. pthread_mutex_unlock( &g_md->mutex_mem );
  1363. return;
  1364. }
  1365. }
  1366. DBG("not found pointer %x", p );
  1367. pthread_mutex_unlock( &g_md->mutex_mem );
  1368. }
  1369.  
  1370. void memory_end(){
  1371. if( !g_md ) return;
  1372. DBG("g_md->item_count = %d", g_md->item_count );
  1373. if( g_md->item_count>0 ){
  1374. memory_print();
  1375. }
  1376. pthread_mutex_destroy( &g_md->mutex_mem );
  1377. }
  1378.  
  1379. void memory_print(){
  1380. if( !g_md ) return;
  1381. DBG("#memory info dumping (item_count: %d) ", g_md->item_count );
  1382. int i;
  1383. pthread_mutex_lock( &g_md->mutex_mem );
  1384. for( i=0; i<g_md->item_count; i++ )
  1385. {
  1386. char timestr[10];
  1387. struct tm* t = localtime( & g_md->items[i]->time_alloc);
  1388. strftime( timestr, 10, "%X", t );
  1389. DBG("[%d] 0x%x(%d)\t%s\t%s", i, g_md->items[i]->pointer, g_md->items[i]->size,
  1390. g_md->items[i]->memo, timestr );
  1391. }
  1392. pthread_mutex_unlock( &g_md->mutex_mem );
  1393. }
  1394.  
  1395. //test
  1396. /*
  1397. int main()
  1398. {
  1399. memory_init();
  1400. char* p, *str2;
  1401. NEW( str2, 1024 );
  1402. NEW( p, 256 );
  1403. strcpy( str2, "hello");
  1404. puts( str2 );
  1405. DEL( p );
  1406. memory_end();
  1407. return 0;
  1408. }
  1409. */
Add Comment
Please, Sign In to add comment