/* ============================================================================ * This program 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 2, or (at your option) * any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ============================================================================ */ #include #include #include #include #include #include #include #include #include #include /* 20010123/FLIX alexandre@neutrinos.org To compile the source: just do: gcc -Wall -O2 archivelog_magic.c -o archivelog_magic To use it: 1. archivelog_magic /path/to/my/archivelog 2. cat /path/to/my/archivelog | archivelog_magic What does it do: for earch file, it search for the magic cookie of oracle (AFAIK bits 12-15) then output: the filename, the blocksize, the number of block the total size of the file the dbname of the archive the thread that created the file the SCN (start & stop) the number of commit in the archivelog (SCN stop - start) (-1 if the redo log is still in use stop=0xffffffffffff) eg. : archivelog/filename: redo01.log ,blocksize: 512 ,nbblock: 1001 ,size: 512512 ,dbname: ORAX ,thread_num: 0001 ,seq_num: 0000001907 ,scn_start: 0x000000044fa5 ,scn_stop: 0xffffffffffff ,#request: -1 ,OK! ps: if the file being parsed is not a archivelog, but still an Oracle file the output will be filename: /usr/local/oracle/data/oradata/orax/control01.ctl ,blocksize: 2048 ,nbblock: 2107 ,size: 4315136 , OK! archivelog has been supressed from the start Why use it: if you got an archivelog (eg. file1.arc) but can't remeber who make it. if you want to graph the number of commit per archivelog if you want to crontol the file size (after multiple transfert) if you are using raw device and would like to know how many space in the raw device is use (in the case of size differ the last arg will be BAD instead of OK!) */ /* functions */ int main(int argc, char **argv); int get_size(int fd, char *filename); /* variables */ typedef struct { char undef1[4]; /* 0-3 */ uint blocksize; /* 4-7 size of one block in octect */ uint nbblock; /* 8-11 number of block */ uint magic; /* 12-15 magic code AFAIL */ char undef2[480]; char undef3[44]; char dbname[8]; /* "XXXXXXXX" */ char undef4[56]; char thread_text[7]; /* "Thread " */ char thread_num[4]; /* "9999" */ char pad1[2]; /* ", " */ char seq_text[5]; /* "seq # " */ char seq_num[10]; /* "9999999999" */ char pad2[2]; /* ", " */ char scn_text[4]; /* "SCN " */ char scn_start[14]; /* "0xffffffffffff" */ char scn_pad[1]; /* "-" */ char scn_stop[14]; /* "0xffffffffffff" */ char end_pad[356]; } ARC_STRUCT; /** **/ int main(int argc, char **argv) { int fd; if (argc==1) { fd=STDIN_FILENO; get_size(fd,"(stdin)"); } else { while (--argc > 0) if ( (fd=open(*++argv,O_RDONLY)) == -1) { perror(argv[0]); continue; } else { get_size(fd, *argv); close(fd); } } exit(0); } int get_size(int fd, char *filename) { long scn_b; long scn_e; struct stat fsb; ARC_STRUCT arc, *p_arc; p_arc=&arc; if ( (read(fd,&arc,1024)) != 1024) { perror("get_size"); return(0); } if (p_arc->magic != 1515936861) { return(0); } if ( strncmp(p_arc->thread_text,"Thread",6) ==0) { printf("archivelog/"); } printf("filename: %s ,", filename); printf("blocksize: %d ,", p_arc->blocksize); printf("nbblock: %d ,", (p_arc->nbblock)+1); printf("size: %d ,", (p_arc->blocksize * ((p_arc->nbblock)+1))); if ( strncmp(p_arc->thread_text,"Thread",6) ==0) { printf("dbname: %.*s ,", (int)sizeof(p_arc->dbname), p_arc->dbname); printf("thread_num: %.*s ,", (int)sizeof(p_arc->thread_num), p_arc->thread_num ); printf("seq_num: %.*s ,", (int)sizeof(p_arc->seq_num), p_arc->seq_num); printf("scn_start: %.*s ,", (int)sizeof(p_arc->scn_start),p_arc->scn_start); printf("scn_stop: %.*s ,", (int)sizeof(p_arc->scn_stop),p_arc->scn_stop); scn_b = strtol(p_arc->scn_start,NULL,16); scn_e = strtol(p_arc->scn_stop, NULL,16); if ( strncmp(p_arc->scn_stop, "0xffffffffffff", 14) != 0) { printf("#request: %ld ,", scn_e-scn_b); } else { printf("#request: -1 ,"); } } else { printf(" "); } if (fd != STDIN_FILENO) { if ( (fstat(fd,&fsb)) == -1) { perror("fstat"); printf("\n"); } else { if (fsb.st_size != (p_arc->blocksize * ((p_arc->nbblock)+1)) ) { printf("BAD\n"); } else { printf("OK!\n"); } } } else { printf("\n"); } return 1; }