Archive for the 'IT' Category

Page 2 of 2

Convert FLAC to MP3

These days I needed to convert some FLAC (Free Lossless Audio Codec) audio files to mp3. As usual when dealing with audio/video formats, there are lots of (useless) tools available on the internet, most of them being shareware or even voruses (windows). Fortunately, this is a strength of Linux … at least if you are used to the console. All you need is lame and the necessary codecs (use apt-cache search to find what you need).

for file in *flac ; do flac -dc "$file" | lame -h - "${file%flac}mp3" ; done

Print QStrings in GDB

If you will ever have to go through the hell of debugging Qt-applications, you might face the problem of printing the contents of QString objects. If you call print on a QString object in gdb, the output will most probably look like the following:

{static null = {<No data fields>}, static shared_null = {ref = {_q_value = 1}, 
alloc = 0, size = 0, data = 0x80e6d0a, clean = 0, simpletext = 0, righttoleft = 0, 
asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, 
static shared_empty = {ref = {_q_value = 2}, alloc = 0, size = 0, data = 0xb734deb2, 
clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, 
reserved = 0, array = {0}}, d = 0x8105138, static codecForCStrings = 0x0}

This is (in most cases) not quite what we want to know about our QString object. Fortunately, GDB can interpret certain routines, so that we can implement a function that prints QStrings. These routines are stored in GDB’s init-file ~/.gdbinit. Unfortunately, the internal data representation of a string has changed in Qt4, such that we most certainly need two versions of the desired function. I will call the functions qprint3 and qprint4, respectively.

Qt3 Version

The Qt3 version was originally posted by David Faure to the KDE maillist in 2001:

define qprint3
    set $i=0
    while $i < $arg0.d->len
	print $arg0.d->unicode[$i++].cl
    end
end

Qt4 Version

define qprint4
    printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d->size
    set $i=0
    while $i < $arg0.d->size
        set $c=$arg0.d->data[$i++]
        if $c < 32 || $c > 127
                printf "\\u0x%04x", $c
        else
                printf "%c", (char)$c
        end
    end
    printf "\"\n"
end

Further reading

The KDE source repository has some further pretty neat GDB macros.

dot.emacs

This is my .emacs file

Download it .emacs or preview:

;; ##############################################################################
;; Frank Meffert's .emacs file
;; 2010-10-02: Beautifying a bit
;; ##############################################################################
 
;; ------------------------------------------------------------------ (load path)
(add-to-list 'load-path "~/.emacs.d/")
 
;; ------------------------------------------------------------------- (ido mode)
(require 'ido)
(ido-mode 1)
 
;; --------------------------------------------------------------- (line numbers)
(require 'linum)
(global-linum-mode 1)
(setq linum-ncols 4)
(setq linum-format (concat "%" (number-to-string linum-ncols) "d"))
 
;; -------------------------------------------------------------------- (tab bar)
(require 'tabbar)
(tabbar-mode)
(setq tabbar-buffer-groups-function
	  (lambda ()
		(list "All")))
(global-set-key [M-left] 'tabbar-backward)
(global-set-key [M-right] 'tabbar-forward)
 
(defun cur-buf-name ()
  "Get the name of the current buffer"
  (interactive)
  (buffer-name (current-buffer)))
 
(setq buf-name-rpl
	  '(("*Completions*" . "Completions")
		("cv.html" . "curricvitae")
		("foo.h" . "_FOO_H_")))
 
(defun rename-cur-buf ()
  "Renames the current buffer, if replacement is available in local list"
  (interactive)
  (let ((rpl (cdr (assoc (cur-buf-name) buf-name-rpl))))
	(if rpl
		(rename-buffer rpl))))
(add-hook 'find-file-hook 'rename-cur-buf)
 
;; (defun initial-rename ()
;;   (mapcar #'(lambda (buf)
;; 			  ()
 
;; --------------------------------------------------------------------- (col 80)
;; marks characters beyond column 80. Seriously: I need a solid line!
;(require 'column-marker)
;(add-hook 'foo-mode-hook (lambda () (interactive) (column-marker-1 80)))
 
;; ------------------------------------------------------------ (backup behavior)
;; do not make any backup files, because they suck!
(setq make-backup-files nil)
 
;; ------------------------------------------------------------------- (Doxymacs)
(require 'doxymacs)
(add-hook 'c-mode-common-hook'doxymacs-mode)
 
(setq doxymacs-file-comment-template
 '("/**" > n
   " * " (doxymacs-doxygen-command-char) "file   "
   (if (buffer-file-name)
       (file-name-nondirectory (buffer-file-name))
       "") > n
   " * " (doxymacs-doxygen-command-char) "author " (user-full-name) (doxymacs-user-mail-address) > n
   " * " (doxymacs-doxygen-command-char) "date   " (format-time-string "%A, %B %e, %Y") > n
   " * " > n
   " * " (doxymacs-doxygen-command-char) "brief  " > n
   " * " > n
   " */" > n))
 
(defun my-javadoc-return () 
  "Advanced C-m for Javadoc multiline comments.
   Inserts `*' at the beggining of the new line if 
   unless return was pressed outside the comment"
  (interactive)
  (setq last (point))
  (setq is-inside
	(if (search-backward "*/" nil t)
	  ;; there are some comment endings - search forward
	  (if (search-forward "/*" last t)
		't
	    'nil)
	  ;; it's the only comment - search backward
	  (goto-char last)
	  (if (search-backward "/*" nil t)
	    't
	    'nil)))
  ;; go to last char position
  (goto-char last)
  ;; the point is inside some comment, insert `*'
  (if is-inside
    (progn 
	  (insert "\n* ")
	  (indent-for-tab-command))
    ;; else insert only new-line
    (insert "\n")))
 
(add-hook 'c-mode-common-hook (lambda () 
  (local-set-key "\r" 'my-javadoc-return)))
 
;; ----------------------------------------------------------------- (Smart-HOME)
(defun smart-beginning-of-line ()
  "Forces the cursor to jump to the first none whitespace char of the current line when pressing HOME"
  (interactive)
  (let ((oldpos (point)))
    (back-to-indentation)
    (and (= oldpos (point))
         (beginning-of-line))))
(put 'smart-beginning-of-line 'CUA 'move)
(global-set-key [home] 'smart-beginning-of-line)
 
;; --------------------------------------------------- (resize window to 80 cols)
(defun win-eighty ()
  "Sets the width of the window to 80 columns"
  (interactive)
  (set-frame-height (selected-frame) (/ (- (x-display-pixel-height) 100) (frame-char-height)))
  (set-frame-width (selected-frame) (+ 81 linum-ncols)))
(add-hook 'after-init-hook 'win-eighty)
 
(defun win-dual ()
  "Splits the screen horizontally and sets the widthd of each window to 80 cols"
  (interactive)
  (set-frame-width (selected-frame) 175)
  (split-window-horizontally (+ 85 linum-ncols)))
 
;; ------------------------------------------------------- (custom set variables)
(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(column-number-mode t)
 '(user-full-name "Frank Meffert")
 '(user-mail-address "frank.meffert@gmail.com")
 '(cua-mode t nil (cua-base))
 '(custom-buffer-indent 4)
 '(delete-selection-mode nil)
 '(display-time-24hr-format t)
 '(display-time-day-and-date 1)
 '(display-time-mode t)
 '(global-font-lock-mode t nil (font-lock))
 '(inhibit-startup-buffer-menu t)
 '(inhibit-startup-screen t)
 '(pc-select-meta-moves-sexps t)
 '(pc-select-selection-keys-only t)
 '(pc-selection-mode t nil (pc-select))
 '(scroll-bar-mode (quote right))
 '(show-paren-mode t)
 '(standard-indent 4)
 '(uniquify-buffer-name-style (quote forward) nil (uniquify)))
 
;; ----------------------------------------------------------------------- (misc)
(setq-default tab-width 4)
(setq-default indent-tabs-mode t)
(setq c-basic-offset 4)
(setq frame-title-format (concat "Emacs <" user-login-name "@" system-name ">: <%b> %+%+ <%f>"))
 
;; Highlighting of the current line
(global-hl-line-mode 1)
(set-face-background 'hl-line "#E8F2FE")
(tool-bar-mode -1)
 
(defalias 'yes-or-no-p 'y-or-n-p)
(display-time)
(set-language-environment "Latin-1")
(put 'scroll-left 'disabled nil)
 
;; ---------------------------------------------------------- (LaF of the cursor)
;; Change cursor color according to mode
(setq djcb-read-only-color       "gray")
;; valid values are t, nil, box, hollow, bar, (bar . WIDTH), hbar,
;; (hbar. HEIGHT); see the docs for set-cursor-type
(setq djcb-read-only-cursor-type 'hbar)
(setq djcb-overwrite-color       "red")
(setq djcb-overwrite-cursor-type 'box)
(setq djcb-normal-color          "black")
(setq djcb-normal-cursor-type    'box)
 
;; ------------------------------------------------------------------------------
;; Helper functions
;; ------------------------------------------------------------------------------
(defun djcb-set-cursor-according-to-mode ()
  "change cursor color and type according to some minor modes."
  (cond
    (buffer-read-only
      (set-cursor-color djcb-read-only-color)
      (setq cursor-type djcb-read-only-cursor-type))
    (overwrite-mode
      (set-cursor-color djcb-overwrite-color)
      (setq cursor-type djcb-overwrite-cursor-type))
    (t 
      (set-cursor-color djcb-normal-color)
      (setq cursor-type djcb-normal-cursor-type))))
(add-hook 'post-command-hook 'djcb-set-cursor-according-to-mode)
 
(defun mouse-stay-and-copy (click)
  "leaves cursor at current position, allows to drag a region which 
is yanked at cursor position"
  (interactive "e")
  (let ((selected nil)
	(win (selected-window)))
    (save-excursion
      (mouse-drag-track click)
      (if mark-active
	  (progn (kill-new (buffer-substring (region-beginning) (region-end)))
		 (setq selected 1))))
    (select-window win)
    (if selected 
	(progn 
	  (if mark-active (delete-region (region-beginning) (region-end)))
	  (yank)
	  (redraw-display)))))
 
(defun mouse-stay-and-kill (click)
  "leaves cursor at current position, allows to drag a region which 
is moved to cursor position"
  (interactive "e")
  (let ((selected nil)
	(win (selected-window)))
    (save-excursion
      (mouse-drag-track click)
      (if mark-active 
	  (progn (kill-region (region-beginning) (region-end))
		 (setq selected t))))
    (select-window win)
    (if selected 
	(progn (if mark-active (delete-region (region-beginning) (region-end)))
	       (yank)
	       (redraw-display)))))
 
(defun mouse-stay-and-swap (click)
  "leaves cursor at current position, allows to drag a region which 
is swapped with the original selection"
  (interactive "e")
  (let ((selected nil)
	(win (selected-window))
	(obuf nil)
	(olen nil)
	(opos nil))
    (save-excursion
      (mouse-drag-track click)
      (if mark-active 
	  (progn (setq olen (- (region-end) (region-beginning)))
		 (kill-region (region-beginning) (region-end))
		 (setq obuf (current-buffer))
		 (setq opos (point))
		 (setq selected t))))
    (select-window win)
    (if selected
	(progn (if (and (eq obuf (current-buffer)) (> opos (point)))
		   (setq opos (+ opos olen 
				 (if mark-active (- (region-beginning) (region-end)) 0))))
	       (if mark-active
		   (kill-region (region-beginning) (region-end))
		 (kill-region (point) (point)))
	       (rotate-yank-pointer 1) (yank)
	       (set-buffer obuf) (goto-char opos)
	       (rotate-yank-pointer -1) (yank)
	       (redraw-display)))))
 
(defun mouse-yank-and-kill (click)
  "yanks selection at mouse click and kills original"
  (interactive "e")
  (if mark-active
      (let ((beg (region-beginning))
	    (end (region-end))
	    (pos (event-start click)))
	(kill-region beg end)
	(select-window (posn-window pos))
	(goto-char (posn-point pos))
	(yank))
    (mouse-set-point click)))
 
(defun my-query-replace (str1 str2)
  (interactive
   (let ((str (read-string "Query replace: " 
			   (if mark-active 
			       (let ((h (buffer-substring (point) (mark))))
				 (if (< (mark) (point)) (exchange-point-and-mark))
				 (kill-new h)
				 h)
			     ""))))
     (setq mark-active nil)
     (list str (read-string (format "Query replace: %s with: " str)))))
  (query-replace str1 str2 current-prefix-arg))
 
(defun my-query-replace-word (str1 str2)
  (interactive
   (let ((str (read-string "Query replace word: " 
			   (if mark-active 
			       (let ((h (buffer-substring (point) (mark))))
				 (if (< (mark) (point)) (exchange-point-and-mark))
				 (kill-new h)
				 (concat "\\<" (regexp-quote h) "\\>"))
			     ""))))
     (setq mark-active nil)
     (list str (read-string (format "Query replace word: %s with: " str)))))
  (query-replace-regexp str1 str2 current-prefix-arg))
 
(defun my-query-replace-regexp (str1 str2)
  (interactive
   (let ((str (read-string "Query replace regexp: " 
			   (if mark-active 
			       (let ((h (buffer-substring (point) (mark))))
				 (if (< (mark) (point)) (exchange-point-and-mark))
				 (kill-new h)
				 (regexp-quote h))
			     ""))))
     (setq mark-active nil)
     (list str (read-string (format "Query replace regexp: %s with: " str)))))
  (query-replace-regexp str1 str2 current-prefix-arg))
 
(defun convert-to-regexp-pattern (a o)
  (interactive "r")
  (let ((h (buffer-substring a o)))
    (delete-region a o)
    (insert (cond ((string-match "^\\s-+$" h) "\\(\\s-+\\)")
		  ((string-match "^[0-9]+$" h) "\\([0-9]+\\)")
		  ((string-match "^[A-Za-z_][0-9A-Za-z_]*$" h) "\\([A-Za-z_][0-9A-Za-z_]*\\)")
		  ((string-match "^\\S-+$" h) "\\(\\S-+\\)")
		  (t "\\(.+\\)")))))
 
;; ------------------------------------------------------------------------------
;; Key bindings
;; ------------------------------------------------------------------------------
(define-key global-map '[C-right] 'forward-sexp)
(define-key global-map '[C-left] 'backward-sexp)
(define-key global-map '[s-left] 'windmove-left)
(define-key global-map '[s-right] 'windmove-right)
(define-key global-map '[s-up] 'windmove-up)
(define-key global-map '[s-down] 'windmove-down)
(define-key global-map '[S-down-mouse-1] 'mouse-stay-and-copy)
(define-key global-map '[C-M-S-down-mouse-1] 'mouse-stay-and-swap)
(define-key global-map '[S-mouse-2] 'mouse-yank-and-kill)
(define-key global-map '[C-S-down-mouse-1] 'mouse-stay-and-kill)
;; replaced with windows key, see above
;;(define-key global-map '[M-down] (lambda () (interactive) (other-window 1)))
;;(define-key global-map '[M-up] (lambda () (interactive) (other-window -1)))
(define-key global-map "*"     'my-query-replace-regexp)
(define-key global-map "%"     'my-query-replace)
(define-key global-map "+"     'my-query-replace-word)
(define-key global-map "&"     'my-replace-string)
(define-key global-map "^" 'convert-to-regexp-pattern)
(define-key global-map "\C-a" 'mark-whole-buffer)
 
;; ------------------------------------------------------------------------------
;; Compilation
;; ------------------------------------------------------------------------------
(defvar current-compilation-buffer nil)
(define-key global-map "\215" 	;; META-RET; compile
  (lambda (prefix) (interactive "P")
    (condition-case nil (kill-compilation) (error nil))
    (if prefix (setq current-compilation-buffer (current-buffer)))
    (save-excursion 
      (set-buffer
       (if (buffer-live-p current-compilation-buffer)
           current-compilation-buffer (current-buffer)))
      (call-interactively 'compile))))
(define-key minibuffer-local-map "\215" 'exit-minibuffer)
(define-key minibuffer-local-map "#" 'minibuffer-keyboard-quit)
 
(define-key ctl-x-map  "." 
  '(lambda() (interactive)
     (condition-case nil (next-error 1)
       (error (condition-case nil (next-error 0) (error (next-error nil)))))))
 
(define-key ctl-x-map  "," 'previous-error)
 
;; ------------------------------------------------------------------------------
;; Debugger
;; ------------------------------------------------------------------------------
(defun gud-break-eval-cont (cmd)
  (interactive "sEnter command:")
  (comint-interrupt-subjob)
  (gud-basic-call cmd)
  (gud-cont nil))
 
(defun gud-gdb-reload ()
  (interactive)
  (let ((nm (buffer-name)))
    (if (string-match "^\\*...-\\(.+\\)\\*$" nm)
	(progn (gud-basic-call (format "file %s" (substring nm (match-beginning 1) (match-end 1))))
	(message "reloaded debugger file")))))
 
(setq gdb-mode-hook
      '((lambda ()
          (define-key gud-mode-map "s" 'gud-step)
          (define-key gud-mode-map '[f5] 'gud-step)
          (define-key gud-mode-map '[f6] 'gud-next)
          (define-key gud-mode-map '[f7] 'gud-finish)
          (define-key gud-mode-map '[f8] 'gud-cont)
          (define-key gud-mode-map '[f9] 'gud-up)
          (define-key gud-mode-map '[f10] 'gud-down)
 
          (define-key gud-mode-map "n" 'gud-next)
          (define-key gud-mode-map "k" 'gud-cont)
          (define-key gud-mode-map "e" 'gud-break-eval-cont)
          (define-key gud-mode-map "f" 'gud-finish)
          (define-key gud-mode-map "u" 'gud-up)
          (define-key gud-mode-map "d" 'gud-down)
          (define-key gud-mode-map "r" 'gud-gdb-reload)

Emacs + Doxygen = Doxymacs

doxymacs

In fact, most developers around the world probably dislike writing comments within their programs, no matter which language is considered. However, exhaustive code documentation improves the overall code quality, and thus also the software quality. Moreover, code documentation is essential in projects where teams with several people work on the same code base. Thus, the motivation to simplify the writing of comments/code documentation is very high, because the developer wants to focus on the essentials, namely the semantic and contents of the documentation and not any kind of syntax (/* ... */). Since the eclipse IDE has an inherent high comfort concerning auto-completion of javadoc and doxygen comments, I was a bit disappointed when I switched to emacs, because there is no such thing in emacs by default. Fortunately, there’s an emacs extension called Doxymacs, which can be obtained from this link.

Installation

If you are using ubuntu, then you’re lucky, since ubuntu has a dedicated package called doxymacs

Configuration and Usage

After successful installation, you should modify your ~/.emacs file to include doxymacs:

1
2
3
4
5
6
(require 'doxymacs)
(add-hook 'c-mode-common-hook 'doxymacs-mode)
(defun my-doxymacs-font-lock-hook ()
    (if (or (eq major-mode 'c-mode) (eq major-mode 'c++-mode))
        (doxymacs-font-lock)))
(add-hook 'font-lock-mode-hook 'my-doxymacs-font-lock-hook)

where the second line automatically activates doxymacs for the c-mode, which is most likely what you want. Furthermore, the function and its invocation in lines 3-6 enables pretty fontification for doxygen keywords (e.g. param)

The defaults key-bindings are as follows:

  • C-c d ? will look up documentation for the symbol under the point.
  • C-c d r will rescan your Doxygen tags file.
  • C-c d f will insert a Doxygen comment for the next function.
  • C-c d i will insert a Doxygen comment for the current file.
  • C-c d ; will insert a Doxygen comment for a member variable on the current line (likeĀ M-;).
  • C-c d m will insert a blank multi-line Doxygen comment.
  • C-c d s will insert a blank single-line Doxygen comment.
  • C-c d @ will insert grouping comments around the current region.

Additions

I found the following function that automatically inserts an asterisk (*) whenever one is hitting return within a multiline comment:

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
(defun my-javadoc-return () 
  "Advanced C-m for Javadoc multiline comments.   
Inserts `*' at the beggining of the new line if 
unless return was pressed outside the comment"
  (interactive)
  (setq last (point))
  (setq is-inside
	(if (search-backward "*/" nil t)
	    ;; there are some comment endings - search forward
	    (if (search-forward "/*" last t)
		't
	      'nil)
	  ;; it's the only comment - search backward
	  (goto-char last)
	  (if (search-backward "/*" nil t)
	      't
	    'nil
	    )
	  )
	)
  ;; go to last char position
  (goto-char last)
  ;; the point is inside some comment, insert `*'
  (if is-inside
      (progn 
	(insert "\n*")
	(indent-for-tab-command))
    ;; else insert only new-line
    (insert "\n")))
(add-hook 'c++-mode-hook (lambda () 
  (local-set-key "\r" 'my-javadoc-return)))

Links

Window Buttons in Ubuntu 10.04

With Ubuntu 10.04 alias “Lucid Lynx” the new “Ambiance”-theme was introduced.
Furthermore, the designers of Ubuntu decided to change the location of the window buttons from the right to the left, which in my opinion is really unusual.
Fortunately, Linux is very customizable and this behavior can be changed in order to move the buttons back to their previous location on the right.

Therefore, you’d have to change the attribute
/apps/metacity/general/button_layout
to the value “menu:minimize,maximize,close”, which can be done with Ubuntu’s configuration editor (GConf). This editor can be started by invoking the gconf-editor command on the console.
Alternatively, you could use the gconftool-2 utility to change the setting directly on the command line:
$ gconftool -s /apps/metacity/general/button_layout -t string menu:minimize,maximize,close

SMBackup

This Script was designed to backup a database onto a backup-server that (only) provides SMB-Shares.
If there are already more than $CYCLE files present within the destination directory, the oldest file will be overwritten.

You might get the impression that I am abusing my blog to host scripts.
Well, you’re right ;-)

There you go:

#!/bin/sh
# This script backs up a db with adjustable cycles
 
BAKPATH='/mnt/backup'                                   ## The Path to store the backups in
SMBPATH='//10.10.10.10/backup'                     	## Path to the smb-share to store the backup in
SMBUSER='user'                                     	## User to login with
SMBPASSWD=''                                		## Password to use for smb-auth. in base64 encoding
CYCLE=7                                                 ## Number of backup-files in one cycle, the oldest backup will be overwritten
SUFFIX='_backup.sql'                                    ## The suffix of the filename
MYSQL_ROOTPW=''                             		## MySQL-Password for root in base64 encoding
MYSQL_DB='somedb'                                 	## The database to be backed up ;)
LOGFILE='/var/log/backups'                              ## Where shall i write logs to?
 
### Mount the SMB-share to BAKPATH
mount -t smbfs $SMBPATH $BAKPATH -o username=$SMBUSER,password=$( echo $SMBPASSWD | openssl enc -base64 -d )
 
### Is it mounted correctly?
MOUNTS=$( mount | grep $BAKPATH | wc -l )
if [ $MOUNTS -eq 0 ] ; then
        echo $(date)"   Couldn't map SMB-share to my local FS! Exiting, no Backup created" >> $LOGFILE;
 
        if [ ! -d $BAKPATH ]; then
                echo $(date)"   The specified BAKPATH doesn't exist!" >> $LOGFILE;
        fi
 
else
        echo $(date)"   SMB-share $SMBPATH mapped successfully to $BAKPATH!" >> $LOGFILE;
 
### Get the number of files in our BAKPATH
        NUMFILES=$(ls -1 $BAKPATH | wc -l)
 
### While the number of backups is >= $CYCLE
        while [ $NUMFILES -ge $CYCLE ]; do
 
### Get the oldest backup; delete it and do some output/logging
                OLDESTFILE=$( ls -t1 $BAKPATH | tail -n 1 )
                OLDESTABSFILE=$BAKPATH"/"$OLDESTFILE
                rm $OLDESTABSFILE
                if [ ! -f $OLDESTABSFILE ]; then
                        NUMFILES=`expr $NUMFILES - 1`
                        echo $(date)"   Deleted Backup $OLDESTABSFILE to make space ;)" >> $LOGFILE
                fi
 
        done
 
### Now create the backup
        FILE=$(date +%Y%m%d)"_"$(date +%H%M%S)$SUFFIX
        ABSFILE=$BAKPATH"/"$FILE
        mysqldump --user=root --password=$( echo $MYSQL_ROOTPW | openssl enc -base64 -d ) $MYSQL_DB > $ABSFILE
        tar -czf $ABSFILE.tar.gz $ABSFILE
        rm $ABSFILE
 
### Do some logging
        if [ -f $ABSFILE.tar.gz ]; then
                echo $(date)"   Backup '$ABSFILE' successfully created" >> $LOGFILE;
        else
                echo $(date)"   Couldn't create the backup!" >> $LOGFILE;
        fi
        umount $BAKPATH
 
fi

Mount/Unmount ISO images in nautilus

Hey,

I figured out that nautilus, the file browser of GNOME, has a nice feature of adding scripts to the context menu (right click).
For instance, you can place the following two scripts in ~/.gnome2/nautilus-scripts/ and make them executable (chmod +x).
Then you will be able to do a right-click on iso-images for (un)mounting them.

mount.sh:

#!/bin/bash
# mount
 
gksudo -k /bin/echo "got r00t?"
BASENAME=`basename $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS`
MOUNTPOINT="/media/$BASENAME"
 
if [ ! -d "$MOUNTPOINT" ] ; then
	sudo mkdir "$MOUNTPOINT"
fi
 
ret=`sudo mount -o loop,uid=$UID,gid=$GROUPS $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS "$MOUNTPOINT"`
if [ $? ] ; then
	zenity --info --title "ISO Mounter" --text "$BASENAME Successfully Mounted."
	exit 0
else
	zenity --error --title "ISO Mounter" --text "Could not mount $BASENAME!\nReason: $ret"
	sudo rmdir "$MOUNTPOINT"
	exit 1
fi

unmount.sh:

#!/bin/bash
# unmount
 
gksudo -k /bin/echo "got r00t?"
BASENAME=`basename $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS`
MP="/media/$BASENAME"
 
ret=`sudo umount "$MP"`
if [ $? ] ; then
	zenity --info --title "ISO Mounter" --text "Successfully unmounted $MP"
	sudo rmdir "$MP"
	exit 0
else
	zenity --error --title "ISO Mounter" --text "Could not
	unmount $MP\nReason: $ret"
fi

LaTeX PDFmerge

Hey there,

since merging several pdf files is a task that needs to be done pretty often, I decided to write a little TeX file for that.
The initial version assumes that all pdf files have the same name pattern and end with a number:

\documentclass[a4paper,landscape]{article}
\usepackage{pdfpages}
\usepackage{forloop}
 
\begin{document}
 
\newcounter{ct}
\forloop{ct}{1}{\value{ct} < 8}%
{%
    \includepdf[pages=-]{FILENAME\arabic{ct}.pdf}
}
 
\end{document}

About one usage after that, I wrote a perl-script that scans a given directory for pdf files and merges them by creating a TeX-script:

#!/usr/bin/perl
 
use Getopt::Std;
use Switch;
 
$texfile = "/tmp/merge.tex";
$getoptstr = 'p:f:';
$path = '';
$format = 'portrait';
 
sub usage() {
	print <<"EOF";
Usage: $0 -p <path> [-f <l|p>]
	-p: path where the pdf's to merge reside
	-f: page format (defaults to p):
		l: landscape
		p: portrait
EOF
	exit(1);
}
 
@ARGV < 2 and usage();
 
getopts($getoptstr, \%args) or usage();
 
while (($key,$value) = each %args) {
	switch ($key) {
		case 'p' { $path = $value; }
		case 'f' { $format = $value eq "l" ? "landscape" : "portrait"; }
	}
}
 
unless (-e $path) {
	die("Directory \"$path\" doesn't exist!");
}
 
open(TEXFILE, ">" . $texfile)
	or die("Couldn't open TeX-File");
 
print TEXFILE <<"EOF";
\\documentclass[a4paper,$format]{article}
\\usepackage{pdfpages}
\\usepackage{forloop}
\\begin{document}
EOF
 
foreach $file (<$path/*.pdf>) {
	print TEXFILE '\includepdf[pages=-]{'.$file.'}'."\n";
}
print TEXFILE '\end{document}'."\n";
close(TEXFILE);
 
print `pdflatex $texfile`;
 
`rm $texfile` and die("Couldn't delete $texfile");
 
exit(0);

Captions in Algorithm2e

Hey guys,

these days I came across the algorithm2e package of LaTeX, which I prefer to the classic packages algorithm and algorithmic. Unfortunately, it has a weird behaviour concerning captions. One can set the caption font with \SetAlCapFnt, but then the complete caption (including caption label and caption text) will be changed. I can provide the following workaround:

\usepackage[algochapter,boxed,longend,linesnumbered]{algorithm2e}
\newcommand{\myalgofont}[1]{\textbf{\sffamily{#1}}}
\SetKwSty{myalgofont}
\SetAlCapFnt{\normalfont}
 
% fix for captions in algorithms
\makeatletter
% org: \newcommand{\algocf@captiontext}[2]{#1\algocf@typo: \AlCapFnt{}#2}
\renewcommand\algocf@captiontext[2]{\usekomafont{captionlabel}#1\algocf@typo:
\usekomafont{caption}#2}
\makeatother

You can replace the \usekomafont stuff with whatever font-setting you prefer. If, however, you are using a koma document class, then I suggest to use it like that.