Olympic college class CMPTR145 code

June 11th, 2009

After considering for a while and, finally, being inspired by this article, I opted to post my code solutions and unit analyses for my CMPTR145 (Introduction to C Programming) class at Olympic college.
We did 5 labs in this class. The first being a simple application to return the square of a number. The second, an application to view the size of different data types. And the last three being successive iterations of a GPA calculator.

These applications are by no means perfect. Indeed, I know of many ways that I can clean them up and make them more efficient. However, I feel that by posting them here, someone may benefit from them if they are trying to learn C. There are many basic, and a few semi-advanced topics covered by these code samples. Hopefully someone finds them useful!

Check them out here: http://evildomain.org/code/C/CMPTR145/

Benchmark file write-times

May 30th, 2009

I found myself needing to test the average write-times over different network services.
Originally, I was simply going to watch network traffic and see how fast random data could transfer over the networks. Unfortunately, this did not work out exactly how I wanted, however, so I decided to write up a script to record the average write-times of dd over a few network shares.

This script will zero out a file at a specified path, and then write random data to it (restricted by the count supplied to dd).
It will then return the start and end times, average write time, and total time taken to accomplish its task.

Here’s the script, followed by a couple screenshots.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
* Usage:
* php bench.php /path/to/dump/file/
*
* Adjust the settings below to fit your needs
*
* ProTip:
* Run in combination with `bwm-ng` and network mount points to
* benchmark different network setups/services
*/
 
/* begin settings */
 
$iterations = 50;        // run the commands this many times
$count=10000;            // count variable to supply dd with
$filename="benchmark";   // name of the file to write to
 
/* end settings */
 
$cmd_0="dd if=/dev/zero of=".$argv[1].$filename." count=".$count." > /dev/null 2>&1";
$cmd_1="dd if=/dev/urandom of=".$argv[1].$filename." count=".$count." > /dev/null 2>&1";
 
$time_s=array();
$time_e=array();
$time_a=0;
 
/* run the dd commands and save timestamps */
$i = 0;
while($i< $iterations) {
   $time_s[] = time(); // save start time
   system($cmd_0);
   system($cmd_1);
   $time_e[] = time(); // save end time
   $i++;
}
 
/* calculate times */
for ($i=0;$i<$iterations;$i++) { // accumulate times taken for each run
   $time_a += $time_e[$i] - $time_s[$i];
}
 
$average_time_taken = $time_a/$iterations; // average the full amount of time taken to run $iterations of the test
$total_time_taken = $time_e[$iterations-1] - $time_s[0];
 
$rpt_header = "\nReport for ".$argv[1].$filename."\n\n| Test start time | Test end time | Average time taken | Total time taken |\n";
$rpt_body = "| %-15s | %-13s | %10.2fs        | %9.2fs       |\n| %-15s | %-14s|\n\n";
 
printf($rpt_header.$rpt_body,
      date("d, M Y",$time_s[0]),
      date("d, M Y",$time_e[$iterations-1]),
      $average_time_taken,
      $total_time_taken,
      date("H:i:s",$time_s[0]),
      date("H:i:s",$time_e[$iterations-1]));


^– While the benchmark is running


^– Finished benchmark

The server is finally colo’d

May 22nd, 2009

I’ve finally gotten my supermicro 6015C-MTB server colo’d. This website will move over to it within the next few days.
For now, enjoy a nice photo (very bottom server):

Contact me (aaron holmes @t devlogicllc d0t com) if you are interested in hosting with me. Fully customizable VMs are available.

Active Directory mail accounts to Google Apps E-mail

September 3rd, 2008

I’m currently in the middle of a project at work, and put together a tool to get all users in active directory, and put them in csv format to upload to google apps. Aside from microsofts unweidly formatting of exported data, this script was farily easy to setup, and should come in handy for anyone in a similar situation.
Keep in mind, I only had about 100 accounts with which to test this, so there may still be situations in which this script will fail.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// run this on your domain controller
// ldifde -f export.ldf -s SERVER -r "(objectclass=user)" -l "dn, cn, samAccountName"
// run this on export.ldf:
// grep -o -P "(dn:.*|cn:.*|sAMAccountName:.*)" export.ldf > temp
// run this script as follows:
// php format_AD.php > format.csv
 
$file = "temp";
$handle = fopen ($file,"r");
$x = 0;
// while we haven't reached EOF
while(!feof($handle)) {
        $i = 0;
        // get each line and store as an array of three data segments
        while($i < 3) {
                $arr[$x][$i] = stream_get_line($handle,4096,"\n");
                $i++;
        }
        $x++;
}
// for each chunk of data
foreach($arr as $index=>$user) {
        // separate the "dn:" line
        $dn = explode(",",$user[0]);
        // pull out the name
        preg_match("/dn: CN=(.+)/",$dn[0],$names[]);
        // pull out the "cn:" name
        preg_match("/cn: (.+)/",$arr[$index][1],$cns[]);
        // pull out the "sAMAccountName:" name
        preg_match("/sAMAccountName: (.+)/",$arr[$index][2],$sams[]);
}
// for each match, pull out the name only, and store in another array
$i = 0;
foreach($names as $name) {
        // explode first and last name
        $exploded_names[$i] = explode(" ",$name[1]);
        // remove extraneous user names (like "sponsorship")
        if (count($exploded_names[$i]) == 1) {
                unset($exploded_names[$i]);
                unset($names[$i]);
                unset($sams[$i]);
                unset($cns[$i]);
        }
        // replace the middle name of some users with their last name, unset their last name
        if (count($exploded_names[$i]) == 3) {
                $exploded_names[$i][1] = $exploded_names[$i][2];
                unset($exploded_names[$i][2]);
        }
        $i++;
}
echo "username,first name,last name,password\n";
foreach($names as $index=>$name) {
        echo trim($sams[$index][1]).",".trim($exploded_names[$index][0]).",".trim($exploded_names[$index][1]).",".genPass()."\n";
}
function genPass ($length = 8) {
        // start with a blank password
        $password = "";
        // define possible characters
        $possible = "0123456789bcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        // set up a counter
        $i = 0;
        // add random characters to $password until $length is reached
        while ($i < $length) {
                // pick a random character from the possible ones
                $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
                // we don't want this character if it's already in the password
                if (!strstr($password, $char)) {
                        $password .= $char;
                        $i++;
                }
        }
        return $password;
}

FreeBSD base and kernel “automatic” update scripts

July 8th, 2008

I wrote these two scripts to make updating FreeBSD “easier” (as if it wasn’t already easy enough). They also allow for (if you are insane) automatic updates via crontab.
Essentially, you use these scripts in the following order:
./update-kernel.sh
nano pops up with the kernel config file. Edit it accordingly. (substitute nano with your prefered editor)
./update-world.sh

Both files can be used separetly or in different orders by changing the values of the variables specified, or by supplying them at the command line (ie `KERNEL_NAME=BLAH ./build-kernel.sh` to only build the kernel)
update-world.sh will, by default, also compile and install a new kernel. You can override this by setting BUILD_KERNEL=0 before the script name.

Note, these scripts require the directory /root/kernels to exist, and will create it if it isn’t there already. As well, these scripts assume they are being run out of /root/, and need to be edited accordingly if they are not.

Note note, there are some situations where one of these scripts may bug out on you, but none of it is fatal. Just be sure things worked right before rebooting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/local/bin/bash
# this is update-kernel.sh
 
if [ -z $KERNEL_NAME ]; then
        HOST_NAME=`/usr/bin/uname -n`
        KERNEL_NAME=$HOST_NAME`/bin/date "+_%m-%d-%y"`
fi
if [ -z $COMPILE_KERNEL ]; then
        COMPILE_KERNEL=
fi
 
# this probably does not need to be changed, but you can if you want
if [ -z $EDIT_KERNEL ]; then
        EDIT_KERNEL=1
fi
 
if [ "$EDIT_KERNEL" = "1" ]; then
        if [ -z $KERNEL_NAME ]; then
                echo You need to set a kernel name before running this
                exit 1
        fi
        if [ -a /root/kernels/$KERNEL_NAME ]; then
                echo This kernel file already exists!
                exit 1
        fi
        if [ ! -d "/root/kernel" ]; then
                mkdir /root/kernel
        fi
 
        # copy things around and make the required symlinks
        cd /usr/src/sys/i386/conf/
        cp GENERIC /root/kernels/$KERNEL_NAME
        ln -fs /root/kernels/$KERNEL_NAME /usr/src/sys/i386/conf/$KERNEL_NAME
        nano -w $KERNEL_NAME
fi
 
if [ "$COMPILE_KERNEL" = "1" ]; then
        echo Ready? Kernel will compile in 5 seconds
        for i in `jot 5`; do echo -n .; sleep 1; done
 
        cd /usr/src
        make buildkernel KERNCONF=$KERNEL_NAME
        make installkernel KERNCONF=$KERNEL_NAME
 
        echo That\'s it! Now, reboot the system and hope nothing broke.
fi
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/local/bin/bash
# this is update-world.sh
if [ -z $BUILD_KERNEL ]; then
        BUILD_KERNEL=1
fi
if [ "$BUILD_KERNEL" = "1" ]; then
        if [ -z $KERNEL_NAME ]; then
        HOST_NAME=`/usr/bin/uname -n`
        KERNEL_NAME=$HOST_NAME`/bin/date "+_%m-%d-%y"`
        fi
        echo Using kernel $KERNEL_NAME
        if [ -z $KERNEL_NAME ]; then
                echo You need to set a kernel name before running this
                exit 1
        fi
        if [ ! -d "/root/kernel" ]; then
                mkdir /root/kernel
        fi
        if [ ! -e /root/kernels/$KERNEL_NAME ]; then
                echo This kernel file does not exist. Perhaps you should run /root/update-kernel.sh
                exit 1
        fi
fi
echo Compiling in 5 seconds
 for i in `jot 5`; do echo -n .; sleep 1; done
 
cd /usr/src
make buildworld KERNCONF=$KERNEL_NAME
if [ "$BUILD_KERNEL" = "1" ]; then
        EDIT_KERNEL=0 COMPILE_KERNEL=1 /root/update-kernel.sh
fi
make installworld
echo That\'s it! Now, reboot the system and hope nothing broke.
echo You may want to run `mergemaster` or `mergemaster -p` when it comes back up
exit 0

Parse Windows PC information for inventory keeping in Retrowiki

June 21st, 2008

Recently I was tasked with taking inventory of every machine at work. Because most of our computers run Windows XP, and I did not feel like doing everything manually, I threw together a batch script to gather the information I needed, and a PHP script that can be run from command line to parse the outputted files, and format them in a way Retrowiki likes (for tables).
This script makes use of the magical jellybean keyfinder with an empty keyfinder.cfg

Here’s the batch script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@echo off
echo Whose computer is this?
set /p Owner=
echo Where is this machine located? (Sponsorship, Communication, etc)
set /p Location=
echo What type of machine is this? (Laptop, Desktop, etc)
set /p Type=
 
echo %Owner% > Done/%COMPUTERNAME%.txt
echo %Type% >> Done/%COMPUTERNAME%.txt
echo %Location% >> Done/%COMPUTERNAME%.txt
ipconfig /all >> Done/%COMPUTERNAME%.txt
systeminfo >> Done/%COMPUTERNAME%.txt
defrag -a c: >> Done/%COMPUTERNAME%.txt
keyfinder.exe /savecsv /close
type %COMPUTERNAME%.csv >> Done/%COMPUTERNAME%.txt
del %COMPUTERNAME%.csv
echo All done. If any errors happened, well, you're on your own!
pause

And the PHP script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
        error_reporting(0);
		file_put_contents("output.txt","");
        // These are what we are looking for. first we list the index of the info we want, than the pattern
        $patterns = array(
                        'brand'         => array('2'=>'/(System Manufacturer:)\s+(.+)/'),
                        'model'         => array('2'=>'/(System Model:)\s+(.+)/'),
                        'mac'           => array('3'=>'/\s+(Physical Address)(\.\s)+:\s(.+)/'),
                        'OS'            => array('2'=>'/(OS Name:)\s+(.+)/'),
                        'OSVer'         => array('2'=>'/(\nOS Version:)\s+(.+)/'),
		  'Serial'		=> array('1'=>'/Microsoft Windows XP,Professional,(([A-Z0-9]{5}-?){5})/'),
                        'RAM'           => array('2'=>'/(Total Physical Memory:)\s+(.+)/'),
                        'HDD'           => array('1'=>'/\s+(([0-9]{1,3}\.[0-9]{1,3}\s|[0-9]{1,3}\s)(GB|MB))\sTotal.+/'),
                        'processor'     => array('1'=>'/\s+.+\~([0-9]+\sMhz)/')
                );
        // the results of our regexs are stored here
        $data = array();
 
		// the output
		$output = "";
 
        // get all files to open
        $files = glob("inv/*");
// int/* was coloring everything, so i put this here to get rid of it! */
        // for each file, store its contents
        foreach($files as $file) {
                $content[$file] = file_get_contents($file);
        }
        // for each content stored (each file), store its name and lines and key=>val pairs
        foreach($content as $name=>$lines) {
                // clean the name
                $name = trim(str_replace(array("inv/",".txt"),"",$name."\n"));
                // for each of our patterns, store the category (ram, os, etc) and info (index and regex pattern) as a key=>val pair
                foreach($patterns as $category=>$info) {
                        // for each of our index, regex arrays, store the index and pattern as key=>val pairs
                        foreach($info as $index=>$pattern) {
                                // check all of our content for the given pattern
                                preg_match_all($pattern,$lines,$matches);
                                // if we have a match, store as data > computer name > category => the index of the match we're looking for
                                if ($matches) { $data[$name][$category] = $matches[$index]; }
                        }
                }
                // put the file into an array instead of just a lump of lines
                $lines_arr = explode("\n",$lines);
                // the user name is the first line
                $data[$name]['user'][] = $lines_arr[0];
                // location is the second
                $data[$name]['location'][] = $lines_arr[1];
                // type is the third
                $data[$name]['type'][] = $lines_arr[2];
        }
        // for each piece of data (our computers), store the name of the computer, and the data for that computer as key=>val pairs
        foreach($data as $name=>$computer) {
                // start our table with the computer name
                $output .= "| $name | ";
                // for each piece of data on a PC, store the category (hdd, ram, etc) and info (arrays that contain "how much ram" or how much hdd space, etc) as key=>val pairs
                foreach($computer as $category=>$info) {
                        // if we have more than 1 result for a given category (like 2 processors), don't echo a pipe, just a space
                        if (count($info) > 1) {
                                foreach($info as $details) {
										if ($category == "mac") {
											$details = str_replace("-",":",$details);
										}
										$output .=  trim($details)." ";
                                }
                                // echo a pipe to finish off the multi-result category
                                $output .=  "| ";
                        // if we have no results, we still need to echo a pipe to have an empty table (no harddrives magically?)
                        } else if(count($info) == 0) {
                                        $output .=  " | ";
                        // when we have 1 result for a given category...
                        } else {
                                // for each of our info arrays, extract info we need
                                foreach($info as $details) {
										if ($category == "mac") {
											$details = str_replace("-",":",$details);
										}
                                        // echo it
                                        $output .=  trim($details)." | ";
                                }
                        }
                }
                // start a new line for the next box, and cause it's prettier
                $output = trim($output)."\r\n";
				if (!file_put_contents("output.txt",$output,FILE_APPEND)) {
					echo $output;
				}
				$output = "";
        }

Dell Inspiron 1720 and Gentoo Linux (I know, I know, I’m still using Gentoo)

March 30th, 2008

So I ordered a new laptop, which got here on Friday, and have been futsing around with installing Linux on it. The only reason I chose Gentoo for this “project” was because I knew I would be having a difficult time (it’s laptop hardware, you know how that goes) and I can make Gentoo my bitch better than any of the other Linuxes out there. I almost opted for DesktopBSD, but I’m afraid most of the hardware won’t work with it. Oh well, FreeBSD will just have to remain my server OS.

So, back to the subject, the installation process wasn’t nearly as bad as I thought it would be, minus a few hicups along the way. When I started, the first thing I noticed was vistas weird partitioning system. I’m not really an expert on how partitions work, but from what I could see, and what some googling revealed, is that vista uses partitions that overlap others. I don’t know why, but cfdisk doesn’t like it; it throws an error, and quits. Fdisk, on the other hand, handles it just fine. I deleted the vista partitions, and re-ran cfdisk, and all went well. After starting the compile process, I realized this laptop (Intel Core 2 Duo T9300(2.5GHz, 800Mhz, 6M L2 Cache), 4GB DDR2, 667MHz RAM) is a screaming fast compiler. KDE took an entire hour to compile, which was unexpected, and I was completely blown away. Some other first impressions were the ease in which most of the drivers compiled and worked after the first try, namely nvidia-drivers; there were some issues with getting non-vista drivers for the video card in this laptop (256MB NVIDIA GeForce Go) in the past, which I’m happy to say is no longer true.

I did, however, have some issues with the wireless nic (Intel 4965N) and the sound card (I have a soundblaster X-Fi extreme “express card” along with the on-board hda-intel audio). The wireless nic threw me in circles for a few hours, while I tried to figure out (with a 2.6.22 kernel) how to get the iwl4965 driver to work properly. I did start with a 2.6.24 kernel, but there were no options for the IWLWIFI driver. Some hours of frustration later, after having spotty wifi with it, I decided to go back to a 2.6.24 kernel, with IWLWIFI compiled in. Don’t ask me why the options were in the kernel the second time – I have no idea. Another downside is that I can’t use wireless N with it. It just doesn’t work properly in Linux. Otherwise, the wireless nic works fine (I’m using it right now) and I’m happy with the performance.

The sound card was another hours long endeavour as I tried to figure out what driver to use – turns out, there is an HDA Intel option in the device drivers for ALSA that I didn’t catch earlier. I also had some issues with compiling it as a module, so everything is built into the kernel. Unfortunately for us Linux users, the X-Fi drivers are still in beta, and only exist for x86_64 kernels. I’m running i686, because 64bit sucks for desktops, but I’m satisfied with the onboard within Linux, and won’t die because I can’t use my express card (sad face).

All in all, the installation process of Gentoo on an Inspiron 1720 laptop was not terribly frustrating, or even hard – just a bit of googling and futsing around with options, and I have a perfectly good, working laptop.
The only things not working, that I’ve noticed, at least, are the keyboard LEDs not being on (power button included) and the wifi switch LED never turns on. The media button LEDs do, however, work. I also haven’t gotten around to configuring the touchpad, which does work, but the scrolly sides don’t.

Desktop screenshot
Laptop during setup

Update:
Ok, I had just had my last straw with Gentoo. Cyclic dependancies on “coreutils” which require lzma (which was installed, but is stupid anyway [gzip works fine and is /everywhere/]), causing me to be unable to update, AND breaking portage in the process is overly ridiculous. I won’t even deal with this bullshit anymore, and am moving to DesktopBSD. FreeBSD is already one of my favorites, so it’s about time I use it for my desk/laptop.

Protect a directory while leaving its contents open for your site with Apache and PHP

March 20th, 2008

Your first thought when reading this topic may be “Oh great, another person discovered how to do referrer checking.” but you would be wrong.
While 1 part of this hack uses the referrer header, it uses a small PHP script to handle authentication.

If none of that made sense to you, this script lets you “hide” a directory from un-authenticated users, while allowing your own site to pull in data from that directory.
So, for example, if I wanted to display an image on my site, but protect that directory from being browsed except by authenticated users, this script will accomplish that.

I tried for a good 2 hours to implement the whole thing in mod_rewrite fashion, but was unable to find a way to set HTTP_USER without using mod_auth, and was unable to do it. If someone else knows how, by all means, post a solution.

So, here’s what I put together to accomplish this.

.htaccess

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
RewriteEngine On
IndexIgnore auth.php htpasswd.php
<filesmatch ^\..*>
        Order Deny,Allow
        Deny from All
</filesmatch>
 
# ok, i didn't used any env vars here, not sure i can.. so..
 
# change "refer" to whatever directory you're protecting (like /images) and leave "auth\.php" alone
RewriteCond %{REQUEST_URI} !^/refer/auth\.php [NC]
 
# change http://evildomain\.org to your domain \.tld (com, org, net, whatever)
# Make sure the . is escaped!
RewriteCond %{HTTP_REFERER} !^http://evildomain\.org [NC]
 
# change the word "key" to some random string. like 35gsF4g90
# remember that key when we edit auth.php
RewriteCond %{HTTP_COOKIE} !(authed=key) [NC]
 
# change http://evildomain/org/refer to yourdomain.tld/path
#leave /auth.php in place
RewriteRule ^.*$ http://evildomain.org/refer/auth.php [L,R]

and auth.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// you can change .secrit something else. it is your htpasswd file, so make sure it starts with a .
$htpasswd = ".secrit";
 
// change $dir to whatever dir you're protecting (like "images")
$dir = "refer";
 
// change $key to the key set in .htaccess
$key = "35gsF4g90";
 
require("htpasswd.php");
$htpw = new htpasswd($htpasswd);
 
function restricted() {
        header('HTTP/1.0 401 Unauthorized');
        echo 'Restricted.';
        die();
}
if (!isset($_SERVER['PHP_AUTH_USER'])) {
        header('WWW-Authenticate: Basic realm="Restricted"');
        restricted();
} else {
  if ($htpw->validate($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'])) {
        setcookie("authed", $key, time()+3600);
        header("Location: /".$dir);
  } else {
        header('WWW-Authenticate: Basic realm="Restricted"');
        restricted();
  }
}

htpasswd.php can be found here: http://www.apachelounge.com/forum/viewtopic.php?t=635
Unfortunately, I was only able to get the script to work when SHA is used as the htpasswd auth method (htpasswd -s …)

Also worth noting, I couldn’t decide with this if the $_SERVER variables used should be sanitized. I don’t see a way where them not being sanitized will cause an issue with this script, but it might be a good idea to do so regardless.

Why I am making the switch from Gentoo to Kubuntu

March 9th, 2008

Note: Please excuse the crappy formatting. <pre> causes wordpress to break, so i’m fixing that right now

Anyone who knows me personally knows that I am an advocate of Gentoo. Linux ricer? Sure, why not, I live for those minute speed advantages. I also, perhaps masochistically, prefer building every package from source, and compiling kernels built just for my machine. Portage, when I first started using Gentoo, seemed like a good package management system. I was familiar with FreeBSD’s ports system, and this was similar, so it was a smooth transition. The way Gentoo and portage functioned as a whole allowed me to keep a minimalist linux install, while providing all the tools I needed for whatever task.
Why, then, am I dumping Gentoo, and for kubuntu of all distros? In a few short words: Portage, lack of direction, outdated support, and a few other issues that are not as signifigant that I will mention below.

Portage
Ah yes, Portage. The almost essential tool to pull in dependancies, update packages, and for all around maintenance of your box. In theory. Portage is a joke in functioning properly. Without citeing specific sources, and speaking from my own personal experience, these are the most common issues I’ve had with Portage:
Ignoring package version specifications
Blocked packages that don’t make any sense for being blocked
Constant changes in the way portage functions
Installing libraries into seemingly random locations, and often not in locations where they should be
Obscure errors (”emake failed”? that’s helpful)
Unclear dependancy trees
Using USE flags I don’t have specified, or not using USE flags I do have specified
Errors that really should have been warnings that result in me wasting 15 hours of compilation time
Unfortunately, there are other issues that I can’t recall currently. So, starting from the top, often times when I specifie a version to use in /etc/portage/package.keywords, it’s completely ignored. Perhaps this isn’t the place to specify versions, in which case portage needs a file for this purpose. Regardless, even specifying emerge =catgegory/package-version has never worked properly for me, whether downgrading or upgrading a package. Anything I could find on google about this didn’t help, and a long time Gentoo using friend of mine told me “yea.. it’s just one of those things that doesn’t work right”, and the isohunt.com system administrator left me with the simple “you’re an idiot”. Whether user error or not, a clearer way to solve this issue would have been nice.
The issues with blocked packages are numerous. Portage even has a case for redundant blocking, which is almost ridiculous, as that shouldn’t happen to begin with. This may be an issue with the package maintainers, which is another issue in and of itself. Regardless, often times you will see some package blocking something else out of no where when no known conflicts exist, or, my personal favorite, blocking a newer version of itself. This issue has cost me a few hours of compilation time because more often than not, i need to uninstall everything that is being blocked, install the packages that are being blocked, and then reinstall what i uninstalled. It’s a horrible process, and something that needs to be fixed immediately in Portage.
Portage doesn’t change too often thankfully, but when it does, new, seemingly random or useless changes are introduced. Deprecated flags are the most common occurance. I understand changing names of things to perhaps be more clear in their functionality, but I do not enjoy seeing messages scroll by about deprecated flags. Guess what? They still function the same! There are other things related to this, such as Portage not being able to keep track of overlays properly, requiring me to run emerge –regen after each –sync. Why Portage can’t do this itself is beyond me, but it’s only a minor annoyance.
This one is always fun. Do you like your system to have 5 copies of every library compiled? I sure don’t, but Portage does!
I don’t really have much to say about this, as I don’t know why it does this, but there has to be a purpose behind it. Either way, I do not enjoy having a /lib/, /usr/lib, /usr/local/lib and so on, that all contain the same libraries (and no, these directories are not symlinks). In addition to this, Portage will install libraries into completely random and unexpected locations.
These obscure errors are perhaps the most annoying thing about Portage. Errors do happen, but when they do, I’d like to get some sort of a hint as to how to fix it. Instead, I see a cc line, and then *bam* error. Great, no problem, I’ll just see what I can find on google. Wait, “emake failed”? “package died unexpectedly”? This is one reason I stopped using WINDOWS! Come on Gentoo developers, I know you can do better than this.
Then there is the obscure dependancy tree. Want to see what requires what? Great, run emerge -vpt package, and it will give you an indented list. But wait, why is xchat pulling in audacious? Who knows! Try setting -audacious to that package; try setting it in make.conf to your global USE flags, all to no avail! Thankfully, this particular issue turned out to be a package maintainers error. Too bad he masked the fixed package! Aside from this, it’s not always clear what, or why certain dependancies are being pulled in, and the tree used to display them presents the packages to be installed in a different order than they will be, so it can be misleading from time to time if you’re trying to solve one of those obscure bugs.
And last, but not least: USE flags being ignored, or pulled in from no where. I tend to think this is the error of package maintainers, but it does happen quite frequently. I really don’t have to say about this issue, other than it’s a huge problem that is very frustrating, especially if you’re trying to update a package that requires another package that is hard masked, and one that you specifically don’t have a USE flag set for for that reason.

Lack of direction
I don’t have a whole lot to say on this, other than I know recently there have been some issues over the leadership of Gentoo. I’m finally feeling the repercussions of this, in that you can see it in the “quality” of the products; portage being one of them. It almost seems like the developers are fighting over what’s best and how to do things and so on and so forth. In addition to this, there was a kernel developer who was working on his own kernel to provide better desktop performance – he stopped doing this because none of the other kernel developers wanted to work with it. They were more interested in squeezing every last drop of server performance out of theirs. There is also the issue of the many different kernel packages. Choice is great, but this was almost ridiculous, because anything that wasn’t gentoo-sources, was not supported by Gentoo for various reasons. Vanilla-sources, for example, is unsupported by gentoo security, but I have to wonder why they bother putting it in portage if they won’t support it. Just my opinion.

Outdated support
This is a biggie. Gentoo has a lot of sources on documentation and guides and such, but most of them are completely outdated. This could very well be a part of that lack of direction, or lazyness on the documenters side; I don’t know. The first one a person is likely to notice is that the installation guide hardly matches the current install process. The kernel configuration steps, for example, and completely different than what is presented to the user. There is also the issue of different support threads linking all over to newer support threads. Why they can’t just update the current ones confounds me. This is a HUGE issue – does Gentoo not want new users?

Gentoo was once fun for me. It provided a brief challenge in the beginning, and I was able to make good use of the tools provided to me. Over time, however, my entire experience degraded into painful hours of wasted time and effort to get a half-functioning system. These are my most major reasons for dumping Gentoo – but why move to Kubuntu?
K/X/*/Ubuntu are all very nice desktop systems. They are easy to install and configure, have excellent support (I often used Ubuntu’s support forums to solve issues on Gentoo), and are just an all around great product. The one thing I don’t like about it, unsurprisingly, is apt. Apt really annoys me more than portage, however, not because apt doesn’t function properly, but simply because of how it functions. I do not enjoy downloading keys so I can install a binary blob of some package, and apt-cache really gets on my nerves. It is for this reason that I am going to take the masochistic route, and compile most of my packages from source. Things like KDE i’ll keep in apt because it will be much easy for me in the long run. I know initially I will be annoyed with the workings of Ubuntu, but anything is better than Gentoo at this point.

Microsoft UAA and HP

March 7th, 2008

Today I’ve had the unfortunate opportunity to deal with this horrid thing called the “Microsoft UAA HD audio bus driver”.
The first time attempting this was on my HP desktop, which first needed a bios flash to work properly. Great, no problem, except the flash didn’t work properly, and resulted in me having to purchase a new mother board (the bios was soldered onto the board, and HP wouldn’t just send me one).

Today, I’m dealing with a work issued laptop, and setting up windows on that. The laptop is a presario F750US, which comes preloaded with vista – which i wiped, of course :)
Only after the fact did I realize that the drivers for XP for this laptop are scattered all over the damn place, and I finally managed to locate a driver package. Thankfully, most of those worked, but not all of them. I’ll package them and post a link to them here incase anyone should want them at a later time.

I digress – the point of this post is to bitch about the insanely ridiculous install process of a required driver to get sound on a laptop.
So, after downloading the UAA driver for this laptop straight from HP’s website, only to have the install not run, and not provide an error, I elected to download and install a random one on their site ( i suspect they all do the same thing ).

This went better, until I get the error “This is only to be used on HP consumer PCs preinstalled with windows XP. Your pc does not meet this requirement, so the update is being aborted”. “Bullshit,” I said, and proceeded into “c:\DOCUME~1\Administrator\LOCALS~1\temp\whatever the folder was named”.
The first thing to catch my eye was the “src” folder, which includes other folders for different languages. I chose “us,” and ran the install in there, which completely bypasses the whole “OEM ONLY!!” error.

Good job HP, way to treat your customers (ok, i’m not really a customer, but i DO have to deal with your shitty products day in and day out). At least you were kind enough to fail to accomplish your goals.

One thing to note, the error above says “update,” so if you’re wondering, yes, I’m still working on getting this laptop functioning correctly, and the above package may not even be what I was looking for. But hey, now you know how to bypass erroneous errors.

Update:
I had to use the sound driver for a different laptop to get this to work. Apparently, HP does not support “downgrading” from vista to XP on this laptop. Bullshit, i say. Oh well, I got most of the hardware working, and will get the drivers up here when I sort through them all.

Update:
Here are the XP drivers I used for the F750US laptop: http://evilpuma.com/valect/f750us/, or bundled (bzip2) at http://evilpuma.com/valect/f750us/f750us.tbz.
Some of the drivers (the ConexantHDAudio 221_XP is one of them, I don’t remember the other ones) require that you open the Device Manager and right-click on the not-installed device, click properties, then the “driver” tab.
Click “update driver” then “install from a specific location”, then next.
Click “don’t search, i will choose the driver to install”, then “have disk” and browse to the appropriate directory in the F750US driver bundle and select the filename.inf file.

Not all the devices require you to do this, so if you get an error with any of the driver installs, give the above steps a shot.