免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6648 | 回复: 4
打印 上一主题 下一主题

[技巧]tnscmd 工具C語言版本 [复制链接]

求职 : 数据库管理员
论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-20 09:13 |只看该作者 |倒序浏览
tnscmd.pl 是一個強大的遠端管理Oracle Listener的工具.
由perl語言實現.
可以查看監聽器狀況,版本,列舉服務,停止監聽等.
查看Oracle 10g時有出現tns版本不符狀況.
TNS COMMAND需要新增一項(VERSION=169869568))
仿照tnscmd的思想用C語言重新實現了一遍.

程序還不是怎麼完善,但基本可用.
感興趣的朋友可以玩玩

歡迎大家一起幫忙來改進,完善它.



11/24日已稍作更新.
為方便本機沒有gcc的朋友,下載檔中新增一個編譯好的tnscmd.exe




在linux和windows平台下可用gcc編議

compile

  1. win32:
  2. gcc -Wall  -o tnscmd   tnscmd.c -lwsock32
  3. Linux;
  4. gcc -Wall  -o tnscmd   tnscmd.c
复制代码


使用
如果監聽器有設置可令才需要 -p password

  1. $tnscmd  status   -h oraclehost
  2. $tnscmd -h oraclehost
  3. $tnscmd status -h oraclehost -p password
  4. 停止監聽
  5. $tnscmd stop -h oraclehost
复制代码




部份代碼是從我常用的庫中剝出來的,
圖方便就直接放在 tnscmd.h中了

tnscmd.h

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>

  4. #ifdef _WIN32
  5.         #include <winerror.h>
  6.         #include <wininet.h>
  7.         #include <winsock.h>
  8.         #include <stdint.h>

  9.         #include <winsock2.h>
  10.         #define sockstart(name)  \
  11.                 do {\
  12.                         WSADATA name;  \
  13.                         if (WSAStartup(MAKEWORD(1,1) ,&name))  \
  14.                                 perror("sockstart") ;  \
  15.                 } while(0)

  16.         #define sockend()  WSACleanup()

  17. #else
  18.         #include <unistd.h>
  19.         #include <sys/socket.h>
  20.         #include <sys/types.h>
  21.         #include <arpa/inet.h>
  22.         #include <netinet/in.h>
  23.         #include <netdb.h>
  24.         #define sockstart(name)
  25.         #define sockend()

  26.         #ifndef  closesocket
  27.                 #define closesocket  close
  28.         #endif
  29. #endif




  30. /*
  31. @tcp_connect:

  32. @ return socket   
  33. */

  34. int  tcp_connect(const  char *hostname,  uint16_t   port)
  35. {
  36.         int  sockfd ;
  37.         struct hostent *hostent ;

  38.         struct sockaddr_in client_addr;



  39.         hostent = gethostbyname(hostname);

  40.         if(NULL == hostent) {
  41.                  return  -1 ;
  42.         }


  43.         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
  44.                 perror("sockfd ");
  45.                 return (-2);
  46.         }
  47.         client_addr.sin_family=AF_INET;
  48.         client_addr.sin_port=htons( port );


  49.         memcpy(&client_addr.sin_addr, hostent->h_addr_list[0], sizeof(client_addr.sin_addr));


  50.         memset(&(client_addr.sin_zero),0,8);
  51.         if (connect(sockfd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == -1) {
  52.                 perror("Connec Error");
  53.                 return -3 ;
  54.         }


  55.         return (sockfd );
  56. }

  57. void int2hex(char *dest, int val, int size)
  58. {
  59.          int i ;
  60.          unsigned int x=val;
  61.          char *dic="0123456789ABCDEF" ;
  62.          for (i=0; i<size; i++){
  63.                dest[size-1-i]= dic[ x & 0x0f] ;
  64.                x = x >>4 ;
  65.          }

  66. }


  67. void sprt_hex(char *buf, char ch, int idx)
  68. {
  69.          char *p ;

  70.          p=buf +idx *3 ;
  71.          if (idx>7) {
  72.                  p+=1 ;
  73.          }

  74.          int2hex(p,ch, 2);
  75.          p[2] =' ';


  76.          if (isprint(ch)) {
  77.                  buf[50+idx]= ch ;
  78.          } else {
  79.                  buf[50+idx]= '.' ;
  80.          }
  81.   
  82.   
  83. }

  84. #define  LSIZE 80

  85. /*
  86. * hex_dump: print ptr in hex mode
  87. *           16 byte/line
  88. *   
  89. */

  90. void hex_dump( char *ptr, int size, int offset)
  91. {

  92.          char buf[LSIZE] ;
  93.          

  94.          
  95.          int x;
  96.          char *p=ptr ;
  97.          char *lim = p+ size ;



  98.          while (p <lim) {
  99.                  memset(buf,' ', LSIZE) ;
  100.                  x =p-ptr ;
  101.                  x+= offset;
  102.                  int2hex(buf, x , 6);

  103.                  for (x=0;  x<16 && p<lim;   x++,p++)
  104.                         sprt_hex(&buf[8], *p,  x);

  105.                  x =58;
  106.                  buf[x-1] ='|';
  107.                  buf[x+16] ='|' ;
  108.                  buf[x+16+1] ='\0';
  109.                  fprintf(stderr, "%s\n",buf);

  110.          }
  111. }




  112. size_t dump_char(const void *ptr, size_t size, size_t nmemb,
  113.               FILE *stream)
  114. {
  115.   /*
  116.             return fwrite(ptr,size,  nmemb, stream);
  117.   */
  118.            char *p=(char *)ptr ;
  119.          char *lim = p + size * nmemb  ;
  120.          char ch;
  121.          

  122.          for (;p<lim; p++) {
  123.                  ch = *p ;
  124.                  if  (isprint(ch) || ch =='\n' || ch=='\r' ) {
  125.                          putc(ch, stream);
  126.                  }else {
  127.                          fputc('.', stream);

  128.                  }
  129.                  
  130.          }

  131.          return 0;
  132. }






  133. size_t dump_char_parenify(const void *ptr, size_t size, size_t nmemb,
  134.               FILE *stream)
  135. {

  136.            char *p=(char *)ptr ;
  137.          char *lim = p + size * nmemb  ;
  138.          char ch;
  139.          int indent =0 ;
  140.          int o_indent = 0;
  141.          int i ;
  142.          for (;p<lim; p++) {
  143.                  ch = *p ;
  144.                  if (ch =='(') indent++;
  145.                  if (ch ==')') indent--;
  146.                  if (indent != o_indent) {
  147.                          if (p[1]  != '('   ){
  148.                                  fputc('\n', stream);
  149.                          }

  150.                          for (i=0; i< indent; i++) {
  151.                                  fprintf(stream, "  ");
  152.                          }
  153.                          o_indent = indent ;
  154.                  }
  155.                  
  156.                  //putc(ch,stream);
  157.                  
  158.                  if  (isprint(ch) || ch =='\n' || ch=='\r' ) {
  159.                          putc(ch, stream);
  160.                  }else {
  161.                          fputc(' ', stream);
  162.                  }
  163.                  
  164.                  
  165.          }
  166.          return 0;
  167. }





  168. void  usage();


复制代码


tnscmd.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>

  5. #include "tnscmd.h"
  6. #define BSIZE  10240


  7. /*Oracle 8.1.7 head */  
  8. char  head_pack[]  = { 0,    0   , 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\
  9.                        0x01, 0x36, 0x01, 0x2c, 0x00, 0x00, 0x08, 0x00,\
  10.                        0x7f, 0xff, 0x7f, 0x08, 0x00, 0x00, 0x00, 0x01,\
  11.                        0,    0 ,   0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,\
  12.                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
  13.                        0x00, 0x00, 0x00, 0x00, 0x34, 0xe6, 0x00, 0x00,\
  14.                        0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
  15.                        0x00, 0x00 };




  16. /*Oracle 10.0.1  head */  
  17. char head_pack1[] ={ 0,   0   ,0x00,0x00,0x01,0x00,0x00, 0x00,
  18.                      0x01,0x39,0x01,0x2c,0x00,0x00,0x08, 0x00,
  19.                      0x7f,0xff,0x7f,0x08,0x00,0x00,0x01, 0x00,
  20.                      0,   0,   0x00,0x3a,0x00,0x00,0x00, 0x00,
  21.                      0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,
  22.                      0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,
  23.                      0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,
  24.                      0x00,0x00} ;



  25. size_t (* write_func)(const void *ptr, size_t size, size_t nmemb,   FILE *stream) = dump_char  ;
  26. int debug_mode = 0;





  27. int build_packet(char *dest, char *cmd)
  28. {
  29.          int cmd_len = strlen(cmd) ;
  30.          int packetlen = sizeof(head_pack)  + cmd_len;

  31.          memcpy(dest, head_pack,  sizeof(head_pack));
  32.          

  33.          dest[0] =(char) packetlen  >> 8;
  34.          dest[1] =(char) packetlen & 0xff;

  35.          


  36.          dest[24] = (char) cmd_len >>8 ;
  37.          dest[25] = (char) cmd_len & 0xff ;
  38.          memcpy(&dest[sizeof(head_pack)], cmd, strlen(cmd));
  39.          
  40.          return  sizeof(head_pack)  + strlen(cmd) ;
  41. }


  42. int getpacklen(unsigned char *p)
  43. {

  44.          unsigned char c0,c1 ;
  45.          c0 =p[0] ;
  46.          c1 =p[1] ;
  47.          return c0 *256 + c1 ;
  48. }


  49. int ora_recv(unsigned int sock, void *buf, unsigned int *packlen)
  50. {

  51.          int rlen =0;

  52.          rlen = recv(sock,buf, BSIZE , 0);  
  53.          if (rlen <=0) {
  54.                  *packlen = 0;
  55.                  return 0;
  56.          }
  57.          *packlen  = getpacklen(buf)  ;

  58.          if (debug_mode ==1) {
  59.                  fprintf(stdout, "recv:%d  packlen:%d\n",rlen , *packlen );
  60.                  hex_dump(buf, rlen, 0);
  61.          }
  62.          

  63.          return rlen ;
  64. }

  65. /*
  66. @tns_cmd : send tns command && recv message from oracle listener

  67. */

  68. int tns_cmd(int sock,char *cmd,char *pass)
  69. {
  70.          char buf[BSIZE] ;


  71.          char command[1024];
  72.          unsigned int packlen =0;

  73.          ssize_t rlen ,slen;
  74.          


  75.          if (pass ==NULL)
  76.                  sprintf(command,"(CONNECT_DATA=(COMMAND=%s)(VERSION=169869568))",cmd);
  77.          else
  78.                  sprintf(command,"(CONNECT_DATA=(COMMAND=%s)(PASSWORD=%s)(VERSION=169869568))",cmd,pass);


  79.          slen = build_packet(buf, command);


  80.          fprintf(stdout, "send command: %s\n\n", command);
  81.          rlen =send(sock, buf, slen,0);


  82.          fprintf(stdout, "begin recv\n");
  83.          

  84.          rlen = ora_recv(sock, buf, &packlen);
  85.          char * p=buf ;

  86.          packlen = packlen < rlen ?packlen:rlen ;
  87.          if  (buf[4] ==4 ) {

  88.                  write_func(&p[12], packlen - 12 ,1, stdout);
  89.                  write_func("\n", 1,1,stdout);
  90.                  return 0;
  91.          }



  92.          send(sock, "\n",1,0);



  93.          while ((rlen = ora_recv(sock, p, &packlen))  >0) {
  94.                 /*this line for  raise  error  some times */
  95.            //                 packlen = packlen < rlen ?packlen:rlen ;
  96.                  write_func(&p[10],  rlen -10  ,1, stdout);
  97.          }

  98.          write_func("\n", 1,1, stdout);

  99.          return 0;
  100. }



  101. extern char *optarg;


  102. int main(int argc, char *argv[])
  103. {
  104.          char *host = NULL;
  105.          char *cmd  = NULL;
  106.          char *pass = NULL;
  107.          int port = 1521 ;


  108.          int flags, opt;
  109.          int nsecs, tfnd;


  110.          if (argc >1 && argv[1][0] == '-') {
  111.                  cmd = "ping";
  112.          }else {
  113.                  cmd = argv[1] ;
  114.          }

  115.          
  116.          

  117.          nsecs = 0;
  118.          tfnd = 0;
  119.          flags = 0;
  120.          while ((opt = getopt(argc, argv, "dih:p:")) != -1) {
  121.                  switch (opt) {
  122.                  case 'h':
  123.                    host = optarg ;
  124.                    break;
  125.                  case 'p':
  126.                    pass = optarg ;
  127.                    break;
  128.                  case 'i':
  129.                    write_func = dump_char_parenify ;
  130.                    break ;
  131.                  case 'd':
  132.                    debug_mode =1 ;
  133.                    break ;
  134.                  default: /* '?' */
  135.                          usage();
  136.                          exit(EXIT_FAILURE);
  137.                  }
  138.          }


  139.          
  140.          if (host ==NULL) {
  141.                  usage();
  142.                  exit(EXIT_FAILURE);

  143.          } ;

  144.          sockstart(wsad);
  145.          int sock = tcp_connect(host, port) ;
  146.          printf("connect to %s:%d\n", host,port);
  147.          if (sock<0) {
  148.                  exit(-1);
  149.          }

  150.          tns_cmd(sock, cmd, pass);
  151.          closesocket(sock) ;
  152.          sockend() ;

  153.          exit (EXIT_SUCCESS);
  154. }




  155. void  usage()
  156. {

  157.   fprintf(stderr, "Usage: tnscmd [command] -h hostname\n\
  158.   where 'command' is something like ping, version, status, etc.\n\
  159.   (default is ping)\n\
  160.        [-p pass] -  the Oracle listener password\n\
  161.        [-r rawcmd command] - build your own CONNECT_DATA string\n\
  162.        [-i]  indent & outdent on parens\n\
  163.        [-d]  debug mode & print hex data \n"  );


  164. }

复制代码


all code:



            阿飛
            2007/11/20

[ 本帖最后由 gangjh 于 2007-11-24 08:42 编辑 ]

tnscmd.tar.gz

14.09 KB, 下载次数: 574

tnscmd.tar.gz

论坛徽章:
0
2 [报告]
发表于 2007-11-20 10:42 |只看该作者

——C较强嘛

——试试。

求职 : 数据库管理员
论坛徽章:
0
3 [报告]
发表于 2007-11-23 16:40 |只看该作者
稍微作了點修改.

论坛徽章:
0
4 [报告]
发表于 2007-11-23 16:48 |只看该作者
一定要试试 ````:em11:

论坛徽章:
0
5 [报告]
发表于 2009-02-06 20:00 |只看该作者
3Q嘿嘿`测试去
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP