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.

Better formatted version here


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

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).

Here's the batch script:

  1.  
  2. @echo off
  3. ipconfig /all >> %COMPUTERNAME%.txt
  4. systeminfo >> %COMPUTERNAME%.txt
  5. defrag -a c: >> %COMPUTERNAME%.txt
  6. echo Get user, type and location
  7. notepad %COMPUTERNAME%.txt
  8.  

And the PHP script:
Edit: Sorry about the horrible formatting in the blog. Wordpress crashes if I use <pre>'s around certain code, and this script happens to do that. You can find a better formatted version here.


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

and auth.php

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

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.

_GET URL extraction

February 24th, 2008

This script will grab a url FROM a url (for example, http://example.com/this_script.php?url=http://ex.com?id=5&img=34).
The extracted URL in this case would be "http://ex.com?id=5&img=34".
This script is useful in a situation where you want to track clicks and forward a user to a page immediately, or some other situation where you need to grab a URL from an argument.

  1.  
  2. // enter all arguments you expect this script to need to use, and *where* you expect to find them.
  3. $args = array(0=>'url');
  4. $arg_count = count($args);
  5. $url = htmlspecialchars($_GET['url']);
  6. $x = 0;
  7. foreach($_GET as $arg=>$val) {
  8. // if the current arg is NOT where it should be, then it's part of the anon url
  9. if ($arg != $args[$x]) {
  10. // append arg and val to the url
  11. $url .= "&".$arg."=".$val;
  12. }
  13. $x++;
  14. }
  15. // with $url available, you can now run a regex against it, use a header("location: ".$url); or whatever fits your need
  16.  

tovid ease of use script

February 4th, 2008

This script utilizes the tovid DVD conversion/burning suite to quickly convert and burn video files for your DVD player.
Usage is:
quickdvd.sh -file file(.avi|.mpg|etc) -convert [-burn] [-clean]
quickdvd.sh -file DVDdisc.xml -burn [-clean]
quickdvd.sh -clean

  1. #!/bin/bash
  2. idx=1
  3. if [ -z "$1" ]; then
  4. echo -e "\nUsage: quickdvd.sh -file file(.avi|.mpg|etc) -convert [-burn] [-clean]\n quickdvd.sh -file DVDdisc.xml -burn [-clean]\n quickdvd.sh -clean"
  5. exit 1
  6. fi
  7. #checks for arguments
  8. function check_args {
  9. i=$(expr $idx + 1);
  10. case "$1" in
  11. "-file" ) FILE=${args[$i]};;
  12. "-burn" ) BURN=1;;
  13. "-convert" ) CONVERT=1;;
  14. "-clean" ) CLEAN=1;;
  15. esac
  16. }
  17. # for lack of a better solution, assign the array args, then iterate them
  18. for arg in "$@"
  19. do
  20. args[$idx]=${arg}
  21. let "idx += 1"
  22. done
  23. idx=1
  24. for arg in "$@"
  25. do
  26. check_args ${arg}
  27. let "idx += 1"
  28. done
  29.  
  30. # check if we entered a file
  31. if [ "$FILE" = "$NULL" ] && [ "$CLEAN" != 1 ]; then
  32. echo "You need to enter a file name";
  33. else
  34. # if we want to convert data, do it
  35. if [ "$CONVERT" = 1 ]; then
  36. if [ -a dvddata.mpg ]; then
  37. echo -e "\nYou need to run ./quickdvd.sh -clean before you can convert another video!"
  38. exit 1
  39. fi
  40. # start tovid scripts
  41. idvid "$FILE"
  42. tovid -dvd -ntsc ./dvddata-tmp "$FILE"
  43. tovid -dvd -ntsc -out ./dvddata -in "$FILE"
  44. tovid -quality 8 -dvd -ntsc -out ./dvddata -in "$FILE"
  45.  
  46. makexml ./dvddata.mpg -out ./DVDdisc
  47. makedvd ./DVDdisc.xml
  48. fi
  49. # if we want to burn data, do it
  50. if [ "$BURN" = 1 ]; then
  51. makedvd -burn "DVDdisc"
  52. fi
  53. if [ "$CLEAN" = 1 ]; then
  54. rm -rf DVDdisc*
  55. rm -rf dvddata*
  56. echo -e "\nTemporary files removed."
  57. fi
  58. if [ "$BURN" = "$NULL" ] && [ "$CONVERT" = "$NULL" ] && [ "$CLEAN" = "$NULL" ]; then
  59. echo -e "\nYou need to supply either -convert, -burn or -clean to use this script."
  60. exit 1
  61. fi
  62. fi

QGallery

February 4th, 2008

QGallery (or Quick Gallery) is a small and simple random-image gallery with a rating system.
Currently, QGallery only support MySQL for storing images and data, but I plan on adding SQLite and hash table support.
Other future plans include a commenting system and multiple site layouts, as well as a prettier-looking admin section.

Here's a code snippet of the ratings class

  1.  
  2. class ratings {
  3. function get_rating($id) {
  4. global $mysqli;
  5. $sql = "SELECT ROUND(rating/rater_count, 2),rater_count FROM images WHERE ID = ".sanitize::mysqlsafe($id,1);
  6. return $mysqli->query($sql,1);
  7. }
  8. function add_rating($star,$id) {
  9. global $mysqli;
  10. $sql = "UPDATE images SET rating = rating + ".sanitize::mysqlsafe($star).", rater_count = rater_count + 1 WHERE ID = '".sanitize::mysqlsafe($id,1)."'";
  11. $mysqli->query($sql);
  12. return "Rating submitted successfully";
  13. }
  14. }
  15.  

You can find a live preview of this code at http://evildomain.org/gallery/

The source code for this gallery can be found at
http://anon:anon@imag33k.net/Qgallery/browser
or downloaded via svn at
http://anonymous@imag33k.net/svn/Qgallery