So I was recently scripting with the unrar tool and discovered something stupid:
unrar t file.rar
if [ $? -eq 0 ]; then
echo "Rar file is good?"
fi
However it was returning zero all the time, even when the file wasn’t a rar:
# unrar t file.rar
UNRAR 3.80 freeware Copyright (c) 1993-2008 Alexander Roshal
file.rar is not RAR archive
# echo $?
0
So it fails the test but returns zero regardless. This makes it very unhelpful for using in scripting. Fortunately enough a mate on IRC discovered that his version did.
So I first download the existing SRPM and installed it:
# yumdownloader --source unrar
# rpm -i unrar*.srpm
Then I installed that and simply modified so I downloaded the latest, created a RPM and installed.
I have submitted the updated spec file to RPMfusion.
This is a simple tutorial produced by me and my good mate enigma. It is aimed at Gentoo and uses the Broadcom drivers but this should replicate to other systems.
The first step is to get your drivers and for Broadcom, which is relatively easy as they produce them for us. So first download the driver (these drivers support BM4311-, BCM4312-, BCM4321-, and BCM4322-based cards) and was also successful in this case with BCM4328.
Check that the package ‘linux-headers’ is installed, this is really just for completeness sakes. Gentoo would not work for long without this package!
(gentoo)# emerge linux-headers
... output ...
Unpack the downloaded drivers and build for your current kernel:
(gentoo)# tar -xzf hybrid-portsrc-ARCH-VERSION.tar.gz
(gentoo)# make -C /lib/modules/`uname -r`/build M=`pwd`
... output ...
Remove any existing wireless drivers.
(gentoo)# rmmod ndiswrapper b43 ssb bcm43xx b43legacy
Add in some modules required for WPA wireless:
(gentoo)# modprobe ieee80211_crypt_tkip
Test the newly built wireless driver:
(gentoo)# insmod wl.ko
(gentoo)# iwconfig
.. output ...
(gentoo)# iwlist scanning
... output ...
If that is working we can copy in the driver to the kernel and add to the autoload:
(gentoo)# cp wl.ko /lib/modules/`uname-r`/kernel/net/wireless/
(gentoo)# rmmod wl
(gentoo)# modprobe wl
(gentoo)# echo 'wl' >>/etc/modules.autoload.d/kernel-2.6
So now we have a working driver we can go on to configure for WPA. Alter the /etc/conf.d/net (note we assume that eth0 is wireless):
# Prefer wpa_supplicant over wireless-tools
modules=( "wpa_supplicant" )
# It's important that we tell wpa_supplicant which driver we should
# be using as it's not very good at guessing yet
wpa_supplicant_eth0="-Dmadwifi"
Next set up the network in the /etc/wpa_supplicant/wpa_supplicant.conf:
# This setting is required or the connection will not work
ctrl_interface=/var/run/wpa_supplicant
# Ensure that only root can read the WPA configuration
ctrl_interface_group=0
# Let wpa_supplicant take care of scanning and AP selection
ap_scan=1
# Only WPA-PSK is used. Any valid cipher combination is accepted
network={
ssid="example"
proto=WPA RSN # RSN is needed for WPA2
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
#The higher the priority the faster it connects
priority=2
}
And that is it, you should find that your wireless is enabled on boot.
Thanks should also go to DJ Kaos for the preparation of the driver.
I was further discussing C ideas and this time we came across bit flags (also called bit fields). The idea behind them is conservation of memory, a boolean data type consumes 1 byte of memory but all that is really needed is a single bit. Therefore you can store several booleans in a single byte.
Here is a simple example, note that each has a specific value to ensure that each matches a single bit in the 8-bit variable:
enum options {
option_a = 0x01, /* 1 == 00000001 */
option_b = 0x02, /* 2 == 00000010 */
option_c = 0x04, /* 4 == 00000100 */
option_d = 0x08, /* 8 == 00001000 */
option_e = 0x10, /* 16 == 00010000 */
option_f = 0x20, /* 32 == 00100000 */
option_g = 0x40, /* 64 == 01000000 */
option_h = 0x80, /* 128 == 10000000 */
};
So basically we have 8 boolean flags (0 off/false, 1 on/true). We can use these by utilising bitwise operations. There is really only 3 operations that you will use regularly on bit flags so lets see them.
Switching individual/multiple options “on” (or setting value true):
options |= option_a;
/* Translates to:
options = options | option_a;
options = 00000000 | 00000001;
options = 00000001;
*/
options = option_a | option_c | option_h;
/* Translates to:
options = 00000001 | 00000100 | 10000000;
options = 10000101;
*/
Equally switching options “off” (or setting false) can be done as follows (note we are using the options from above, thus a, c and h are on):
options &= ~option_a;
/* Translates to:
options = options & ~option_a;
options = 10000101 & ~00000001;
options = 10000101 & 11111110;
options = 10000100;
*/
Obviously you need a basic grasp of boolean mathematics to be able to handle this but learning the basics shouldn’t be too hard. Finally the last thing to do is check to see if a flag is “on” or “off” (again using the options from before, so c and h are “on”:
if( options & option_b ) printf("B is ON\n");
/* 10000100 & 00000010 = 00000000 .. i.e. false, so no output */
if( options & option_c ) printf("C is ON\n");
/* 10000100 & 00000100 = 00000100 .. i.e. true, so "C is ON" is outputting */
As with most things in C, once you start using and abusing it should start to fall into place. I hope that this serves as a basic introduction to bit fields.
With C++ there is ways of handling optional function parameters or overloading functions to handle different amounts of parameters, obviously within C these abilities do not exist. However if we wanted to handle a variable list of parameters then C and C++ would work the same.
Let’s see how we’d do that:
#include <stdarg.h>
#include <stdio.h>
int Adding(int cnt, ...) { /* the three ... indicate a variable list */
int add, tmp, i;
va_list args; /* make a va_list */
va_start(args, cnt); /* variable list starts after 'cnt' */
for(i = 0; i < cnt; i++) {
tmp = va_arg(args, int); /* grab the next */
add = add + tmp; /* add to the sum */
}
va_end(args); /* finished using variable list */
return add;
}
int main( ) {
int a;
a = Adding(2, 1, 2);
printf("%u\n", a); /* Outputs 3 */
a = Adding(3, 1, 2, 3);
printf("%u\n", a); /* Outputs 6 */
return 0;
}
So the first argument indicates how many variables we are going to pass and the rest are summed together. The function Adding() would be identical in C++.
Sometimes when people are using Linux they will find that they come across a simple security check that confirms the authenticity of the RPM/Deb files that they are installing. Every so often the key is missing but that is easy to remedy. Here I will use an example with the YUM install of Adobe Flash:
[root@marine]# ls
adobe-release-i386-1.0-1.noarch.rpm
[root@marine]# yum localinstall adobe-release-i386-1.0-1.noarch.rpm
Loaded plugins: fastestmirror, priorities
Setting up Local Package Process
Examining adobe-release-i386-1.0-1.noarch.rpm: adobe-release-i386-1.0-1.noarch
Marking adobe-release-i386-1.0-1.noarch.rpm to be installed
Loading mirror speeds from cached hostfile
* addons: anorien.csc.warwick.ac.uk
* base: anorien.csc.warwick.ac.uk
* centosplus: anorien.csc.warwick.ac.uk
* contrib: anorien.csc.warwick.ac.uk
* extras: anorien.csc.warwick.ac.uk
* rpmforge: fr2.rpmfind.net
* updates: anorien.csc.warwick.ac.uk
588 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package adobe-release-i386.noarch 0:1.0-1 set to be updated
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
adobe-release-i386 noarch 1.0-1 /adobe-release-i386-1.0-1.noarch 1.9 k
Transaction Summary
================================================================================
Install 1 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total size: 1.9 k
Is this ok [y/N]: y
Downloading Packages:
warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID f6777c67
Public key for adobe-release-i386-1.0-1.noarch.rpm is not installed
As you can see it attempted to install but because the key was missing it refused to install. So what do we do to find that key? First we must download the key from somewhere, there is various key servers around the world, some of the most popular are (note hkp is the HTTP keyserver protocol):
- hkp://subkeys.pgp.net
- hkp://pgp.mit.edu
- hkp://keys.gnupg.net
- hkp://wwwkeys.uk.pgp.net (where UK can be replaced by any country code)
So lets search for the missing key:
[root@marine]# gpg --keyserver hkp://wwwkeys.uk.pgp.net --recv-keys f6777c67
gpg: requesting key F6777C67 from hkp server wwwkeys.uk.pgp.net
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key F6777C67: public key "Adobe Systems Incorporated (Linux RPM
Signing Key) " imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg: imported: 1
So now we have the key and see that it is indeed Adobe’s key. Now all we need to do is add into RPM:
[root@marine]# gpg --armor --export f6777c67 >tmp-gpg.key
[root@marine]# rpm --import tmp-gpg.key
Simple as that, the install will work now!
This post is a refreshed look at a previous post on the same matter.