- 求职 : 数据库管理员
- 论坛徽章:
- 0
|
tnscmd.pl 是一個強大的遠端管理Oracle Listener的工具.
由perl語言實現.
可以查看監聽器狀況,版本,列舉服務,停止監聽等.
查看Oracle 10g時有出現tns版本不符狀況.
TNS COMMAND需要新增一項(VERSION=169869568))
仿照tnscmd的思想用C語言重新實現了一遍.
程序還不是怎麼完善,但基本可用.
感興趣的朋友可以玩玩
歡迎大家一起幫忙來改進,完善它.
11/24日已稍作更新.
為方便本機沒有gcc的朋友,下載檔中新增一個編譯好的tnscmd.exe
在linux和windows平台下可用gcc編議
compile
- win32:
- gcc -Wall -o tnscmd tnscmd.c -lwsock32
- Linux;
- gcc -Wall -o tnscmd tnscmd.c
复制代码
使用
如果監聽器有設置可令才需要 -p password
- $tnscmd status -h oraclehost
- $tnscmd -h oraclehost
- $tnscmd status -h oraclehost -p password
- 停止監聽
- $tnscmd stop -h oraclehost
复制代码
部份代碼是從我常用的庫中剝出來的,
圖方便就直接放在 tnscmd.h中了
tnscmd.h
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #ifdef _WIN32
- #include <winerror.h>
- #include <wininet.h>
- #include <winsock.h>
- #include <stdint.h>
- #include <winsock2.h>
- #define sockstart(name) \
- do {\
- WSADATA name; \
- if (WSAStartup(MAKEWORD(1,1) ,&name)) \
- perror("sockstart") ; \
- } while(0)
- #define sockend() WSACleanup()
- #else
- #include <unistd.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #define sockstart(name)
- #define sockend()
- #ifndef closesocket
- #define closesocket close
- #endif
- #endif
- /*
- @tcp_connect:
- @ return socket
- */
- int tcp_connect(const char *hostname, uint16_t port)
- {
- int sockfd ;
- struct hostent *hostent ;
- struct sockaddr_in client_addr;
- hostent = gethostbyname(hostname);
- if(NULL == hostent) {
- return -1 ;
- }
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
- perror("sockfd ");
- return (-2);
- }
- client_addr.sin_family=AF_INET;
- client_addr.sin_port=htons( port );
- memcpy(&client_addr.sin_addr, hostent->h_addr_list[0], sizeof(client_addr.sin_addr));
- memset(&(client_addr.sin_zero),0,8);
- if (connect(sockfd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == -1) {
- perror("Connec Error");
- return -3 ;
- }
- return (sockfd );
- }
- void int2hex(char *dest, int val, int size)
- {
- int i ;
- unsigned int x=val;
- char *dic="0123456789ABCDEF" ;
- for (i=0; i<size; i++){
- dest[size-1-i]= dic[ x & 0x0f] ;
- x = x >>4 ;
- }
- }
- void sprt_hex(char *buf, char ch, int idx)
- {
- char *p ;
- p=buf +idx *3 ;
- if (idx>7) {
- p+=1 ;
- }
- int2hex(p,ch, 2);
- p[2] =' ';
- if (isprint(ch)) {
- buf[50+idx]= ch ;
- } else {
- buf[50+idx]= '.' ;
- }
-
-
- }
- #define LSIZE 80
- /*
- * hex_dump: print ptr in hex mode
- * 16 byte/line
- *
- */
- void hex_dump( char *ptr, int size, int offset)
- {
- char buf[LSIZE] ;
-
-
- int x;
- char *p=ptr ;
- char *lim = p+ size ;
- while (p <lim) {
- memset(buf,' ', LSIZE) ;
- x =p-ptr ;
- x+= offset;
- int2hex(buf, x , 6);
- for (x=0; x<16 && p<lim; x++,p++)
- sprt_hex(&buf[8], *p, x);
- x =58;
- buf[x-1] ='|';
- buf[x+16] ='|' ;
- buf[x+16+1] ='\0';
- fprintf(stderr, "%s\n",buf);
- }
- }
- size_t dump_char(const void *ptr, size_t size, size_t nmemb,
- FILE *stream)
- {
- /*
- return fwrite(ptr,size, nmemb, stream);
- */
- char *p=(char *)ptr ;
- char *lim = p + size * nmemb ;
- char ch;
-
- for (;p<lim; p++) {
- ch = *p ;
- if (isprint(ch) || ch =='\n' || ch=='\r' ) {
- putc(ch, stream);
- }else {
- fputc('.', stream);
- }
-
- }
- return 0;
- }
- size_t dump_char_parenify(const void *ptr, size_t size, size_t nmemb,
- FILE *stream)
- {
- char *p=(char *)ptr ;
- char *lim = p + size * nmemb ;
- char ch;
- int indent =0 ;
- int o_indent = 0;
- int i ;
- for (;p<lim; p++) {
- ch = *p ;
- if (ch =='(') indent++;
- if (ch ==')') indent--;
- if (indent != o_indent) {
- if (p[1] != '(' ){
- fputc('\n', stream);
- }
- for (i=0; i< indent; i++) {
- fprintf(stream, " ");
- }
- o_indent = indent ;
- }
-
- //putc(ch,stream);
-
- if (isprint(ch) || ch =='\n' || ch=='\r' ) {
- putc(ch, stream);
- }else {
- fputc(' ', stream);
- }
-
-
- }
- return 0;
- }
- void usage();
复制代码
tnscmd.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "tnscmd.h"
- #define BSIZE 10240
- /*Oracle 8.1.7 head */
- char head_pack[] = { 0, 0 , 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\
- 0x01, 0x36, 0x01, 0x2c, 0x00, 0x00, 0x08, 0x00,\
- 0x7f, 0xff, 0x7f, 0x08, 0x00, 0x00, 0x00, 0x01,\
- 0, 0 , 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,\
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
- 0x00, 0x00, 0x00, 0x00, 0x34, 0xe6, 0x00, 0x00,\
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
- 0x00, 0x00 };
- /*Oracle 10.0.1 head */
- char head_pack1[] ={ 0, 0 ,0x00,0x00,0x01,0x00,0x00, 0x00,
- 0x01,0x39,0x01,0x2c,0x00,0x00,0x08, 0x00,
- 0x7f,0xff,0x7f,0x08,0x00,0x00,0x01, 0x00,
- 0, 0, 0x00,0x3a,0x00,0x00,0x00, 0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,
- 0x00,0x00} ;
- size_t (* write_func)(const void *ptr, size_t size, size_t nmemb, FILE *stream) = dump_char ;
- int debug_mode = 0;
- int build_packet(char *dest, char *cmd)
- {
- int cmd_len = strlen(cmd) ;
- int packetlen = sizeof(head_pack) + cmd_len;
- memcpy(dest, head_pack, sizeof(head_pack));
-
- dest[0] =(char) packetlen >> 8;
- dest[1] =(char) packetlen & 0xff;
-
- dest[24] = (char) cmd_len >>8 ;
- dest[25] = (char) cmd_len & 0xff ;
- memcpy(&dest[sizeof(head_pack)], cmd, strlen(cmd));
-
- return sizeof(head_pack) + strlen(cmd) ;
- }
- int getpacklen(unsigned char *p)
- {
- unsigned char c0,c1 ;
- c0 =p[0] ;
- c1 =p[1] ;
- return c0 *256 + c1 ;
- }
- int ora_recv(unsigned int sock, void *buf, unsigned int *packlen)
- {
- int rlen =0;
- rlen = recv(sock,buf, BSIZE , 0);
- if (rlen <=0) {
- *packlen = 0;
- return 0;
- }
- *packlen = getpacklen(buf) ;
- if (debug_mode ==1) {
- fprintf(stdout, "recv:%d packlen:%d\n",rlen , *packlen );
- hex_dump(buf, rlen, 0);
- }
-
- return rlen ;
- }
- /*
- @tns_cmd : send tns command && recv message from oracle listener
- */
- int tns_cmd(int sock,char *cmd,char *pass)
- {
- char buf[BSIZE] ;
- char command[1024];
- unsigned int packlen =0;
- ssize_t rlen ,slen;
-
- if (pass ==NULL)
- sprintf(command,"(CONNECT_DATA=(COMMAND=%s)(VERSION=169869568))",cmd);
- else
- sprintf(command,"(CONNECT_DATA=(COMMAND=%s)(PASSWORD=%s)(VERSION=169869568))",cmd,pass);
- slen = build_packet(buf, command);
- fprintf(stdout, "send command: %s\n\n", command);
- rlen =send(sock, buf, slen,0);
- fprintf(stdout, "begin recv\n");
-
- rlen = ora_recv(sock, buf, &packlen);
- char * p=buf ;
- packlen = packlen < rlen ?packlen:rlen ;
- if (buf[4] ==4 ) {
- write_func(&p[12], packlen - 12 ,1, stdout);
- write_func("\n", 1,1,stdout);
- return 0;
- }
- send(sock, "\n",1,0);
- while ((rlen = ora_recv(sock, p, &packlen)) >0) {
- /*this line for raise error some times */
- // packlen = packlen < rlen ?packlen:rlen ;
- write_func(&p[10], rlen -10 ,1, stdout);
- }
- write_func("\n", 1,1, stdout);
- return 0;
- }
- extern char *optarg;
- int main(int argc, char *argv[])
- {
- char *host = NULL;
- char *cmd = NULL;
- char *pass = NULL;
- int port = 1521 ;
- int flags, opt;
- int nsecs, tfnd;
- if (argc >1 && argv[1][0] == '-') {
- cmd = "ping";
- }else {
- cmd = argv[1] ;
- }
-
-
- nsecs = 0;
- tfnd = 0;
- flags = 0;
- while ((opt = getopt(argc, argv, "dih:p:")) != -1) {
- switch (opt) {
- case 'h':
- host = optarg ;
- break;
- case 'p':
- pass = optarg ;
- break;
- case 'i':
- write_func = dump_char_parenify ;
- break ;
- case 'd':
- debug_mode =1 ;
- break ;
- default: /* '?' */
- usage();
- exit(EXIT_FAILURE);
- }
- }
-
- if (host ==NULL) {
- usage();
- exit(EXIT_FAILURE);
- } ;
- sockstart(wsad);
- int sock = tcp_connect(host, port) ;
- printf("connect to %s:%d\n", host,port);
- if (sock<0) {
- exit(-1);
- }
- tns_cmd(sock, cmd, pass);
- closesocket(sock) ;
- sockend() ;
- exit (EXIT_SUCCESS);
- }
- void usage()
- {
- fprintf(stderr, "Usage: tnscmd [command] -h hostname\n\
- where 'command' is something like ping, version, status, etc.\n\
- (default is ping)\n\
- [-p pass] - the Oracle listener password\n\
- [-r rawcmd command] - build your own CONNECT_DATA string\n\
- [-i] indent & outdent on parens\n\
- [-d] debug mode & print hex data \n" );
- }
复制代码
all code:
阿飛
2007/11/20
[ 本帖最后由 gangjh 于 2007-11-24 08:42 编辑 ] |
|