Showing posts with label Hacks. Show all posts
Showing posts with label Hacks. Show all posts

Workaround: dpkg goes Segmentation Fault

So, your apt-get [dist-]upgrade stops when a post/pre-installation script goes in Segmentation Fault. The strange thing is that the same script, extracted from your favourite deb package, works if launched standalone. That's probably a debconf or dpkg bug but, frankly, I didn't even google to find if it's really a known bug: I get this problem quite often on my Debian testing (especially while upgrading libc6, tzdatam console_common), so I chose to spend my time looking for a workaround. And, finally, I found a very simple one.

That's, more or less, the error I get (note: my system is localized in italian):

(Lettura del database ... 184524 file e directory attualmente installati.)
Mi preparo a sostituire libc6 2.7-3 (con libc6 2.7-5) ...
Spacchetto il sostituto di libc6 ...
Configuro libc6 (2.7-5) ...
dpkg: errore processando libc6 (--install):
il sottoprocesso post-installation script è stato terminato dal segnale (Segmentation fault)
Sono occorsi degli errori processando:
libc6

In a nutshell, my solution is:
  • Unpack the .deb package causing the problem and grab the meta-files
  • Clear the pre/post-installation script (depending on which one causes the segmentation fault)
  • Pack a new .deb package with these fake scripts and install it
  • Run manually the scripts you modified (do this before the installation if it was a preinst or pre/post-rm)
  • Done: you can go on with your dist-upgrade
That's easy to do within a bash shell if you know the right commands. And they are:

# Make a copy of crashing package
cp /var/cache/apt/archives/crashing_pkg_x.y.z.deb ./crashing_package.deb

# Extracts package data
dpkg-deb -x crashing_package.deb ./temp_dir

# Extracts package meta-files
dpkg-deb -e crashing_package.deb ./temp_dir/DEBIAN

# Make fake post/pre installation scripts
echo "echo Fake" > ./temp_dir/DEBIAN/postinst

# Pack a new modified package
dpkg-deb -b ./temp_dir/ mod_package.deb

# Install the hacked package (should not go in segfault)
dpkg -i mod_package.deb

# Manually run postinst script
./temp_dir/DEBIAN/postinst

# Clean
rm -rf ./temp_dir
rm crashing_package.deb mod_package.deb
Dirty and functional, as usual. But pay attention to the manual execution of scripts: they may crash, or refuse to go on, or they may contain debconf commands that bash can't execute; so my advice is: take a look inside and try to manually do, step by step, what the script was supposed to do (uninstalling packages, stopping processes, restarting daemons, upgrading configurations, and so on).

I guess you're experienced enough to change them to suit your needs (and, above all, I'm in a hurry now!). So, good luck and may the GNU-force be with you =)

NVIDIA 1.0-9629 on Debian testing

Being on the testing branch of Debian is cool; you have recent software, fresh updates, and plenty of little problems to solve.

Some days (weeks?) ago, after an apt-get dist-upgrade, graphic acceleration on my laptop stopped working. I didn't play with 3D things for a long time, so I realized just some days ago that the nvidia driver was not loaded anymore.

Why? Well... Who could say? Probably something changed (gcc, kernel subversion, xorg) and nvidia driver got angry for that. So, again and again:

aer:/pozzo# sh ./NVIDIA-Linux-x86-100.14.19-pkg1.run
...

But xorg couldn't find any "nvidia" driver. Among my tries, there was:

aer:/pozzo# cp /usr/X11R6/lib/modules/drivers/* /usr/lib/xorg/modules/drivers/
aer:/pozzo#

Yeah, I know, it was rough: soft linking would have been much more efficient (and more elegant). Anyway, after this, all worked.

One day later I found out a new driver version was available (100.14.19), and this latter one didn't require any workaround. Too late...

Out from the proxy in 60 seconds

So, in your university, you can surf internet only behind a proxy, within a limited surfing area. If your situation is like the following:

  • IP-level web proxy
  • Only educational domains accessible
  • Personal Linux account without any administrative privileges
then there could be a way to go out. I'll briefly explain how I did in my university, but most probably with a few adaptations the same procedure could work in very different environments. Please note that this is not a guide for dummies: I'll just list the necessary steps, without going deep in details (e.g. how to use a hex editor or how to set up a configuration file).

Have you ever heard about Planetlab platform and its proxy service Codeen? If not, please inform yourself through Wikipedia before continuing :) Let's just say there's a free http proxy service available in some educational domains (especially universities); most of them are accessible also from limited surfing proxies, so all we have to do is to configure our system so that a Codeen proxy is used to surf. How to reach that proxy? Through your ordinary proxy, of course; but how to use two proxies in a chain? Most of web browsers don't allow to set up a proxy chain, so we must use additional softwares like proxychains.

Most probably you can access at least the package mirrors of the distro you're using; for example, I could access http://packages.ubuntu.com and some of its download mirrors from behind my proxy, so I could download the package with the same computer. Otherwise, I would just have had to download the same package through another machine and then to copy it in the behind-proxy-machine.

Once we have a .deb (or .rpm or whatever) package, we can open it with an archive manager to unpack just the files we need: the executable(s), eventual local configuration files and the required libraries (tipically to be unpacked in a ./lib subdirectory). We cannot install new shared libraries because we don't have administrative privileges, but we know other ways to use non-installed libraries. For example:
user@lab:~/proxy$ export LD_LIBRARY_PATH=./lib
user@lab:~/proxy$ export LD_PRELOAD=`pwd`/lib/libproxychains.so
user@lab:~/proxy$ ./proxychains /usr/bin/firefox
ERROR: ld.so: object '/usr/lib/libproxychains.so' from LD_PRELOAD cannot be preloaded: ignored.
ERROR: ld.so: object '/usr/lib/libproxychains.so' from LD_PRELOAD cannot be preloaded: ignored.
user@lab:~/proxy$
Unfortunately, setting LD_LIBRARY_PATH or LD_PRELOAD doesn't work, because proxychains executable overwrites the latter one. Two choices: modifying proxychains source and compiling it again (but we may need other "dev" packages to install), or modifying the proxychains executable with a hexadecimal editor. We choose the second one, and if we don't have a hex editor on our machine, we can download also another app like hexedit; it allows us to modify the only text string we care about: "/usr/lib/libproxychains.so", that we're going to change in a local path (with the same length like "././/lib/libproxychains.so" or "./tmplib/libproxychains.so".

At this point, we should have proxychains working. Let's choose from this list a Codeen proxy accessible from our usual proxy; from an italian university, a proxy ending with ".uni**.it" should be fine. On my machine, setting a 2-proxies chain doesn't work; for some reasons, the only way to make it work is to set up proxychains.conf with the "internal" proxy (the university proxy) and the browser (Firefox, of course) with the Codeen proxy. And the result is...

Google! Good job. But there's another point to consider: if you're not surfing from a Planetlab IP, as you probably aren't, HTTPS traffic is disabled. This means: no Gmail, Yahoo Mail, nor other SSL logins or transactions. Unfortunately, some forums are managed via https protocol; to reach these forums (e.g. your university forum), you have to disable the use of Codeen proxy and to change Firefox settings again. The fastest way to do this is probably to keep two separate profiles in Firefox with different settings; supposing you named the "special" profile freefox, a bash script to open a free Firefox will be like this:
#!/bin/bash
cd ~/proxy
./proxychains /usr/bin/firefox -P freefox $* &
Other solutions to have HTTPS support:
  1. Finding an external, free proxy which supports HTTPS traffic tunneling, and adding this proxy to the chain;
  2. Setting up a machine with public or dynamic IP with SSH server in http tunneling (with -X extension enabled); but if you can do this, then you don't need to read this lousy "tutorial" ;)
In a nutshell:
  1. Download proxychains and a hexadecimal editor (from their website or from your favourite distro repository);
  2. Replace the absolute library path inside the proxychains executable with a (valid) local one;
  3. Find in the list a Codeen proxy you can reach from behind your proxy;
  4. Setup proxychains to use your usual proxy, and Firefox (or another program you need) to use the Codeen proxy;
  5. You're out!
60 seconds should be enough, once you know what to do and you have a little practive.

From great powers come great responsabilities... Spread this trick and you won't find a free place in your laboratory anymore. And, of course, all this is only intended to help you reaching external websites for educational purposes only... like The Unbearable Lightness of Bit.

Have a nice (didactic) free web browsing!

Forcing video preview frame in YouTube

Many people noticed YouTube flash player is not so rich in options, and one of its the lacks is that it's not possible to choose the preview frame for an uploaded video; not a static image, neither a frame from the video itself. However, if you absolutely have the need to choose the preview frame, you should know YouTube takes as preview the frame at about the temporal half of the video. This is not an official information, but just the result of some observation: maybe for some videos the choosing "algorithm" is different.

In my expreriences (the most beautyful video I uploaded, that's nevertheless a poor one, is this), the frame at the exact half of total frames number is not the chosen preview; it seems that the algorithm is:

  1. Take the temporal length of the video;
  2. Divide by 2, and truncate to the shortest integer;
  3. Choose previous frame, or the current one if it's exactly the moment to change frame (if 1/framerate divides the length).
I made two videos to confirm this hypothesis, with labels in each frame indicating the current position:

As you can see, the choosen frame is not the exact half. 500 frames at 25 frames/second are 20 seconds, and 510 frames are 20.4 seconds. In both cases, frame number 251 (1-based) is choosen; 0.4 seconds more make no influence at all.
If you want to do more tests by yourself, you can use ImageMagick go generate the frames and MEncoder to merge them into a video. Here is the bash script I used to generate these videos.

Interlacing makes things more complicated, because there's no way to know in advance how YouTube converting engine will work; and, of course, we can not choose in advance useful video parameters (like deinterlacing method). So, try to upload an already deinterlaced video, if possible; Flash streams are progressive, and would be a good choice not to let YouTube decide how to deinterlace.

Update: by downloading again my same video, I noticed that its length has changed, though the original submission was already progressive. The conclusion is: I can't find out the algorithm YouTube uses to choose the preview, it would need more experiments and I don't have the time to do them.

But is this just a useless toy?
In my opinion, it's not just a toy, but a powerful trick. Consider, for example, this video:


The preview is absolutely arbitrary, and has *nothing* to do with the content of the video. During the first two hours after I uploaded it, 239 views were hit. Without this "special preview", the same video was viewed 2 times in a week... Tricks for cheating people apart, this technique can be used to set a decent preview to your videos; the default YouTube's algorithms produces lots of annoying previews, that just don't match well the real content of the videos. That was why I had the initial idea: in one of my videos, the chosen preview was a frame almost completely black, while the rest of the video was white.

As you probably noticed, poor seeking is another annoying fact in YouTube videos; this time, the injection of keyframes is related also to scene changes, so if you move the "preview frame" one or two or three position before, it's not the preview anymore but it's still a keyframe (I did this experiment). To do: upload a .flv video already encoded with many keyframes, to test if YouTube is going to delete some of them or not.

Now, if YouTube chose for your video an awful preview, you know how to force it to use a better one. Power to masses! But remember: from a great power, come great responsabilities... Try to imagine what spammers could do with this trick... Oouch!