2013-12-18

Sending emails to addresses and subjects in a CSV with a fixed message in a textfile

The following script was generated to notice approvers that an audit initiated the deletion of some users they did not approved (again). The Subject contains the usernames, and the message is a template with some PC blahblah.

#!/bin/bash

if [ $# -lt 2 ]; then
 echo "No arguments passed! I need a 'mailaddr;subject' .csv and a txt containing the fixed message."
 echo "csvmailer.sh addresses.csv message.txt"
 exit 1
fi

while read p; do
 IFS=';'
 TOKENS=($p) 
 EMAIL=${TOKENS[0]}
 SUBJ=${TOKENS[1]}
 IFS=' '
 mail -s "$SUBJ" "$EMAIL" < $2
done < $1

The CSV is like "jane.doe@company.com;This is a message in the subject about deleting the account of 'johndoe@company.com'\n". Do NOT put a semicolon into the subject column :-D

IFS sets the Internal Field Separator to semicolon (';'), instead of the default whitespace. This way the array generator/tokenizer is dead simple in the next line.

$1 is the CSV file, read into $p line-by-line.

$2 is the fixed message piped into mail.

2013-12-17

Battlefield 2 Piloting with mouse - tip of the day

Assign "pitch up" ("pitch+") to a key on your keyboard (like spacebar, it's unused by default in jets), so you don't have to destroy your mouse while pulling up ;-)

Thanks, Andris!

2013-12-15

Cisco VPN vs. Linux, KDE

So you have a Cisco proprietary PCF file, and you want to use it in your KDE, but the Network Manager's VPN Import says it cannot do it?
Here is what to do:
# apt-get install network-manager-vpnc
(This should also install vpnc if you haven't had it already.) Now, try importing the PCF file again.

Many thanks to: http://thomas.zumbrunn.name/blog/2013/04/04/479/

2013-12-05

Linux: Send files in e-mail from console

So I wanted to send some files, but my mailx package did not have support for the famous -a parameter.

#!/bin/bash

function create_attachment_block()
{
        echo -ne "--$BOUNDARY\r\nContent-Transfer-Encoding: base64\r\n"
        echo -ne "Content-Type: $(file -bi "$1"); name=\"$1\"\r\n"
        echo -ne "Content-Disposition: attachment; filename=\"$1\"\r\n\r\n$(base64 -w 0 "$1")\r\n\r\n"
}

if [ $# -lt 2 ]; then
        echo No files specified...
        exit 1;
fi

BOUNDARY="==combine-autogun==_$(date +%Y%m%d%H%M%S)_$$_=="
BODY=""

for a in "$@"
do
        if [ -s "$a" -a -f "$a" -a -r "$a" ]; then
                BODY="$BODY""`create_attachment_block "$a"`"
        fi
done

/usr/sbin/sendmail -oi -t << COMPLEX_MAIL
To: $1
Subject: Please see files attached
MIME-Version: 1.0
User-Agent: $0
Content-Type: multipart/mixed; boundary="$BOUNDARY"

$BODY
--${BOUNDARY}--
COMPLEX_MAIL

2013-11-18

Get per process IO activity

So you want to see a live average, how your processes spin your disks (in fact, any mounts, including NFS).

Well, procfs exports an io counter, maintained by the read*/write* syscalls.

You can find the source here.

Logging IO activity of a process

Okay, your 3rd party app sucks. It sucks big time. Generates heavy disk traffic at seemingly random times, and you just can't think of anything, anymore. The users are revolting, the website is lagging, your boss is raging.

It is time to check what the hell the app is actually doing.

The following script is using strace to catch all IO-related syscalls done by the given process, and dump them in a CSV manner. Later, you can aggregate by seconds, minutes, file systems, or subsystems (like Lucene, etc), create charts, graphs, and pivots.

#!/bin/sh

if [ "x$1" == "x-h" ]; then
 echo "Usage: ./iotrace.sh <pid>"
 exit 0
fi

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root " 1>&2
   exit 1
fi

if [ $# -gt 0 ]; then
PID=$1
else
echo "Hey, I need a parameter!"
exit 1
fi

ps -eL | grep $PID | awk '{print"-p " $2}' | xargs strace -q -f -v -ttt -T -s 0 -e trace=open,close,read,write 2>&1 | awk -v pid=$PID '
function output(a, f, r, t)
{
 # a - action
 # f - file descriptor
 # r - result
 # t - time as unix epoch
 if (f in fd)
  file = fd[f];
 else
 {
  ("readlink /proc/" pid "/fd/" f) | getline file;
  fd[f] = file;
 }
 if (file !~ /^(socket|pipe|\/dev|\/proc)/ || r ~ /\d+/)
  print a, file, r, strftime("%Y-%m-%d %H:%M:%S"); #substr(t, 0, index(t, ".")-1));
}

BEGIN { OFS=";"; print "op;path;bytes;epoch";}
{
 if($6 ~ /resumed>/)
 {
  if ($5 ~ /open/){fd[$(NF-1)] = pending[$2];}
  else if ($5 ~ /close/){match($4, /([0-9]+)/, a);delete fd[a[1]];}
  else if ($5 ~ /write/){match($4, /([0-9]+)/, a);output("write", pending[$2], $(NF-1), $3);}
  else if ($5 ~ /read/) {match($4, /([0-9]+)/, a);output("read", pending[$2], $(NF-1), $3);}
  
  delete pending[$2];
 }
 else if ($4 ~ /^open\(/)
 {
  match($4, /\"(.+)\"/, a);
  f = a[1];
  if ($(NF-1) == "<unfinished")
  {
   pending[$2] = f;
  } else {
   fd[$(NF-1)] = f;
  }
 }
 else if ($4 ~ /^close\(/)
 {
  match($4, /([0-9]+)/, a);
  f = a[1];
  if ($(NF-1) == "<unfinished")
  {
   pending[$2] = f;
  } else {
   delete fd[f];
  }
 }
 else if ($4 ~ /^write\(/)
 {
  match($4, /([0-9]+)/, a);
  f = a[1];
  if ($(NF-1) == "<unfinished")
  {
   pending[$2] = f;
  } else {
   output("write", f, $(NF-1), $3);
  }
 }
 else if ($4 ~ /^read\(/)
 {
  match($4, /([0-9]+)/, a);
  f = a[1];
  if ($(NF-1) == "<unfinished")
  {
   pending[$2] = f;
  } else {
   output("read", f, $(NF-1), $3);
  }
 }
}'

What it does?
  1. Takes your input of a process ID
  2. Reads all the child processes of this process
  3. Feeds these into xargs to make strace to attach to all of them, also make strace to only print the four syscalls we are interested in (open, close, read, write), these are used by normal java IO methods
  4. Make a dictionary of file descriptors and filenames, and pretty-print the filenames with the acutal number of processed bytes
  5. Also, take care of the interrupted syscall printouts.

An average java webapp with Lucene can produce 3.5M rows in an hour. Note, that it cannot be opened in Excel ;-)

Cisco PCF encrypted group password

Cisco invented the PCF format to store VPN configuration for its clients.
It contains the group password (that lets you through to the individual authentication). Encrypted.

If you need that password, for like: using on your smartphone, setting it up in your SOHO router, or other completely legal reasons, here is a cute website that decrypts that for you:

https://www.unix-ag.uni-kl.de/~massar/bin/cisco-decode

2013-11-11

warning: passing argument <n> of '<some function>’ with different width due to prototype

You receive warnings, like
warning: passing argument 1 of ‘ptrace’ with different width due to prototype
but you do not have any magic there?

You are using -fshort-enums, and the referenced function accepts a member of an enum there (enum __ptrace_request in this example). By -fshort-enums, all the enums will be short int-s, but the function declaration remains a normal int, as the compiler knows it.

Solution: Remove -fshort-enums from your compiler flags.

2013-11-07

Makefile automatic variables

$@
The file name of the target of the rule. If the target is an archive member, then `$@' is the name of the archive file. In a pattern rule that has multiple targets (see section Introduction to Pattern Rules), `$@' is the name of whichever target caused the rule's commands to be run.
$%
The target member name, when the target is an archive member. For example, if the target is `foo.a(bar.o)' then `$%' is `bar.o' and `$@' is `foo.a'. `$%' is empty when the target is not an archive member.
$<
The name of the first dependency. If the target got its commands from an implicit rule, this will be the first dependency added by the implicit rule.
$?
The names of all the dependencies that are newer than the target, with spaces between them. For dependencies which are archive members, only the member named is used.
$^
The names of all the dependencies, with spaces between them. For dependencies which are archive members, only the member named is used. A target has only one dependency on each other file it depends on, no matter how many times each file is listed as a dependency. So if you list a dependency more than once for a target, the value of $^ contains just one copy of the name.
$+
This is like `$^', but dependencies listed more than once are duplicated in the order they were listed in the makefile. This is primarily useful for use in linking commands where it is meaningful to repeat library file names in a particular order.
$*
The stem with which an implicit rule matches. If the target is `dir/a.foo.b' and the target pattern is `a.%.b' then the stem is `dir/foo'. The stem is useful for constructing names of related files. In a static pattern rule, the stem is part of the file name that matched the `%' in the target pattern. In an explicit rule, there is no stem; so `$*' cannot be determined in that way. Instead, if the target name ends with a recognized suffix, `$*' is set to the target name minus the suffix. For example, if the target name is `foo.c', then `$*' is set to `foo', since `.c' is a suffix. GNU make does this bizarre thing only for compatibility with other implementations of make. You should generally avoid using `$*' except in implicit rules or static pattern rules. If the target name in an explicit rule does not end with a recognized suffix, `$*' is set to the empty string for that rule.

2013-10-31

libcmt and msvcrt, cannot compile

Having trouble with libcmt and msvcrt?

Then certainly you are attempting to link multithreaded code to singlethreaded. The libcmt is multi threaded, msvcrt is single threaded. Switch to msvcmrt.lib, or change /MD to /LD, if you're creating dll-s.

2013-10-30

tryLock and NFS --> weird failure, lockfile created but IOException returned

Using tryLock() on a FileChannel, and you cannot get a lock, BUT the lockfile itself is created?

Your nfslock daemon is not running. Check for rpc.statd:
Bad: NFS Locking Daemon is NOT running
If you cannot start it, restart portmap first.

2013-10-29

MCC DAQ miniLAB 1008 (USB) under Linux

Most of the MCC DAQ's USB and PCI devices have 3rd party Linux kernel drivers. For details, see: http://www.mccdaq.com/daq-software/Linux-Support.aspx
  1. Fetch all stuff from here: ftp://lx10.tx.ncsu.edu/pub/Linux/drivers/USB/
  2. Read the README_mcc_usb file CAREFULLY. You have two options:
    1. hiddev
      1. + Easy, works unprivileged.
      2. - May not be present in linux kernel v3.0+, and is not working in 2.4 at all.
      3. - SLOW: max 200Hz (which is not enough for a big setup)
      4. - No documentation and examples exists.
    2. libhid/libusb
      1. + Uses libusb, works under all linux kernels
      2. + No theoretical ceiling for max throughput.
      3. + libusb is portable through Linux, Windows, Mac, etc
      4. - Needs to be run as root, or set the executable to suid.
      5. - Need USB programming knowledge.
      6. - Compiling libhid manually.
  3. I assure you, option 2 (libhid+libusb) will be better.
  4. Step 0: Deploy dependencies
    1. sudo apt-get install libusb-1.0-0 libusb-1.0-0-dev
  5. Step 1: Deploy libhid
    1. Fetch libhid from http://libhid.alioth.debian.org/
    2. tar -xzf libhid*.tar.gz
    3. cd libhid*
    4. ./configure --prefix=/usr --sysconfdir=/etc --disable-werror
    5. make
    6. sudo make install
  6. Step 2: Deploy the MCC-specific libhid-based usb library
    1. wget ftp://lx10.tx.ncsu.edu/pub/Linux/drivers/USB/60-mcc.rules
    2. sudo cp 60-mcc.rules /dev/.udev/rules.d/
    3. sudo udevadm control --reload-rules
    4. tar xzf MCCLIBHID*.tgz
    5. cd libhid (this is another directory!)
    6. Edit the Makefile
      1. Add " -lm" to the end of the line (after "-o $@") in the libmcchid.so target.
      2. Replace all occurence of "/usr/local/" to "/usr/" (there will be 33)
    7. make
    8. sudo make install
    9. run your device's test as root, like "sudo ./test-minilab1008"
      1. Good: "miniLAB 1008 Device is found!" and a menu-driven test interface
      2. Bad: 
        1. "hid_force_open failed" - you're not root
        2. Any other error message: well, hack :-)

2013-10-13

BCM43xx vs. (k)ubuntu 10.04+

  1. sudo bash
  2. apt-get purge bcmwl-kernel-source
  3. apt-get purge bcm-kernel-source
  4. apt-get install linux-firmware-nonfree
  5. reboot
  6. Make sure to turn ON the Wi-Fi button/latch/whatever
  7. Enjoy

2013-10-08

Perforce: Delete a client/workspace even if it does not exist anymore

So the user formatted/lost/whatever their computer and maybe even had opened files there?
Grab your admin account:

  1. p4 client WORKSPACE
    Delete the line starting with "Host:", to remove host restriction from that client workspace.
  2. p4 -u USER -c WORKSPACE revert -k -a
    Reverts all (no file glob specified) unchanged (-a) open files in that workspace (-c), and doesn't sync anything (-k).
  3. p4 client -f -d WORKSPACE
    Deletes (-d) the workspace, forced (-f).
Extras:
    • List user's client workspaces:
      p4 clients -u USER
    • Remove all managed files (just files! directory is just metadata in perforce) from the current workspace:
      p4 sync //...#none
      Then delete the directories manually -_-
    • Explicitly set a server:
      p4 -p perforce-otherone:1666 clients -u USER
    • (Moar to come)

    2013-10-07

    Selenium: Maximizing Chrome and Firefox through a RemoteWebDriver

    Having issues because your browsers driven by a RemoteWebDriver says "no such element"? Maybe other windows interfere.
    Nevertheless, you can try putting it in fullscreen.
    Chrome:
    DesiredCapabilities capability = DesiredCapabilities.chrome();
    LinkedList<String> switches = new LinkedList<>();
    switches.add("--start-maximized");
    capability.setCapability("webdriver.chrome.driver", ".\\chromedriver.exe");
    capability.setCapability("chrome.switches", switches);
    // ...
    RemoteWebDriver driver = new RemoteWebDriver(new URL(this.hub), capability);
    
    A list of chrome command line arguments: http://peter.sh/experiments/chromium-command-line-switches/
    Firefox:
    // ...
    driver.manage().window().maximize();
    

    2013-09-20

    Absolute musthave for vi(m)


    • "Get me out!!!": Esc Esc :q!
    • Save: Esc Esc :w
    • Save&Exit: Esc Esc :wq
    • Insert: Esc Esc i
    • Search for regex: Esc Esc /regex
    • Do search further: n
    • Delete line: Esc Esc dd
    • Delete n lines: Esc Esc ndd
    • Undo: u
    • Go to given line: Esc Esc :number
    • Go to beginning: g
    • Go to end: G

    2013-09-17

    Linux: IO things

    system activity
    sar -P ALL
    If %iowait is greater than 5%, something is DJ-ing with your disks.
    iostat w/ nfs
    iostat -mnh
    This shown which block devices are being read/write right now. If Blk_read/s or Blk_wrtn/s is greater than 50, you can start being suspicious.

    2013-09-16

    LabVIEW: LV By a Programmer

    Some thoughts I had while working in LabVIEW for a couple of years:
    1. Mathematics. Think before draw. "The less you plan, the more complex your VI will be."
    2. Pre-compute. Reuse. Pipeline. "Used twice? SubVI!"
    3. Avoid Express VI-s.
    4. Organize wires into a cluster if they are related, and are more than 3 of them.
    5. If and only if an input is required by the algorithm, set it to required. Not required inputs should have sane defaults. Otherwise, you’ll trash the block diagram with unnecessary constants.
    6. Customize the Clean-up Diagram button for your favourite style, and Use It.
    7. Always go from left to right. Do not make wires that go around from the right, rather extend the space on the left.

    2013-09-10

    Confluence: Search for things skipping the shipped "search engine"

    Using Atlassian Confluence, and have to report on exact things, like "How many, and which pages refer to a given phrase"?
    This searches through all the latest version of all the pages:
    SELECT DISTINCT
       'http://confluence.example.com/confluence/pages/viewpage.action?pageId=' || contentid AS URL
    FROM
       CONTENT
    INNER JOIN BODYCONTENT USING(contentid)
    WHERE
       prevver      IS NULL
       AND SPACEID  IS NOT NULL
       AND PARENTID IS NOT NULL
       AND REGEXP_LIKE(BODY, 'internal-webserver\d(\.example\.com)?\\public', 'i');
    

    HP BSM: Using Oracle Services instead of SID (useful if having a RAC)

    This cannot be set on the wizard, this has to be done by hand. Origin of this information

    1. Log into the server. (rdp or other)
    2. Stop BSM.
    3. Create the file D:\HPBSM\conf\bsm-tnsnames.ora with content:
      hpbsm_service = 
      (DESCRIPTION = 
          (ADDRESS_LIST = 
              (ADDRESS = 
                  (PROTOCOL = TCP)
                  (HOST = oraclerac-vip.example.com)
                  (PORT = 1521)
              )
              (LOAD_BALANCE = on)
              (FAILOVER = on)
          )
          (CONNECT_DATA = 
              (SERVER = DEDICATED)
              (SERVICE_NAME = hpbsm_service)
          )
      )
      
    4. Edit D:\HPBSM\conf\jdbc.drivers.properties
      1. Comment out the line starting with: ddoracle.url=
      2. Add new line (literally): ddoracle.url=jdbc:mercury:oracle:TNSNamesFile=D:\\HPBSM\\conf\\bsm-tnsnames.ora;TNSServerName=${sid}
    5. Create the file D:\HPBSM\odb\conf\jdbc.properties:
      Oracle = ddoracle
      cmdb.url = jdbc:mercury:oracle:TNSNamesFile=D:\\HPBSM\\conf\\bsm-tnsnames.ora;TNSServerName=hpbsm_service
      
      (here you have to include the service name from the bsm-tnsnames.ora)
    6. Run the "Configure HP Business Service Management" utility, and enter hpbsm_service in the SID field (it will be converted to a tnsnames.ora entry lookup by our hack above).
    7. Connect to hp_mgr with SQL Developer or TOAD (or whatever you like):
      SELECT SESSION_ID, SESSION_DB_SID FROM sessions WHERE SESSION_DB_NAME = 'profile_mgr'; -- Must be hpbsm_service. If not, update.
      SELECT SP_ID, SP_VALUE FROM setting_parameters WHERE SP_NAME IN ('opr.db.connection.sid', 'dal.bpi.runtime.sid', 'dal.bpi.pr.repos.sid');  -- All must be hpbsm_service. If not, update.
      
      UPDATE SESSIONS SET SESSION_DB_SID = 'hpbsm_service' WHERE SESSION_ID IN (SELECT SESSION_ID FROM SESSIONS WHERE SESSION_DB_NAME = 'profile_mgr');
      UPDATE SETTING_PARAMETERS SET SP_VALUE = 'hpbsm_service' WHERE SP_ID IN (SELECT SP_ID FROM SETTING_PARAMETERS WHERE SP_NAME IN ('opr.db.connection.sid', 'dal.bpi.runtime.sid', 'dal.bpi.pr.repos.sid'));
      
      
    8. Start BSM.
    9. VALIDATE

    HP BSM: Removing licenses

    As you already know, you cannot remove licenses through the BUI. The only way there is to remove it from the database directly!
    Log in to the DB, into the hp_mgr schema, and:
    SELECT license_key FROM licenses;
    
    The rows ending with a "T*" identifier are the actual licenses. Select the license you want to remove, and delete that row (note: the license_key is the key candidate here), and restart BSM, to get the change in effect!

    Useful, if you have mistakenly added a prod license to your dev tier, or vice versa.

    Jira: Get latest activity for all users after a given date

    This query lists active users after a given date. Useful for filtering out inactive users.
    In this example, list users who were active in this year (2013):
    WITH w_all_user_activities AS
      (SELECT 
        author,
        g.created
      FROM jiraissue i
      INNER JOIN changegroup g ON i.id = g.issueid
      INNER JOIN changeitem c ON c.groupid = g.id
      UNION
      SELECT author, created FROM jiraaction
      UNION
      SELECT reporter, created FROM jiraissue
    ),
    w_tmp_latest_user_activities AS
      (SELECT
        author,
        created,
        RANK() OVER (PARTITION BY author ORDER BY created DESC) dest_rank
      FROM w_all_user_activities
    ),
    w_latest_user_activities AS
      (SELECT 
        author,
        created
      FROM w_tmp_latest_user_activities
      WHERE dest_rank = 1
    )
    SELECT * FROM w_latest_user_activities 
    WHERE created >= TO_DATE('2013-01-01', 'yyyy-mm-dd');
    

    Jira: SQL for "Check workflow entry states are correct" integrity check

    If this query returns any rows, run the "Check workflow entry states are correct" action in the Integrity Checker.
    This issue happens as a result of the lack of using database transactions during the workflow transitions (which changes numerous tables) in Jira.
    SELECT jiraissue.pkey, jiraissue.workflow_id, OS_WFENTRY.*
    FROM jiraissue
    INNER JOIN OS_WFENTRY ON jiraissue.workflow_id = OS_WFENTRY.id
    WHERE OS_WFENTRY.STATE IS NULL OR OS_WFENTRY.STATE = 0;
    

    Update: For JIRA version 6.x I suggest reading this: http://kozelljozsef.blogspot.com/2014/11/jira-check-workflow-entry-states-are-correct.html

    Jira: List users assigned explicitly to project roles

    Assigning people to project roles explicitly is a bad habit, you should avoid it, as it will lay much work on your shoulders when a user's privileges will be changed.
    SELECT actor.roletypeparameter AS username, r.name AS rolename, p.pkey, p.pname AS projectname
    FROM projectroleactor actor
    INNER JOIN cwd_user u ON u.lower_user_name = actor.roletypeparameter
    INNER JOIN projectrole r ON actor.projectroleid = r.ID
    INNER JOIN project p ON actor.pid = p.ID;
    

    Jira: Activity Stream stopped working, throws error

    Using Atlassian Jira, and having faulty activity streams? Also, using Oracle?
    You have an issue (usually from an email), where the subject is empty.
    In Oracle, the empty string is stored as null.
    Therefore, when Jira reads back an issue, its subject will be null (not empty string).
    This screws up the Activity Stream gadget, as it calls String.substring() on it, without any error checking.

    Get rid of the null subjects.
    UPDATE JIRAISSUE SET SUMMARY = '(no subject)' WHERE SUMMARY IS NULL;
    

    Jira: "Passed List had more than one value."

    This error happens in Atlassian Jira, as they maliciously and intentionally avoid using foreign keys and unique indices in their table design.
    If you see the following error in your tomcat log, you have to do a cleanup:
    2013-01-01 01:01:01,111 ajp-8009-1 ERROR      [500ErrorPage.jsp] Exception caught in 500 page org.apache.jasper.JasperException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Passed List had more than one value. 
    org.apache.jasper.JasperException: org.apache.jasper.JasperException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Passed List had more than one value. 
    (...)
    Caused by: java.lang.IllegalArgumentException: Passed List had more than one value. 
            at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:62) 
    (...)
    
    This actually deletes all the duplicated rows, to make every row to be unique (over 'username', at least):
    DELETE FROM columnlayout
    WHERE ROWID IN (
          SELECT "ROWID" FROM (
                SELECT RANK() OVER(PARTITION BY USERNAME ORDER BY ROWID) RANK_N, ROWID AS "ROWID" FROM columnlayout
                WHERE USERNAME IN (
                      SELECT USERNAME FROM columnlayout
                      GROUP BY USERNAME
                      HAVING COUNT(*) > 1
                )
          )
          WHERE RANK_N > 1
    );
    

    Jira: deleted user coming from external directory (like LDAP)

    You are using Atlassian Jira, but your users are authenticated from LDAP (AD/whatever)?
    Surely, when one of your users leaves or gets her name changed, you'll be stuck with malfunctioning watcher lists, as Jira does not use any of those pesky "relational" stuff in RDBMS-s (valid of any DBMS vendor).
    Get rid of the faulty associations.

    DELETE FROM userassociation 
    WHERE LOWER(source_name) IN (
        SELECT DISTINCT LOWER(source_name) FROM userassociation
        MINUS
        SELECT DISTINCT lower_user_name FROM cwd_user)
    

    Jira: "No scrollbar" problem

    Using Atlassian Jira, and an issue view page does not have scrollbars but it should?
    You've got an email containing "overflow: hidden". Get rid of it.

    This will list you all the issues where the description contains the offending CSS.
    SELECT * FROM jiraissue
    WHERE REGEXP_LIKE(description, 'overflow: *hidden', 'i');
    

    2013-08-30

    Java: Running any type of Callable with any kind of constructors

    Java 1.7
    import java.lang.reflect.InvocationTargetException;
    import java.util.concurrent.*;
    
    public class ParallelCaller {
    
        public static final int NUM_CORES = 2 * Runtime.getRuntime().availableProcessors();
        private ExecutorService eservice = Executors.newFixedThreadPool(NUM_CORES);
        ;
        private CompletionService<Object> cservice = new ExecutorCompletionService<>(eservice);
    
        public void Parallel(int numtasks, int iterations, Class clazz, Object... args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            long begTest = new java.util.Date().getTime();
    
            for (int index = 1; index <= numtasks; index++) {
                cservice.submit((Callable<Object>) clazz.getConstructors()[0].newInstance(args));
            }
    
            eservice.shutdown();
    
            Object taskResult;
            for (int index = 0; index < numtasks; index++) {
                try {
                    taskResult = cservice.take().get();
                    System.out.println("result " + taskResult);
                } catch (ExecutionException e) {
                    System.out.println(e.getMessage());
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                    // (Re-)Cancel if current thread also interrupted
                    eservice.shutdownNow();
                    // Preserve interrupt status
                    Thread.currentThread().interrupt();
                }
            }
    
            Double secs = new Double((new java.util.Date().getTime() - begTest) * 0.001);
            System.out.println("run time " + secs + " secs");
        }
    }
    

    Usage:
    public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            int parallel = args.length > 0 ? Integer.parseInt(args[0]) : 5;
            int iterations = args.length > 1 ? Integer.parseInt(args[1]) : 100;
    
            new ParallelCaller().Parallel(parallel, iterations, LoginTest.class, "http://somethingtotest.com", "testuser02", "testuser02", iterations, LoginTest.KnownDrivers.Firefox);
        }
    
    The referred class should implement Callable.

    Java: Parallel.For

    This piece is from StackOverflow:

    public class Parallel {
        private static final int NUM_CORES = Runtime.getRuntime().availableProcessors();
    
        private static final ExecutorService forPool = Executors.newFixedThreadPool(NUM_CORES  * 2);
    
        public static void For(final Iterable<T> elements, final Operation<T> operation) {
            try {
                // invokeAll blocks for us until all submitted tasks in the call complete
                forPool.invokeAll(createCallables(elements, operation));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static Collection<Callable<Void>> createCallables(final Iterable<T> elements, final Operation<T> operation) {
            List<Callable<Void>> callables = new LinkedList<Callable<Void>>();
            for (final T elem : elements) {
                callables.add(new Callable<Void>() {
                    @Override
                    public Void call() {
                        operation.perform(elem);
                        return null;
                    }
                });
            }
    
            return callables;
        }
    
        public static interface Operation<T> {
            public void perform(T pParameter);
        }
    }
    

    Usage:
    // Collection of items to process in parallel
    Collection<Integer> elems = new LinkedList<Integer>();
    for (int i = 0; i < 40; ++i) {
        elems.add(i);
    }
    Parallel.For(elems, 
     // The operation to perform with each item
     new Parallel.Operation<Integer>() {
        public void perform(Integer param) {
            System.out.println(param);
        };
    });
    

    Java: Simple multithreading a piece of code

    import java.util.*;
    import java.util.concurrent.*;
    
    // ...
    
    ExecutorService exec = Executors.newFixedThreadPool(2 * Runtime.getRuntime().availableProcessors());
    try {
        for (int i = 0; i < num_of_runs; i++) {
            exec.submit(new Runnable() {
                @Override
                public void run() {
                    // do stuff in num_of_runs times through a 2*#CPU threadpool
                }
            });
        }
    } finally {
        exec.shutdown();
    }
    

    2013-08-29

    C, MySQL: A minimal UDF

    An example, how to start writing an UDF for MySQL.
    #include <stdio.h>
    #include <string.h>
    
    #include <mysql/my_global.h>
    #include <mysql/my_sys.h>
    #include <mysql/mysql.h>
    #include <mysql/m_ctype.h>
    #include <mysql/m_string.h>
    
    #define UUID_LEN 36
    #define FMASK "%36s"
    #define UUID "/proc/sys/kernel/random/uuid"
    
    my_bool newid_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
    void new_deinit(UDF_INIT *initid);
    char *newid(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
    
    my_bool newid_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
        if (args->arg_count != 0 || args->arg_type[0] != STRING_RESULT)
        {
            strcpy(message, "Wrong arguments to newid; Use the source");
            return 1;
        }
        initid->max_length=UUID_LEN;
        return 0;
    }
    
    void newid_deinit(UDF_INIT *initid)
    {
    //
    }
    
    char *newid(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error)
    {
    FILE *fp;
    char id[UUID_LEN];
    
        if ((fp = fopen(UUID, "r")) != NULL) {
            fscanf(fp, FMASK, id);
            memcpy(result, id, initid->max_length); // UUID_LEN
            *length = initid->max_length; // UUID_LEN
            *error = 0;
            *is_null = 0;
            return result;
        }
        *is_null = 1;
        *error = 1;
        free(result);
        return NULL;
    }
    

    Provides a newid function, which returns an UUID from the kernel's random pool.

    C: conversion from int to string in a given base

    char* baseconv(unsigned long long num, int base)
    {
     char* retbuf = (char*)calloc(65, sizeof(char));
     char *p;
    
     if(base < 2 || base > 16)
      return NULL;
    
     p = &retbuf[64];
     *p = '';
    
     do {
      *--p = "0123456789abcdef"[num % base];
      num /= base;
     } while(num != 0);
    
     return p;
    }
    

    The base can be any integer between 2 and 16. If you expand the string on line 13, you can increment the limit in line 6.

    Why is retbuf 65 char long? The largest parameter value we can get is 264-1. In hexadecimal is 0xFFFFFFFFFFFFFFFF, 16 pieces of "0xF", plus the '\0' at the end. Without the "0x", of course, which we do not prepend.
    But in binary, 264-1 = 11111111111111111111111111111111111111111111111111111111111111112, 64 pieces of "1", plus the final '\0'.

    C#: If you stuck with an Excel interop

    Error message:
    System.Runtime.InteropServices.COMException (0x80028018): Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))

    Solution:
    System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
    WB = XL.Workbooks.Open(newfilepath, ...);
    

    Set the CurrentCulture to en-US just before the Workbooks.Open(). This is required because the one and only VBA language supported by Excel is en-US.
    And no, the Office MUI does NOT exists (altough it is often referenced on msdn...)

    SQL: why you cannot use regex to validate a select

    Regular expressions can match languages only a finite state automaton can parse, which is very limited, whereas SQL is a syntax. It can be demonstrated you can't validate SQL with a regex. So, you can stop trying.
    SQL is a type-2 grammar, it is too powerful to be described by regular expressions. It's the same as if you decided to generate C# code and then validate it without invoking a compiler. Database engine in general is too complex to be easily stubbed.

    C#: Writing xlsx from C#

    http://simpleooxml.codeplex.com/

    C#: Crosscontext calls in WPF

    public static class DispatcherObjectExtensions{
     public static TRet myInvoke(this T source, Func func)  where T:DispatcherObject {
      return (TRet)source.Dispatcher.Invoke(func);
     }
     public static void myInvoke(this T source, Action act) where T:DispatcherObject {
      source.Dispatcher.Invoke(act);
     }
    }
    

    This will put these two extension methods on all DispatcherObject descendants (like System.Windows.Window), and you can call a delegate put in the object's thread/context.

    C#: Anonymous delegates asynchronously

    this.BeginInvoke(new Action(delegate
    { 
     MessageBox.Show("Asynchronous :D"); 
    }));
    

    System.Action is a framework-defined Delegate successor, that does not return anything and doesn't take any arguments. You should use this, instead of fucking around with inheriting from System.Delegate.

    C: Log a message through a macro with the current function name and line number

    // macro magic :D:D
     #define STRINGIFY(x) #x
     #define TOSTRING(x) STRINGIFY(x)
     #ifdef DEBUG
         #define LOG(x, ...) logzor( "NIHLEDTEST " __FILE__  ":"   \
              TOSTRING(__LINE__) " : " __FUNCTION__  "() ==> " x "n", __VA_ARGS__)
     #else
         #define LOG(x, ...)
     #endif
     
     #ifdef DEBUG
     static __inline void logzor(char *msg, ...)
     {
         va_list argptr;
         va_start(argptr, msg);
         vfprintf(stderr, msg, argptr);
         va_end(argptr);
     }
     #endif
    

    2013-08-07

    Oracle: delete duplicate rows from a table, to have only one row for each unique expression

    DELETE FROM EXTERNAL_ENTITIES
    WHERE
       ROWID IN
       (
          SELECT "ROWID" -- ESCAPED, BECAUSE WE NEED THE INNER ROWID, NOT THIS TMPTABLE'S ROWID
          FROM
             (
                SELECT
                   RANK() OVER(PARTITION BY NAME ORDER BY ROWID) RANK_N, -- ORDER IN THE SUBGROUP
                   ROWID AS "ROWID"                                    , -- ESCAPE THE ROWID
                FROM EXTERNAL_ENTITIES
                WHERE
                   NAME IN
                   (
                      SELECT NAME
                      FROM EXTERNAL_ENTITIES
                      GROUP BY NAME
                      HAVING COUNT(*) > 1 -- ONLY DUPLICATES OR MORE
                   )
             )
          WHERE RANK_N > 1
       );
    
    or
    DELETE FROM CUSTOMFIELDVALUE
    WHERE ROWID IN
       (SELECT T."ROWID" FROM
          (SELECT RANK() OVER(PARTITION BY ISSUE, CUSTOMFIELD ORDER BY ROWID) RANK_N, ROWID AS "ROWID"
             FROM CUSTOMFIELDVALUE
             WHERE CUSTOMFIELD IN (10180, 10216, 10336, 10340, 10464, 10550, 10590, 10911, 14714) -- customfield ID-s come here, taken from the log.
          ) T
       WHERE T.RANK_N > 1);
    

    Oracle: Get bind variables inline'd

    This should be run as a script (F5), in SQL Developer. The serveroutput enabling syntax may differ in other clients. Sorry. Run it as SYS.
    This query tries to put inline the bind values, if they were captured.
    EXECUTE DBMS_MONITOR.DATABASE_TRACE_ENABLE( BINDS => TRUE, WAITS => TRUE );
    ALTER SYSTEM SET "_cursor_bind_capture_interval" = 3999;
    ALTER SYSTEM SET "_xpl_peeked_binds_log_size" = 8192;
    
    DECLARE
      V_CHILD_ADDRESS VARCHAR2(64) ;
      V_SQLTEXT       VARCHAR2(4000) ;
      V_BINDNAME      VARCHAR2(30) ;
      V_VALUE         VARCHAR2(4000) ;
      V_WASCAPTURED   VARCHAR2(3) ;
      V_DATATYPE      VARCHAR2(32) ;
      CURSOR C_BIND IS
        SELECT
          NAME        ,
          VALUE_STRING,
          WAS_CAPTURED,
          DATATYPE_STRING
        FROM GV$SQL_BIND_CAPTURE
        WHERE CHILD_ADDRESS = V_CHILD_ADDRESS
        ORDER BY NAME DESC;
    BEGIN
      DBMS_OUTPUT.ENABLE(BUFFER_SIZE => NULL) ;
      FOR ITEM IN
      (SELECT CHILD_ADDRESS, SQL_TEXT
        FROM
          (SELECT
              SQL_ID        ,
              CHILD_ADDRESS ,
              SQL_TEXT      ,
              LAST_LOAD_TIME,
              ROW_NUMBER() OVER(PARTITION BY SQL_ID ORDER BY LAST_LOAD_TIME DESC) AS RN
            FROM GV$SQL
              WHERE SERVICE = (SELECT DISTINCT LOWER(VALUE || '_user') FROM GV$PARAMETER WHERE NAME = 'db_unique_name')
              AND SQL_TEXT NOT LIKE '%I will be filtered out.%'
          ) SQ
        INNER JOIN GV$SESSION SS ON SS.PREV_SQL_ID = SQ.SQL_ID
        WHERE RN = 1
        ORDER BY PREV_EXEC_START DESC
      )
      LOOP
        V_CHILD_ADDRESS := ITEM.CHILD_ADDRESS;
        V_SQLTEXT       := ITEM.SQL_TEXT;
        OPEN C_BIND;
        LOOP
          FETCH C_BIND INTO V_BINDNAME, V_VALUE, V_WASCAPTURED, V_DATATYPE;
          EXIT WHEN C_BIND%NOTFOUND;
          IF V_WASCAPTURED = 'NO' THEN
            V_SQLTEXT := REPLACE(V_SQLTEXT, V_BINDNAME, '''(THE ' || V_DATATYPE || ' VALUE WAS NOT CAPTURED)''') ;
          ELSE
            V_SQLTEXT := REPLACE(V_SQLTEXT, V_BINDNAME, '''' || SUBSTR(V_VALUE, 0, 500) || '''') ;
          END IF;
        END LOOP;
        CLOSE C_BIND;
        DBMS_OUTPUT.PUT_LINE(V_SQLTEXT || ';') ;
      END LOOP;
    END;
    

    Oracle: get a lot of variables

    Run this query as SYS user:
    SELECT ksppinm AS param_name, ksppdesc AS descr, ksppstvl AS param_value, ksppstdvl AS default_value, ksppstcmnt AS comments
    FROM x$ksppi
    INNER JOIN x$ksppcv USING(indx)
    WHERE ksppinm LIKE '%bind_capture%' -- This line is optional, of course
    ORDER BY ksppinm;