Showing posts with label convert. Show all posts
Showing posts with label convert. Show all posts

Tuesday, April 7, 2009

Duplicating And Modifying NetBackup Policies, Schedules And Client Via Command Line On Linux And Unix

Hey There,

SPOILER ALERT: THE BULLET POINTS IN THIS POST ARE IN ALL CAPS. I'M SORRY FOR SHOUTING. I HAVE NO SENSE OF HOW OBNOXIOUSLY LOUD I AM!

Actually tomorrow's post has turned into today's and I'm going to do today's tomorrow. I don't know why I felt compelled to write that. I guess I just don't want you to lose track of time like I do ;)

Today we're going to check out a way to copy (and modify) an existing host's NetBackup policies, clients and schedules to a new host, and then modify those policies, clients and schedules (just slightly) to suit the new host (you can't backup to a hostname that isn't the name of the host you want to back up. ...if you want to backup your the new host, that is ;)

The beauty of it is that it can all be done from the command line. No more UI GUI for you :)

And now, in one of my driest pieces to date, a step by step guide on how to perform the process I just described above (If you're interested in staying away from the GUI, check out our old post on our NetBackup command line activity monitor)

1. GET YOUR POLICIES AND SCHEDULES FROM THE KNOWN-GOOD HOST YOU WANT TO EMULATE/REPLICATE (orig_host will be the known-good host and new_host will be the host you want to be just about the same. Also, we're assuming you've installed the base product. This walk-through is focused only on policies, policy schedules and policy clients).

orig_host # ls /usr/openv/netbackup/db/class (you may have more than this - generally there's one directory per policy. Each directory includes the schedules for the policy the directory name indicates):

HOST_BACKUP HOST_OS_BACKUP HOST_CATALOG


You may want to copy off the old policy and schedule output, just so you can compare it with your new host setup later and make sure you didn't forget to change any instances of an old hostname to your new hostname

orig_host # /usr/openv/netbackup/bin/admincmd/bppllist -allpolicies -U >/var/tmp/policies.txt


Then just tar that all up:

orig_host # tar cpf /var/tmp/policies_and_schedules.tar /usr/openv/netbackup/db/class /var/tmp/policies.txt


2. VERIFY THAT EITHER NO "class" DIRECTORY EXISTS ON YOUR NEW HOST, THE EXISTING "class" DIRECTORY IS EMPTY OR THAT IT JUST CONTAINS THE STANDARD TEST GARBAGE YOUR SETUP MAY COME WITH - DELETE IT OR UNTAR OVER IT IF YOU WANT TO (USER DISCRETION ADVISED!) - THIS MAY NOT BE A BIG DEAL SINCE YOU PROBABLY HAVE NO SCHEDULES OR POLICIES ON YOUR NEW HOST ANYWAY.

new_host # ls /usr/openv/netbackup/db
/usr/openv/netbackup/db: No such file or directory
new_host # ls /usr/openv/netbackp/db/class
/usr/openv/netbackp/db/class: No such file or directory
new_host # ls /usr/openv/netbackp/db
/usr/openv/netbackp/db: No such file or directory


3. AFTER SCP'ING/COPYING THE TAR FILE FROM YOUR KNOWN GOOD HOST, UNTAR IT ON THE NEW HOST AND LIST ALL POLICIES TO DOUBLE VERIFY - THE HOST NAMES WILL BE WRONG (FOR YOUR NEW HOST) SO THE DIFF WON'T BE TOO DIFFERENT!

new_host # tar xpf /var/tmp/policies_and_schedules.tar
new_host # /usr/openv/netbackup/bin/admincmd/bppllist -allpolicies -U >/var/tmp/policies_new.txt
diff /var/tmp/policies.txt /var/tmp/policies_new.txt


4. CHECK THAT ALL THE POLICIES ARE THERE IN YOUR policies_new.txt FILE (YOU CAN LOOK IN BPADM, TOO). ALL HOSTNAMES AND TAPE RESIDENCE NAMES WILL STILL BE WRONG (ANYTHING THAT CONTAINS A HOSTNAME, ANYWAY)

new_host # /usr/openv/netbackup/bin/admincmd/bppllist -M new_host
HOST_BACKUP
HOST_OS_BACKUP
HOST_CATALOG


5. DETERMINE YOUR TAPE RESIDENCE (TLD NAME) ON THE NEW HOST (FIRST ENTRY IN OUTPUT BELOW)

new_host # /usr/openv/netbackup/bin/admincmd/bpstulist
new_host-hcart3-robot-tld-o 2 new_host 8 0 20 2 0 "*NULL*" 0 1 1048576 *NULL* 0 1 0 0 0 0 *NULL* new_host


"new_host-hcart3-robot-tld-o" is the residence name

6. ASSUMING ALL POLICIES LISTED ABOVE ARE GOOD, YOU WON'T HAVE TO MODIFY THIS LINE TO REMOVE AND/OR UPDATE THE RESIDENCE FOR ALL POLICIES (OF COURSE, THEY PROBABLY AREN'T SINCE THIS POST WAS WRITTEN FOR THE GENERAL PUBLIC ;)

new_host # while read line;do /usr/openv/netbackup/bin/admincmd/bpplinfo $line -modify -residence new_host-hcart3-robot-tld-o;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host`"


7. LIST OUT ALL THE SCHEDULES NOW - NOTE THAT YOU MAY NOT WANT TO MODIFY YOUR CATALOG POLICY AND THAT SOME POLICIES HAVE MORE THAN ONE CLIENT (This may vary from setup to setup, so it's important to check!)

NOTE ALSO THAT, SINCE YOU'RE NOT CHANGING YOUR SCHEDULES, ALL YOU NEED TO DO TO MODIFY THEM IS TO CHANGE THE CLIENTS ASSOCIATED WITH THEM, WHICH GETS DONE IN THE FOLLOWING STEPS, AS WELL :)

new_host # while read line;do echo "POLICY $line";/usr/openv/netbackup/bin/admincmd/bpplclients $line;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host`"
POLICY HOST_BACKUP
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris10 orig_host
POLICY HOST_OS_BACKUP
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris10 orig_host
Solaris Solaris10 orig_host2
POLICY HOST_CATALOG
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris8 orig_host


8. WITH THE SAME ASSUMPTIONS AS ABOVE, USE THIS TO CHANGE CLIENTS FOR YOUR POLICIES - CHOPPING OFF LAST POLICY AND MODIFIYING CLIENTS BY TAKING INPUT FROM LIST, MODIFYING AND THEN RUNNING "ADD NEW" AND "DELETE OLD" IN A LOOP (The simple sed expression to change the host name can be as specific as you like)

A. DO A "PROOF OF CONCEPT" RUN FIRST

while read line;do count=3;for x in $(/usr/openv/netbackup/bin/admincmd/bpplclients $line|awk '{print $3}'|grep db|/usr/bin/sed 's/orig_/new_/g'|xargs echo);do oldhwos=$(/usr/openv/netbackup/bin/admincmd/bpplclients $line|sed -n ${count}p|awk '{print $1,$2}');let count=$count+1;echo "POC TEST $line /usr/openv/netbackup/bin/admincmd/bpplclients $line -add $x $oldhwos";done;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host|egrep -iv 'vault|catalog'`"
POC TEST HOST_BACKUP /usr/openv/netbackup/bin/admincmd/bpplclients HOST_BACKUP -add new_host Solaris Solaris10
POC TEST HOST_OS_BACKUP /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -add new_host Solaris Solaris10
POC TEST HOST_OS_BACKUP /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -add new_host2 Solaris Solaris10


B. THEN - IF ALL IS WELL - DO IT FOR REAL

while read line;do count=3;for x in $(/usr/openv/netbackup/bin/admincmd/bpplclients $line|awk '{print $3}'|grep db|/usr/bin/sed 's/orig_/new_/g'|xargs echo);do oldhwos=$(/usr/openv/netbackup/bin/admincmd/bpplclients $line|sed -n ${count}p|awk '{print $1,$2}');let count=$count+1;echo "Running /usr/openv/netbackup/bin/admincmd/bpplclients $line -add $x $oldhwos";/usr/openv/netbackup/bin/admincmd/bpplclients $line -add $x $oldhwos;done;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host|egrep -iv 'vault|catalog'`"
Running /usr/openv/netbackup/bin/admincmd/bpplclients HOST_BACKUP -add new_host Solaris Solaris10
Running /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -add new_host Solaris Solaris10
Running /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -add new_host Solaris Solaris10


C. CHECK TO MAKE SURE THE NEW CLIENTS ARE ADDED

while read line;do /usr/openv/netbackup/bin/admincmd/bpplclients $line ;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host`"
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris10 orig_host
Solaris Solaris10 new_host
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris10 orig_host
Solaris Solaris10 orig_host1
Solaris Solaris10 new_host
Solaris Solaris10 new_host1
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris8 orig_host
Solaris Solaris8 new_host


D. NOW SOME POC TO MAKE SURE THE DELETE OF THE OLD HOSTS WORKS OKAY

while read line;do for x in $(/usr/openv/netbackup/bin/admincmd/bpplclients $line|awk '{print $3}'|grep orig_|xargs echo);do echo "POC TEST $line /usr/openv/netbackup/bin/admincmd/bpplclients $line -delete $x";done;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host|egrep -iv 'vault|catalog'`"
POC TEST HOST_BACKUP /usr/openv/netbackup/bin/admincmd/bpplclients HOST_BACKUP -delete orig_host
POC TEST HOST_OS_BACKUP /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -delete orig_host
POC TEST HOST_OS_BACKUP /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -delete orig_host1


E. THEN REMOVE THEM FOR REAL

while read line;do for x in $(/usr/openv/netbackup/bin/admincmd/bpplclients $line|awk '{print $3}'|grep orig_|xargs echo);do echo "Running /usr/openv/netbackup/bin/admincmd/bpplclients $line -delete $x";/usr/openv/netbackup/bin/admincmd/bpplclients $line -delete $x;done;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host|egrep -iv 'vault|catalog'`"
Running /usr/openv/netbackup/bin/admincmd/bpplclients HOST_BACKUP -delete orig_host
Running /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -delete orig_host
Running /usr/openv/netbackup/bin/admincmd/bpplclients HOST_OS_BACKUP -delete orig_host1


F. THEN CHECK AGAIN

while read line;do /usr/openv/netbackup/bin/admincmd/bpplclients $line ;done <<< "`/usr/openv/netbackup/bin/admincmd/bppllist -M new_host`"
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris10 new_host
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris10 new_host
Solaris Solaris10 new_host1
Hardware OS Client
--------------- --------------- --------------
Solaris Solaris8 orig_host


9. NOW THAT YOU'VE GOT THE POLICIES, SCHEDULES AND CLIENTS MOVED OVER, MAKE SURE THAT YOUR CATALOG JOB EXISTS (IF YOU USE ONE)

new_host # /usr/openv/netbackup/bin/admincmd/bppllist HOST_CATALOG
CLASS HOST_CATALOG *NULL* 0 650000 0 *NULL*
NAMES
INFO 35 1 0 0 *NULL* 0 0 1 1 0 1 2 0 0 0 0 0 0 1236208342 EA91EDF01DD111B2AB1900144FEAC8FE 1 0 0 0 0 0 0 0 2 0 0 0 0 0 6
KEY *NULL*
BCMD *NULL*
RCMD *NULL*
RES new_host-hcart3-robot-tld-o *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL*
POOL CATALOGPOOL NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup
FOE 0 0 0 0 0 0 0 0 0 0
SHAREGROUP *ANY*
DATACLASSIFICATION *NULL*
CLIENT new_host Solaris Solaris8 0 0 0 0 *NULL*
INCLUDE CATALOG_DRIVEN_BACKUP


10. NOW JUST DEACTIVE ANY POLICIES THAT ARE ACTIVE AND SHOULDN'T BE AND ACTIVATE ANY POLICIES THAT SHOULD BE ACTIVE BUT AREN'T!

All set!

CHEERS! ;)

, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Tuesday, July 15, 2008

Converting Binary Numbers To Decimal The Hard Way On Linux Or Unix

Hey There,

If you recall a while back, we looked at using Perl's "unpack" function to easily convert binary values to decimal and convert decimal back to binary. Those were both (some folks may consider) relatively sophisticated methods of tackling the problem. Although, once you understand how "unpack" works, the first becomes incredibly simple to use and understand. The other one may always be a little awkward.

Today we're going to look at doing binary to decimal conversion using a less "worldly" method ;) The program we have for you today (and I refer to it as a program since it's written in C) attacks the problem more naturally. And, by naturally, I mean that it should make sense to anyone at its core (assuming they understand the C programming language). The method of execution is not the most efficient, but I think it's the most "human readable." In a future post, we'll definitely convert it to Perl, shell and Awk. And, maybe before then, we'll get to the next part in our ongoing series on Perl, shell and Awk porting. We'll get there eventually. If I didn't have so many different things to write about, I could bore you to tears with that stuff (if I haven't already ;)

Hope you enjoy the program. You can build it easily, using a compiler like gcc in this fashion:

host # gcc -o bin2dec bin2dec.c

and run it just as easily:

host # $ ./bin2dec

8 Digit Binary Number?
10010010
<-- I think there's a subtle homage to Rush in there - just forget about the ending 0 ;)

Binary 10010010 equals Decimal 146!

The only catch, which the executable program will prompt you with, is that (in order to keep it simple) it's limited to 8 digit binary numbers and expects an 8 digit binary number as input. This means that binary 1 would return 128 (10000000) instead of 1 (00000001). Both symptoms can be fixed by adding extra code to pad zeros on the left hand side, but I felt, after seeing the resulting code, that including it would take away from the basic gist of this post, which is that C, Perl, shell and Awk are totally accessible to "anyone" who wants to learn them. I wanted to put something out that looked as little like a completely foreign language as possible. It is my philosophy that anyone can learn how to code and/or use the Linux or Unix Operating System(s).

Of course, if "everyone" loses their irrational "fear of computers" and does start doing this stuff well, I'll end up being a fry-guy at McDonald's in about 10 years ;)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

/********************************************
* bin2dec - Convert 8 digit binary numbers *
* to decimal numbers *
* *
* 2008 - Mike Golvach - eggi@comcast.net *
* *
********************************************/

/* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

main()
{

char binnumber[8];
int length;
int difference;
int total = 0;

printf("\n8 Digit Binary Number?\n");
scanf("%s", &binnumber);
length = strlen(binnumber);
if ( length < 8 ) {
difference = -(length - 8);
}
if ( binnumber[7] == '1' ) {
total = total + 1;
}
if ( binnumber[6] == '1' ) {
total = total + 2;
}
if ( binnumber[5] == '1' ) {
total = total + 4;
}
if ( binnumber[4] == '1' ) {
total = total + 8;
}
if ( binnumber[3] == '1' ) {
total = total + 16;
}
if ( binnumber[2] == '1' ) {
total = total + 32;
}
if ( binnumber[1] == '1' ) {
total = total + 64;
}
if ( binnumber[0] == '1' ) {
total = total + 128;
}
printf("\nBinary %s equals Decimal %d!\n", binnumber, total);
return 0;
}


, Mike

Friday, May 2, 2008

Perl Script To Do Lame Encryption With Octal Dump On Linux Or Unix

Hey There,

A post ago, we took a look at using od on Linux or Unix. Hopefully, it made the use of that cryptic command somewhat more accessible.

Today, I thought we'd take a look at using the "od" command for a less practical purpose. Much like crypt (and a much older post we did on using simple encryption and decryption using Perl's pack and unpack functions), the quick-and-dirty Perl script we're putting out today is a pretty good way to keep people who don't know what they're reading from rifling through your stuff ;)

The script is simple enough, and only takes two arguments. You can either instruct it to convert a file from ASCII to octal, like so:

host # ./octala.pl -o shell.pl

or the opposite ( octal to ASCII conversion ):

host # ./octala.pl -a shell.pl.od <--- Assuming you're just running this script and accepting the default extension we popped on the end (BTW, by default, this line of code will add an ".as" extension to your file. The original is never destroyed. But that can be easily fixed by adding a line of code if you like. ...just don't forget to back up any file you might need!)

Below is a simple demonstration of the script in action, followed by the real deal. Note that we only substitute four characters that aren't "representable" (SPC = a space, HT = a tab, LF = a line feed, CR = a carriage return -- actually the CR and LF are both replaced with a new-line).

Here's to people not knowing what you're up to ;)

Cheers,

Ex:

host # cat shell.pl
<--- This script is one of our old ones with some lines chopped off, so it probably won't run :)

#!/usr/bin/perl

if ( $port =~ /\D/) {
$port = getservbyname($port, $protocol) || die "getservbyname ${port}/$protocol\n";;
}
$inet_address = inet_aton($host) || die "inet_aton: ${host}\n";
$port_address = sockaddr_in($port, $inet_address);
$protocol_num = getprotobyname('$protocol');

while (1) {
$shell_shock=accept(NEWSOCKET, SOCKET)|| die "accept $!\n";
dup2(STDERR,2);
system("/bin/sh -i");
close($shell_shock);
}
exit;


host # ./octala -o shell.pl <--- Here we convert the file to octal, and strip out the offset field.

host # cat shell.pl.od
043 041 057 165 163 162 057 142 151 156 057 160 145 162 154 012
012 151 146 040 050 040 044 160 157 162 164 040 075 176 040 057
134 104 057 051 011 173 012 011 044 160 157 162 164 040 075 040
147 145 164 163 145 162 166 142 171 156 141 155 145 050 044 160
157 162 164 054 040 044 160 162 157 164 157 143 157 154 051 040
174 174 040 144 151 145 040 042 147 145 164 163 145 162 166 142
171 156 141 155 145 040 044 173 160 157 162 164 175 057 044 160
162 157 164 157 143 157 154 134 156 042 073 073 012 175 012 044
151 156 145 164 137 141 144 144 162 145 163 163 040 075 040 151
156 145 164 137 141 164 157 156 050 044 150 157 163 164 051 040
174 174 040 144 151 145 040 042 151 156 145 164 137 141 164 157
156 072 040 044 173 150 157 163 164 175 134 156 042 073 012 044
160 157 162 164 137 141 144 144 162 145 163 163 040 075 040 163
157 143 153 141 144 144 162 137 151 156 050 044 160 157 162 164
054 040 044 151 156 145 164 137 141 144 144 162 145 163 163 051
073 012 044 160 162 157 164 157 143 157 154 137 156 165 155 040
075 040 147 145 164 160 162 157 164 157 142 171 156 141 155 145
050 047 044 160 162 157 164 157 143 157 154 047 051 073 012 012
167 150 151 154 145 040 050 061 051 011 173 012 011 044 163 150
145 154 154 137 163 150 157 143 153 075 141 143 143 145 160 164
050 116 105 127 123 117 103 113 105 124 054 040 123 117 103 113
105 124 051 174 174 040 144 151 145 040 042 141 143 143 145 160
164 040 044 041 134 156 042 073 012 011 144 165 160 062 050 123
124 104 105 122 122 054 062 051 073 012 011 163 171 163 164 145
155 050 042 057 142 151 156 057 163 150 040 055 151 042 051 073
012 011 143 154 157 163 145 050 044 163 150 145 154 154 137 163
150 157 143 153 051 073 012 175 012 145 170 151 164 073 012

host # ./octala -a shell.pl.od
<--- and here we take that octal file and translate it back to ASCII

host # cat shell.pl.od.as
#!/usr/bin/perl

if ( $port =~ /\D/) {
$port = getservbyname($port, $protocol) || die "getservbyname ${port}/$protocol\n";;
}
$inet_address = inet_aton($host) || die "inet_aton: ${host}\n";
$port_address = sockaddr_in($port, $inet_address);
$protocol_num = getprotobyname('$protocol');

while (1) {
$shell_shock=accept(NEWSOCKET, SOCKET)|| die "accept $!\n";
dup2(STDERR,2);
system("/bin/sh -i");
close($shell_shock);
}
exit;


host # diff shell.pl shell.pl.od.as <--- Cool - They're exactly the same :)


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# octala.pl - convert files from octal to ASCII or reverse
# Usage: octala [-o|-a] input_file
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

if ( $#ARGV != 1 ) {
print "Usage: $0 [-o|-a] input_file\n";
exit(1);
}

$oct_or_asc = $ARGV[0];
$input_file = $ARGV[1];

if ( ! -f $ARGV[1] ) {
print "File $input_file can't be found! Over\n";
exit(2);
}

$tmp=$$;

%otoa = qw(000 NUL 001 SOH 002 STX 003 ETX 004 EOT 005 ENQ 006 ACK 007 BEL 010 BS 011 HT 012 LF 013 VT 014 FF 015 CR 016 SO 017 SI 020 DLE 021 DC1 022 DC2 023 DC3 024 DC4 025 NAK 026 SYN 027 ETB 030 CAN 031 EM 032 SUB 033 ESC 034 FS 035 GS 036 RS 037 US 040 SPC 041 ! 042 " 043 # 044 $ 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 054 , 055 - 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 < 075 = 076 > 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 \ 135 ] 136 ^ 137 _ 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 { 174 | 175 } 176 ~ 177 DEL);

if ( $oct_or_asc eq "-o" ) {
system("od -b $input_file >odfile.$tmp");
open(TMPODFILE, "<odfile.$tmp");
@TMPODFILE = <TMPODFILE>;
close(TMPODFILE);

open(NEWODFILE, ">$input_file.od");
foreach $odline (@TMPODFILE) {
if ( $odline =~ /^\w+$/ ) {
next;
}
$odline =~ s/^\w+ //;
print NEWODFILE $odline;
}
close(NEWODFILE);
unlink("odfile.$tmp");
} elsif ( $oct_or_asc eq "-a" ) {
open(TMPASFILE, "<$input_file");
@TMPASFILE = <TMPASFILE>;
close(TMPASFILE);
open(NEWASFILE, ">$input_file.as");
foreach $asline (@TMPASFILE) {
@asline = split(" ", $asline);
foreach $aschunk (@asline) {
$fixedaschunk = $otoa{$aschunk};
$fixedaschunk =~ s/SPC/ /;
$fixedaschunk =~ s/HT/\t/;
$fixedaschunk =~ s/LF/\n/;
$fixedaschunk =~ s/CR/\n/;
print NEWASFILE $fixedaschunk;
}
}
close(NEWASFILE);
unlink("odfile.$tmp");
} else {
print "Unrecognized option: $oct_or_asc\n";
exit(3);
}


, Mike

Wednesday, March 19, 2008

Converting Decimal Values To Binary Without Using Unpack

Howdy,

Yesterday we took a look at using Unix or Linux Perl's unpack function to convert binary numbers to decimal. Today we're going to look at doing the opposite conversion ( decimal to binary ) and we're going to do it without using unpack :)

Actually, this script would be a whole lot shorter if we were to use the unpack function, but I wanted to highlight that Perl (and most scripting languages) can be used to achieve whatever ends you need met in any number of ways. Generally, your possibilities are limited only by your imagination (and the most basic rules ;)

To achieve the results we want from today's script, we're taking the input (the decimal number) and breaking it down into an array of binary values. The array that gets produced can be fed to yesterday's script to convert binary back to decimal just to verify, if you want :)

The process of converting the decimal number to a binary one in this script, breaks down (at its most basic level) to using the Perl exponential operator (**) to create a massive array of possible binary values and then using that same exponential math to determine whether each valid binary value is a 0 or a 1, and building the array (the actual answer) from that.

I hope these scripts serve as a halfway decent example of how you can do two almost identical things in two almost completely different ways, and, perhaps, as an incentive to write each of the two scripts (yesterday's and today's) in the manner of the other (Not necessary, and not necessarily fun, but a good exercise nonetheless ;)

Best wishes,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# db - Convert decimal values to binary
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

print "Decimal Value:\t";
chomp ($decimal=<stdin>);
$x = 100;
$total = "0";
while ($x != -1) {
$y = 2 ** $x;
$total = $total + $y;
--$x;
}
$a = 100;
$b = 0;
$decbin{$a} = 2 ** $a;
while ($a != -1) {
if ($decimal > $total) {
print "Time to Upgrade, boy!\n";
exit;
}
$decbin{$a} = 2 ** $a;
if ($decimal >= $decbin{$a}) {
$decimal = $decimal - $decbin{$a};
$binarray[$b] = 1;
--$a;
$b++;
} else {
$binarray[$b] = 0;
--$a;
$b++;
}
}
while ($binarray[0] != 1) {
$tmp = shift(@binarray);
$tmp = "0";
--$x;
}
$binarray = join("", @binarray);
print "Binary Number:\t$binarray\n";



, Mike




Saturday, March 15, 2008

Converting Linux RPM's Into Solaris Pkg Files

Hey there,

As this week wraps up, I thought I'd put out the last few things I've been toying around with. Today, we've got a Perl script for you that will take an RPM (From Linux) and convert it to a Solaris datastream pkg file. Of course, we've got the opposite (just like we have the opposite of our post on creating Solaris pkg files from already installed content, which we'll post in the next few days. That might be a more useful script than this one (you might actually "need" to recreate a Linux RPM from what's on your box more often), but I thought this script was kind of cool :)

Basically, you can take any Linux RPM (I tested against RedHat AS and SUSE 9), feed it to this script, like so:

host # ./rpm2pkg PROGRAM-3.2-1.rpm

and end up with your own valid Solaris pkg file named:

PROGRAM-3.2-1.pkg

My thought was that this might be useful, since one of the commands used inside it (rpm2cpio) is already included in Solaris 9 and 10. For architecture-independent, and binary compatible, programs, there obviously exists a need to convert Linux RPM's to a cpio archive that can then be extracted to the local filesystem on a Solaris machine. In my mind, the logical next step would be to skip ahead and create a valid Solaris datastream pkg file from that cpio output. This way, the process could be completed once and then distributed easily as a single pkg installation file to all of your Solaris servers:)

The script works, as mentioned above, by using rpm2cpio to extract the Linux RPM's contents and then using the "strings" command on the actual RPM to extract all the header information that we require to seed the "pkginfo" file. The prototype file is the easiest necessary pkgmk file to create since you just have to use find and pkgproto on the extracted rpm2cpio output.

If you want to be able to tweak this more to your liking, there's a lot more information about the Solaris pkg making process in our previous posts on building Solaris pkg files quickly and, more theoretically, what you need to know to create your own Solaris pkg files.

Enjoy the script and have fun trying to get Linux binaries to run on your Solaris box (Hint: You're success rate will be much greater on Solaris 10, since they're finally buying into "open source" :)

Best wishes,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# rpm2pkg - creating Solaris pkg files from Linux rpm's
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

$rpm=$ARGV[0];
$tmp_dir="dir.$$";
$orig_dir=`pwd`;

mkdir("$tmp_dir");
chdir("$tmp_dir");
system("rpm2cpio ../$rpm|cpio -dim");
$proto_list=`find . -print|pkgproto|grep -v prototype`;
open(TMP_FILE, ">>prototype");
print TMP_FILE "i pkginfo\n";
print TMP_FILE $proto_list;
close(TMP_FILE);
@pkg_info=`strings ../$rpm`;
$count = 0;
foreach (@pkg_info) {
if ( $_ =~ /\# \@\(\#\)BegWS/ ) {
push(@rpm_info, $_);
$count++;
} elsif ( $_ =~ /\# \@\(\#\)EndWS/ ) {
last;
} elsif ( $count > 0 ) {
push(@rpm_info, $_);
}
}
$uname_s = `uname -s`;
$uname_r = `uname -r`;
$uname_p = `uname -p`;
$pkg_name = $rpm;
$pkg_name =~ s/\.rpm//;
chomp $uname_s;
chomp $uname_r;
chomp $uname_p;
chomp $rpm_info[1];
chomp $rpm_info[2];
chomp $rpm_info[5];
chomp $rpm_info[12];
open(PKGINFO, ">>pkginfo");
print PKGINFO "SUNW_PRODNAME=\"$uname_s\"\n";
print PKGINFO "SUNW_PRODVERS=\"$uname_r\"\n";
print PKGINFO "SUNW_PKGTYPE=\"usr\"\n";
print PKGINFO "PKG=\"$pkg_name\"\n";
print PKGINFO "NAME=\"$rpm_info[2]\"\n";
print PKGINFO "VERSION=\"$rpm_info[5]\"\n";
print PKGINFO "VENDOR=\"$rpm_info[1]\"\n";
print PKGINFO "ARCH=\"$uname_p\"\n";
print PKGINFO "EMAIL=\"me@xyz.com\"\n";
print PKGINFO "CATEGORY=\"application\"\n";
print PKGINFO "BASEDIR=/\n";
print PKGINFO "DESC=\"$rpm_info[12]\"\n";
print PKGINFO "PSTAMP=\"Your Name Here\"\n";
print PKGINFO "CLASSES=\"none\"\n";
close(PKGINFO);
system("pkgmk -o -b `pwd` -d /tmp");
system("pkgtrans -o -s /tmp `pwd`/${pkg_name}.pkg $pkg_name");
system("mv ${pkg_name}.pkg ../");
system("cd ../;pwd;rm -r $tmp_dir");


, Mike