RWE: Step by step instructions for building AOKP 6.0 for the T-Mobile variant of the Samsung Galaxy S4

I have noticed that the build instructions on the AOKP website are a bit outdated. They date back to JellyBean. I would like to encourage other users to build more custom roms, and I thought that it would help if I show how to build one of the roms wich compiled successfully for me (Praise God!). It is my hope that these instructions are clear and easy to follow. Hey, if I can do it, anybody can do it!

<<<<< Step 1: Setup your system. >>>>>

To be honest, this can be the most daunting part, because if you do not set this up properly, it just will not work. I use Ubuntu 14.04 on a HP Compaq 6715b laptop. I know, not a very ideal compiler, but it is what I’ve got. Here are the suggested packages, just open a terminal and paste this in:

$ sudo apt-get install bison build-essential bzip2 curl dpkg-dev flex g++-multilib git git-review gnupg gperf lib32ncurses5-dev lib32readline-gplv2-dev lib32z1-dev openjdk-7-jdk libbz2-1.0 libbz2-dev libc6-dev libghc-bzlib-dev libgl1-mesa-dev libgl1-mesa-glx:i386 libncurses5-dev libreadline6-dev libreadline6-dev:i386 libx11-dev:i386 libxml2-utils lzop maven pngcrush pngquant python-markdown schedtool squashfs-tools tofrodos x11proto-core-dev xsltproc zip zlib1g-dev zlib1g-dev:i386

This will take a while. Once it is done, do this:

$ mkdir ~/bin && curl > ~/bin/repo && chmod a+x ~/bin/repo

$ gedit ~/.bashrc

Now you should see gedit open up your .bashrc file, to which you should add this at the very end, and save it:

export PATH=~/bin:$PATH

Now you need to close your terminal and open a new one to get the PATH variables to stick. Actually, it wouldn’t hurt to reboot your system after installing all of those programs we just installed. Your computer should now be primed and ready to go.

<<<<< Step 2: Download the source. >>>>>

Here is a very short project for you that takes the computer a long time to complete. Open a terminal and start typing:

$ cd ~
$ mkdir aokp6
$ cd aokp6
$ repo init -u -b mm
$ repo sync

You can now go outside, play with the kids, phone a friend, and then go to bed. When you awake the next morning, this might be done, depending on your internet connection!

<<<<< Step 3: Adding the device, kernel, and vendor trees. >>>>>

In some cases, you can simply type the command

[CODE]$ breakfast[/CODE]

and just choose your device, but at this time, the AOKP repository did not include a current device tree for the JFLTETMO phone, so we need to download one. I chose to test out the Dirty Unicorn JFLTETMO devices trees, by going here and choosing to download the zips. Later, perhaps we can learn about adding them as dependencies, but here are the links, be sure to choose the 6.0 branches and click the download button to download the zips:

Once you have downloaded them, unzip each one and rename them:

android_device_samsung_jfltetmo – jfltetmo
android_device_samsung_jf-common – jf-common
android_device_samsung_jflte – jflte
android_device_samsung_msm8960-common – msm8960-common
android_device_samsung_qcom-common – qcom-common

Go to you aokp6/device folder and create a folder called “samsung”. Now put the above folders into it.

Then unzip the kernel_samsung_jf folder and rename it “jf”. Go to the aokp6 folder and create a folder called “kernel”, go into the kernel folder and make a new folder called “samsung”, enter that folder, and put your “jf” folder here. Don’t worry, we are almost done.

Now go to your aokp6/vendor folder. Create a new folder called “samsung”. Enter the samsung folder and copy the contents of your unzipped proprietary_vendor_samsung folder. This should be a bunch of folders like jf-gsm-common, jf-common, etc. You actually don’t need all of these folders right now, but it will not hurt to have them, and there are two folders in there that you need.

Now you should probably take a break before going on to the next step!

<<<<< Step 4: Editing the device, kernel, and vendor trees. >>>>>

Now, go to the device/samsung/jfltetmo folder and rename to and edit it as follows:

$(call inherit-product, device/samsung/jfltetmo/

# Enhanced NFC
$(call inherit-product, vendor/aokp/configs/

# Inherit some common DU stuff.
$(call inherit-product, vendor/aokp/configs/

PRODUCT_NAME=jfltetmo \
TARGET_DEVICE=jfltetmo \
BUILD_FINGERPRINT=”samsung/jfltetmo/jfltetmo:4.4.4/KTU84P/M919UVUFNK2:user/release-keys” \
PRIVATE_BUILD_DESC=”jfltetmo-user 4.4.4 KTU84P M919UVUFNK2 release-keys”

PRODUCT_NAME := aokp_jfltetmo
PRODUCT_DEVICE := jfltetmo

NOTE: the original file said “vendor/du/config/*” you must change it to “configs” or there will be an error!

Then, in the jfltetmo folder, delete the cm.dependencies file. Do the same deletion in all of the device/samsung/* directories. You don’t want to download CM dependencies, because you already have them here.

Note: Because repositories are constantly updated, I can only garuntee that this will work based on the files as they were the day of this writing. However, with all of this in place, if you follow this guide, it should work realatively the same as what happened for me.

You can actually just run the compiler right now, however, you will have several stop errors that we plan to address here before you do that. All of these edits are due to errors that cropped up when running the compiler.

The first error was relating to libhealthd. Android and AOKP source already has a built in libhealthd for the qcom motherboards, and it is a duplication of efforts (which causes an error) to have both the device tree libhealthd and the source libhealthd. So here is how we fix it. Now, go to the device/samsung/qcom-common/libhealthd folder, and make the following changes to the file:

# WJH LOCAL_PATH := $(call my-dir)

# WJH include $(CLEAR_VARS)
# WJH LOCAL_SRC_FILES := healthd_board_default.cpp
# WJH LOCAL_MODULE := libhealthd.qcom
# WJH LOCAL_C_INCLUDES := system/core/healthd bootable/recovery

Another error that will crop up if you run the compiler now, is that your multi-media video will have a problem setting the picture order, and the compiler will get confused and stop with an error. So we can fix that here before we begin. We need to edit one of the hardware files. Go to hardware/qcom/media-caf/msm8960/mm-video/vidc/venc/src, and edit the video_encoder_device.cpp file as follows (this is the last few lines of the file):

bool venc_dev::venc_set_picture_order_count_type(OMX_U32 type)
// WJH venc_poctype temp;
// WJH venc_ioctl_msg ioctl_msg = {&temp, NULL};

// WJH temp.poc_type = type;
// WJH DEBUG_PRINT_HIGH(“Setting poc type: %d”, type);
// WJH if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_PIC_ORDER_CNT_TYPE, (void *)&ioctl_msg) < 0)
// WJH {
// WJH DEBUG_PRINT_ERROR(“Request for setting poc type failed”);
// WJH return false;
// WJH }
return true;

And finaly, there is an error that will pop up and stop your compiler because of a conflict over the “ambientIsAvailable” portion of this file: packages/apps/InCallUI/src/com/android/incallui/ at line 404. So we will just go ahead and edit it here before we begin.

final boolean showNote = isProvisioned &&
// WJH DeepLinkIntegrationManager.getInstance().ambientIsAvailable(getUi().getContext()) &&
mNoteDeepLink != null;

Now that all of the hard work is done, it is time to actually build something!

<<<<< Step 5: Start your build! >>>>>

Phew! You have invested a lot of hours into this project, now it is time to actually put those files and time to use! Open up a terminal in your aokp6 folder and start typing:

aokp6$ . build/

Which will output something like this:

including vendor/aokp/
including sdk/bash_completion/adb.bash
including vendor/aokp/bash_completion/git.bash
including vendor/aokp/bash_completion/repo.bash

Now type:

aokp6$ brunch jfltetmo

Which will start the long build process, it will output this:

including vendor/aokp/
Got local manifest
Got local manifest
Checked dependency tree over :
NO_DEPS: device/*/jfltetmo

AOKP_VERSION = aokp_jfltetmo_mm_unofficial_2016-06-20_1015
TARGET_PRODUCT = aokp_jfltetmo
TARGET_ARCH_VARIANT = armv7-a-neon
HOST_ARCH = x86_64
HOST_OS = linux
HOST_OS_EXTRA = Linux-3.16.0-73-generic-x86_64-with-Ubuntu-14.04-trusty
OUT_DIR = /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out

And this:

…..edited for space…..

Import includes file: /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/import_includes
host C: libhost <= build/libs/host/CopyFile.c
build/libs/host/CopyFile.c:86:43: warning: unused parameter ‘pSrcStat’ [-Wunused-parameter]
static bool isSameFile(const struct stat* pSrcStat, const struct stat* pDstStat)
build/libs/host/CopyFile.c:86:72: warning: unused parameter ‘pDstStat’ [-Wunused-parameter]
static bool isSameFile(const struct stat* pSrcStat, const struct stat* pDstStat)
build/libs/host/CopyFile.c:104:42: warning: unused parameter ‘src’ [-Wunused-parameter]
static void printNotNewerMsg(const char* src, const char* dst, unsigned int options)
build/libs/host/CopyFile.c:531:69: warning: unused parameter ‘isCmdLine’ [-Wunused-parameter]
static int copyFileRecursive(const char* src, const char* dst, bool isCmdLine, unsigned int options)

…..edited for space….. Stuff like this will scroll by …..

Copy: /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/target/product/jfltetmo/obj/STATIC_LIBRARIES/libext4_intermediates/libipt_LOG.c
Copy: /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/target/product/jfltetmo/obj/STATIC_LIBRARIES/libext4_intermediates/libipt_MASQUERADE.c
Copy: /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/target/product/jfltetmo/obj/STATIC_LIBRARIES/libext4_intermediates/libipt_MIRROR.c
Copy: /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/target/product/jfltetmo/obj/STATIC_LIBRARIES/libext4_intermediates/libipt_NETMAP.c
target StaticLib: libip4tc (/home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/target/product/jfltetmo/obj/STATIC_LIBRARIES/libip4tc_intermediates/libip4tc.a)
target thumb C++: keystore <= system/security/keystore/keystore.cpp
target thumb C++: keystore <= system/security/keystore/keyblob_utils.cpp
target thumb C++: keystore <= system/security/keystore/operation.cpp

…..edited for space…..


Notice that there were some “warning” flags in there. Warnings are not all bad, but they can be. In this case it works out okay. Hopefully, after many hours, you should see this:

______ _____ __ __ _____
/\ _ \/\ __`\/\ \/\ \ /\ _ `\
\ \ \L\ \ \ \/\ \ \ \/’/’\ \ \L\ \
\ \ __ \ \ \ \ \ \ , < \ \ ,__/
\ \ \/\ \ \ \_\ \ \ \\`\ \ \ \/
\ \_\ \_\ \_____\ \_\ \_\\ \_\
\/_/\/_/\/_____/\/_/\/_/ \/_/

===========-Package complete-===========
zip: /home/alaskalinuxuser/Documents/projects/phones/compile/aokp6/out/target/product/jfltetmo/
md5: 46bc18249c61988e75aba813464692a3
size: 320M

Success! Praise God! Now you can put this on your phone and test it out! Hopefully everything will be working! For future use, now you can start making changes or edits, from backgrounds to kernels! Have fun and make lots of backups. Remember, sometimes it is really hard to undo a change that you make.

Hopefully we learned how to set up our system, get the source, add devices and kernels that are not in the source, make proper edits, and run the compiler. Like I said, this works on my machine, as of this writing. You may notice, that if you make this build, it will not be identical to the one that I have posted on XDA. That is because I have made a few edits, additions, and/or subtractions here and there. That is the great thing about Android and open source! It is now up to you to make it better, to make it unique, or to make it you. Good luck with those builds, and be sure to share and help the next guy or gal with thier projects too!

Linux – keep it simple.


Real World Example: Setting up a dynamic IP for remote ssh sessions – for free!

Yet another Real World Example (RWE)! I know it has been a while since I have posted one of these, but it is better late than never, right?

The situation: An undisclosed party needed a way to log into their Linux computer from anywhere. Particularly from their home computer, or their cell phone while on the go. This is pretty handy, as an admin can log in, restart/start/stop services, and check on status without driving back to the office. They also didn’t want to spend any money for services, or purchase any new equipment, it just wasn’t in their budget.

The Solution:

The first thing that we had to discuss was what kind of connection they needed. In this case it was an SSH session, which is great as far as bandwidth and setup. However, this scenario would work just as well for Xrdp, vnc, ftp, etc., it just helps that in this case it was a “simple” fix that would be quick to set up.

The second thing that we needed was a way to establish the address of the computer in question. We will refer to the computer that they wish to connect to as the server, and we will refer to the gadget that they are using to connect as their cell phone or home computer. We needed a way to tell the cell phone the ip number of their remote server. Since they do not have a staic WAN IP address assigned to their router, they do not have a hard and fast “set” WAN IP address that does not change, instead they have the dynamically assigned IP address that gets changed potentially every time they connect to the internet, or every DHCP renewal to their router, etc.

The best answer to this problem would be to pay for a static IP address and assosiated Dynamic Name Services (DNS) so that you have a hostname that you type into your home computer or cell phone which always leads to your server. Ths service actually cost money, and hense would be outside of their budget.

So how did we solve this issue? Well, enter No-IP for free ( ), which is an internet based company that has a few very handy tools to do just that. As we will see from the following, setup was really easy, and FREE. By free, they mean, FREE. Which is pretty nice these days. Now, they do have upgrade options which are not free, but the basic package is completely free.

The first thing that we had to do was register an account for them. Once registered, we added a “hostname” for them. They have many to choose from, such as “” and “”. We will not discuss their actual choice to protect the innocent, but for this example I will continue with

Second, we set up the computer with their DUC (dynamic updater client) which we downloaded from their website. It comes as a tar file, which we unzipped, and then we ran make install to put the files where they needed to be. It was really pretty simple and had a few straitforward questions in the config file, as well as instructions on how to start and stop the service, and how often it should update.

This DUC tool is what makes it all work. The DUC tool finds out what your router’s dynamic (changing) WAN IP address is at any given moment, and sends a packet to the No-IP server to tell it your present dynamic IP address. So when you connect to, it is actually asking No-IP’s server what the current WAN IP address is for your server. Pretty slick trick actually.

Once that was done, we of course needed to do the basics, such as installing the SSH server. In this case we chose to:

$ sudo apt-get install openssh-server

Which istalled OpenSSH Server. Now I don’t want to get too deep into the details of their setup, for security purposes, but I will cover the basics here. I highly recommend that you choose an arbitrary port other than 22 for your SSH connections, to help trick those who do wrong from attempting the connection. It may even be wise to pick a port that is used for something else. For the remainder of this explanation, though, I will explain what we did using the standard SSH port 22.

For security reasons, you should also not allow root logins, but rather use a special user who can then sudo or switch user to root with a password. This double door password feature will likely save your bacon if someone gets in. You should also use an obscure username, not something like admin, ssh, maintenance, or server. Finally, you should have a really complicated password, one that is as complicated as you can remember. In this case, we actually had to change their password to something a little tougher, because theirs was too short and a dictionary word, which is bad. Also be sure to properly set up your firewall, which is something we will not talk about here.

The next step on the bucket list was to configure the router. Which has several smaller steps, but which were easy to manage locally. Their server already had a static IP on the Local Area Network, but if you are setting this up for yourself, say at home, be sure to give your server a local static IP address from your home router. This is usually done based on the server’s mac address. In this case, consider it

After all that, we were down to the final step, which is to configure the router for port forwarding. Most routers have a web gui that is fairly intuitive, and you will need a guide for your router to complete this step. In this case, we assigned anything coming in on port 22 to be forwarded to the local IP address of the server computer, or Note that the :22 means to send it to port 22 of the local computer.

Now the setup was done and it was time to test it. Which I did from my cell phone. Having an Android phone running SlimLP (5.1.1) I used an app called JuiceSSH. It is a really great app that is well constructed, looks snazzy, and works flawlessly. It also allows screen rotation, and even has special keys such as tab and ctrl. So in the app, I chose to set up a new connection to, port 22, with the appropriate username and credentials. Once I clicked connect, I was greeted by some scrolling information about echanging keys, passwords, etc., and eventually the remote server’s command prompt. Success!

All told, that was a pretty simple fix for a complex problem! Not to mention it was completely free. One down side to the free option, however, is the need to renew your free hostname every 30 days. That’s a pretty easy trade off for the free service though. Also, the free package only includes 3 dynamic addresses. So if you want to do this for a large business, you are better off with a paid package.

Linux – Keep it simple.

Real World Example: Why can’t I talk to my blackbox?

You are probably getting tired of hearing about TCPdump, but I just can’t get over how handy it is.

After a recent upgrade to one of our simulator systems, we needed to re-align the projectors. This re-alignment is quite complicated, where you have multiple projectors overlayed on a curved screen which reflects off of a curved mirror to point all of the image to the focal point of the pilot who is driving in the simulated world. Fortunately for us, we have a computer program that does the heavy math for “warping” the image on the projectors to make them line up on the curved surface. To do that, however, we first have to turn on a series of LED lights to guide the projector and camera system to the edges of the screen. Here is where we ran into a problem.

The LED lights are controlled by a simple blackbox controller with the IP address of, which you can open in a browser on several hosts to reach the web gui and turn on and off the various LEDs. When we tried to connect to the web gui, our connection would time out, and we were unable to communicate with the box.

Unfortunately, I did not tee it to a log, so I don’t have the log example to paste here, but here is what we did.

First we tried to ping it:


All of the pings whent through. However, the pings had unusually high return times. Something was creating a problem. We then ran two different TCPdump instances.

#tcpdump -i eth0 |grep

There are better ways to do this, but it was the quick and dirty way to see who the black box was talking to, and who was talking to the black box. As it turns out, the Image Generation system ( was incredibly busy talking to the blackbox. What we found was that the IG system was set to talk to all of the projectors and cameras on the addresses and was constantly polling the projectors for status updates and consistently sending the projectors a time stamped request to display the image, a sort of lock to keep them in sync. Because the blackbox was above 50, it was also receiving this data, but it was useless to the blackbox. Unfortunately, the blackbox was not able to keep up with the constant amount of useless traffic, and would falter on loading the gui because it was too busy processing the other traffic.

Since we are not allowed to change the software settings, we simply changed our procedure to first stop the IG system, which was not needed for projector alignment. Problem was solved, and we were once again able to communicate with the blackbox. Just another easy real world example of using TCPdump with Linux.

Linux – keep it simple.

Real World Example: Why you can’t add a swap file to an older Android device.

Recently, while utilizing Linux on my Android phone, I ran into an interesting problem. Android uses memory differently than Linux usually does. In the Android world, programs that you open are suspended in RAM, and a portion of that RAM is kept active even when you “close” a program. This allows the programs you have previously opened to become available again very quickly.

Linux does not typically operate in this fashion, although there are options and configurations to do similar things. The problem, however, is that Debian is sharing the RAM with Android on my phone, rather than being a seperate chroot program under Android. So Debian can only utilize the RAM that Android is not hogging.

I decided that a swap file may help me while I am utilizing Debian. So I set about to create one:

phone@localhost:~$ dd if=/dev/zero of=./swapfile bs=512 count=102400
102400+0 records in
102400+0 records out
52428800 bytes (52 MB) copied, 9.79242 s, 5.4 MB/s
phone@localhost:~$ ls -lah
total 63M
drwxr-xr-x 24 phone phone 4.0K May 27 20:02 .
drwxr-xr-x 3 phone phone 4.0K Feb 12 15:32 ..
————- Edited
-rw-r–r– 1 phone phone 50M May 27 20:02 swapfile
————- Edited

phone@localhost:~$ sudo chmod 0600 swapfile
phone@localhost:~$ sudo chown root:root swapfile
phone@localhost:~$ sudo mkswap ./swapfile
mkswap: ./swapfile: warning: don’t erase bootbits sectors
on whole disk. Use -f to force.
Setting up swapspace version 1, size = 51196 KiB
no label, UUID=c083a787-70da-40e1-bd44-e2a18875cf75
phone@localhost:~$ sudo swapon ./swapfile
swapon: ./swapfile: swapon failed: Function not implemented
phone@localhost:~$ sudo mkswap -f ./swapfile
Setting up swapspace version 1, size = 51196 KiB
no label, UUID=55faa525-9190-45da-888e-01c829eca1dc
phone@localhost:~$ sudo swapon ./swapfile
swapon: ./swapfile: swapon failed: Function not implemented
phone@localhost:~$ uname -a
Linux localhost #1 PREEMPT Fri May 27 09:18:49 KST 2011 armv7l GNU/Linux

What we can see here, however, is that it didn’t work. The question was why did it not work. The answer is that the Android/Linux kernel was compiled without CONFIG_SWAP=y. WIthout this compiled into the kernel, then swap is disabled. Unfortunately, since these kernels are digitally signed, I cannot simply find a swap module for the kernel and load it. Not to mention, as far as I can tell there isn’t one. I would need a whole new digitally signed kernel with that option enabled.

As of Android 4.0, I have been told this option is enabled, but for all of these older phones and tablets, it is not an option without specific kernels or patches. Bummer.

Linux – keep it simple.

Real World Example: Fixing LSB tags and overrides on a Linux expanded Android phone.

As is often the case, I usually expand my Android phones to full Debian distributions using Sven-Ola’s Debian Kit. Since Sven does not appear to support the kit anymore, it sometimes takes quite a bit of tweaking to make it work. Recently, I put Debian on a phone with PacMan Rom which was equivalent to Android 4.4.4. One of the many problems which I ran into involved LSB tags and overrides.

Note: LSB stands for Linux Standard Base. “The Linux Standard Base (LSB) is a joint project by several Linux distributions under the organizational structure of the Linux Foundation to standardize the software system structure, including the filesystem hierarchy used in the GNU/Linux operating system.” –Wikipedia. Essentially, LSB is a movement amongst Linux to set some standards that should be common between all distributions.

The PacMan Rom creator needed to fix a few things that happen during startup. They did this by creating some scripts for insserv to utilize and make the system perform/work as it ought to. The particular problem was this: with these scripts in place, I would be alerted every time I tried to install something new that there was an error. Sometimes this error would make insserv so angry that it could not continue to do what I originally told it to do, like install something from the repositories through scripts. That is not acceptable when it causes a failure, and rather annoying when it creates all of the warnings.

The warnings look like this:

insserv: warning: script ’90userinit’ missing LSB tags and overrides
insserv: warning: script ’81setrenice’ missing LSB tags and overrides
insserv: warning: script ’81cron’ missing LSB tags and overrides
insserv: warning: script ’80check’ missing LSB tags and overrides

A cursory reading of the Debian wiki page for LSB tags told me to either add the tags or place copies of the files in the /etc/insserv/overrides/ directory. Since the original scripts make the PacMan Rom work, I really didn’t want to edit them. So I decided to fix this by putting copies of each script into the overrides directory.

# cp /etc/init.d/90userinit /etc/insserv/overrides/
# cp /etc/init.d/81setrenice /etc/insserv/overrides/
# cp /etc/init.d/81cron /etc/insserv/overrides/
# cp /etc/init.d/80check /etc/insserv/overrides/

Well, that ought to do it. Or so I thought. Physically putting them in the overrides folder does not make them overridden. As I came to learn, you need to tell insserv to look for each individual overridden file.

# insserv -o 90userinit
# insserv -o 81setrenice
# insserv -o 81cron
# insserv -o 80check

Wow, now I’m done right? Wrong! As it turns out, what I didn’t understand, and what I don’t feel was reasonably clear in the wiki page was: putting something into the override folder and telling insserv that it is overridden doesn’t actually make it null and void and cause it to ignore the files or errors. Doing all of this simply tells insserv to use the override file instead of the original. Of course, all of my overridden files were copies of the original, and had the same problems and caused the same errors. So I needed to perform a few more steps to make this work.

Ultimately, it would have been shorter to add the LSB tags to the original scripts, but I was still concerned that changing them in any way might hinder their function, so I didn’t want to touch them. However, I now had overridden copies that were available to be edited to my hearts content. So I simply stole the tags from another script.

# head -17 /etc/init.d/cron >> /etc/insserv/overrides/90userinit
# head -17 /etc/init.d/cron >> /etc/insserv/overrides/81setrenice
# head -17 /etc/init.d/cron >> /etc/insserv/overrides/81cron
# head -17 /etc/init.d/cron >> /etc/insserv/overrides/80check

I then opened each file, went to the last 17 lines, and edited the runlevels and name listed in the LSB tags. A quick check with insserv -n revealed that I no longer had any errors popping up! Finally that nuisance was gone and I could focus on the real problems.
Linux – keep it simple.

Real World Example: Converting a package with Alien

At my office we have a new printer, a Dell C3765dnf Color Multifunction printer. This was not my choice of printer, but it is what we were given, so I needed to make the most of it. Unfortunately, I didn’t find any suitable ppd drivers in Cups for it. Not only that, but a search of the internet did not lead me to any ppd files either. I tried everything I could think of, from searching for Debian packages containing Dell, to unzipping Mac OS files to look for it. Nothing. The closest thing I could find was an RPM as Dell’s token support for Linux.

Well, at least that is something. I can work with that. I’ve used alien before to convert packages from one distro to another, but it usually doesn’t work if you lack the dependencies. In this case, however, the rpm simply installs the ppd’s which cups uses, so I was pretty sure I wouldn’t have a dependency problem. So here’s what I did:

$ sudo apt-get install alien

$ alien -d Dell-C3765-Color-MFP-1.0-3.noarch.rpm
Must run as root to convert to deb format (or you may use fakeroot).

I left this in so you could see that you needed root permissions to use alien.

$ sudo alien -d Dell-C3765-Color-MFP-1.0-3.noarch.rpm
Warning: Skipping conversion of scripts in package Dell-C3765-Color-MFP: postinst postrm
Warning: Use the –scripts parameter to include the scripts.
dell-c3765-color-mfp_1.0-4_all.deb generated

$ sudo dpkg -i dell-c3765-color-mfp_1.0-4_all.deb
Selecting previously unselected package dell-c3765-color-mfp.
(Reading database … 109097 files and directories currently installed.)
Preparing to unpack dell-c3765-color-mfp_1.0-4_all.deb …
Unpacking dell-c3765-color-mfp (1.0-4) …
Setting up dell-c3765-color-mfp (1.0-4) …

After that, I loaded up cups in my browser with localhost:631, and added my new printer. The new driver showed up at the top of the Dell list! For once, something easy when working with alien.

Linux – keep it simple.

Real World Example: Another excuse to use tcpdump

This happened a while back, but I really can’t stress enough how great a program TCPdump is. A great way to show it is to include it in a real world example where I actually used it at work.

This was yet another simple problem that had to be addressed on one of the simulators at work. Once again, poor documentation left us in the dark with what was actually happening between the different hosts on a network and an environmental control unit sensor, which was supposed to relay information about the current temperature in the box to ultimately be displayed to the user on the IOS host computer.

The problem was that it would display *sometimes* and often erroneously. It would often seem to be “outdated” information, as in, that was what the temperature was a minute or two ago, especially a problem when you are trying to constantly monitor the temperature during a problem that leads to overheating. So, we dove in with TCPdump to find out how often it was updating the hosts, and who it was updating specifically. We already knew the IP address of the unit, as it has a digital display that told us so. We also knew where the information was displayed, on the IOS host, but we wanted to make sure the information didn’t stop somewhere else along the way.

#tcpdump -avvv -i eth0 src |tee ecutcpdump.txt

05:43:38.313916 IP (tos 0x0, ttl 64, id 2, offset 0, flags [none], proto TCP (6), length 40) > IOS.local.2770: Flags [.], cksum 0x6d89 (correct), ack 17, win 512, length 0
05:43:38.346370 IP (tos 0x0, ttl 64, id 3, offset 0, flags [none], proto TCP (6), length 63) > IOS.local.2770: Flags [P.], cksum 0xc0a0 (correct), seq 1:24, ack 17, win 512, length 23
….r.;.nP……………. .B…B……..
05:43:38.563462 IP (tos 0x0, ttl 64, id 4, offset 0, flags [none], proto TCP (6), length 40) > IOS.local.2770: Flags [.], cksum 0x6d71 (correct), ack 18, win 512, length 0
05:43:39.076462 IP (tos 0x0, ttl 64, id 7, offset 0, flags [none], proto TCP (6), length 40) > IOS.local.2771: Flags [.], cksum 0x9427 (correct), ack 17, win 512, length 0
05:43:39.106468 IP (tos 0x0, ttl 64, id 8, offset 0, flags [none], proto TCP (6), length 63) > IOS.local.2771: Flags [P.], cksum 0xe734 (correct), seq 1:24, ack 17, win 512, length 23

Here we see our answers. First, it appears to be communicating with the IOS.local.2771 host, which correlated with the IOS host computer where the information was displayed. This was great to know, as it did not go through several hosts to get to the displaying host for the user. Second, it appears that the unit is communicating frequently. In fact, it seems to be communicating at least 3 times per second, as you can see in this section of the log file that I collected.

Ultimately, the problem turned out to be a software issue with the program that displays the information, but it was a good first step to rule out problems of communication being too sparse or going through multiple hosts on the network to reach the destination. Just another easy real world example of using TCPdump with Linux.

Linux – keep it simple.

Real World Example: UDEV rules for cell phones

The other day, when using adb to communicate with my phone, I had a problem where my laptop would not connect to my phone.

# adb devices
List of devices attached

Odd, it should have listed the device serial number. So I checked out lsusb to see if the phone was showing up at all, which it was:

# lsusb
-other stuff-
Bus 001 Device 004: ID 22b8:41da Motorola PCS

After some research, I realized that I needed some rules for this
device, and found that one guy did something similar for his nook. I
stole what he did, but changed it for my phone.

# touch /etc/udev/rules.d/99-android.rules
To create the file.

# echo “SUBSYSTEM==usb, ATTR{idVendor}==22b8, MODE=0666, OWNER=user #
motorola” >> /etc/udev/rules.d/99-android.rules
# service udev restart

Now when I run adb devices, I can actually communicate with my phone:

# adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
04039C4E19009019 device

Just a quick and dirty real world example.

Linux – keep it simple.

Real World Example: Determining an APC battery backup IP Address with tcpdump

While not overly complicated, we ran into a problem at work the other day relating to an APC battery backup unit. The unit in question was an APC Symmetra PX. The problem was that it was connected to the network, but we didn’t know what the IP address of the unit was. Nor did we know if/what the unit was communicating to the other computers on the network. We could not change the configuration of this unit, but we needed to get into the web gui for maintenance purposes.

Thus started our short adventure. Now there are many tools to complete this task, but being a Linux enthusiast, I chose TCP dump on a Debian laptop. We plugged the laptop into the hub that the APC was on, which then whent on to a network switch and a bunch of computers, etc. The entire network is on the, so I set my laptop for, as there was no DHCP server. Oddly enough, everything was set statically when this was set up. Part of the reason that we don’t know what everything was.

I disconnected the APC ethernet from the Hub to the switch, so only my laptop and the APC were on the hub. Then I opened up a terminal and:

$ su
# tcpdump -i eth0 -tl
This removes the time stamp (-t) and buffers the lines (-l) to keep me from missing anything.

This however produced way too much traffic. So I then used:

# tcpdump -i eth0 ip and not net -tl |grep -v
This prevented me from listening to anything on the loopback and cut out everything coming from the laptop that I had.

There was only one candidate left. So, hooking everything back up, I could then watch what the APC was doing.

# tcpdump -i eth0 src -tl

And there was the answer: the APC ( was sending a packet of information every 45 seconds or so to a host called the ET-Client, which was

So, disconnecting my laptop, and double checking that all of the wiring was proper, I then went to the ET-Client host computer and viola! Using the web browser I could connect to and was greeted by the login prompt.

Fortunately we were able to figure out the password and now have a viable means to communicate with the APC unit from the host computer within the system.

Linux – keep it simple.