OTRS custom crontab was lost

Q: what can I do to restore lost custom crontab of otrs user after update?
A: nothing

Sounds horrible, isn't it? You can only avoid it in the future.

Don't use anymore crontab -e command. Just create new file (e.g. zzz_mycustom_tasks) in the directory
/opt/otrs/var/cron/

and save all your custom tasks in the crontab style
# unlock every hour old locked tickets
35 * * * *  $HOME/bin/otrs.UnlockTickets.pl --timeout >> /dev/null

and run then 
# /opt/otrs/bin/Cron.sh restart

Enjoy!


EuroISDN and DAHDI error message with Digium 1TE435 card span 1: Invalid argument


I have changed setting to serve E1 line with Digium 1TE435BF in /etc/dahdi/system.conf file

span=1,0,0,ccs,hdb3,crc4

and appears error message "DAHDI_SPANCONFIG failed on span 1: Invalid argument (22)"

The problem was in missing settings for wcte43x kernel module in /etc/modprobe.d/dahdi.conf file.
I just added to the file
options wcte43x default_linemode=e1

and restarted modules without error message
# /etc/init.d/dahdi  restart




Enjoy!

HOWTO resolve host name on CentOS, RHEL or Red Hat

It isn't installed nslookup or dig on CentOS by default  anymore. If you want to resolve host names from command-line you should install bind-utils.

#yum install bind-utils

Systemwide nameserver(s) is defined in file /etc/resolv.conf

Enjoy!

All Extension Methods

Sometimes it's better to see how linq method is implemeted to better understand functionality. Microsoft implementation of System.Linq.Enumerable.cs Mono implementation of System.Linq.Enumerable.cs and full list of linq methods (from MSDN)

LINQ query syntax vs method syntax

LINQ query syntax is close to native language and it's simple and easy to read. The method syntax is powerfull but definitively more complicated tool. For example take one previous listing
MySqlConnection conn = new MySqlConnection("SERVER=localhost; DATABASE=employees;UID=root;PASSWORD=");
var emp = new EmployeeDataContext(conn);

var lastSalaries = (from s in emp.Salaries
                    orderby s.EmpNo ascending, s.ToDate descending
                    group s by s.EmpNo into grp
                    let o = grp.First()
                    let averageSalary = (from s in emp.Salaries select s.Salary1).Average()
                    select new { o.EmpNo, o.Salary1, MoreOrLess = (averageSalary > o.Salary1) }).Take(10);

foreach (object b in lastSalaries)
    Console.WriteLine(b);

Listing 12.1

and convert it into new code using corresponding method syntax
MySqlConnection conn = new MySqlConnection("SERVER=localhost; DATABASE=employees;UID=root;PASSWORD=");
var emp = new EmployeeDataContext(conn);

var lastSalaries = emp.Salaries.OrderBy(s => s.EmpNo)
    .ThenByDescending(s => s.ToDate)
    .GroupBy(s => s.EmpNo)
    .Select(grp => new { o = grp.First(), averageSalary = emp.Salaries.Average(s => s.Salary1) })
    .Select(e => new { e.o.EmpNo, e.o.Salary1, MoreOrLess = (e.averageSalary > e.o.Salary1) })
    .Take(10);


foreach (object b in lastSalaries)
    Console.WriteLine(b);

Listing 12.2

now let's open executable file with Reflector and have look at it. Can you imagine what kind of code was generated?!
    MySqlConnection connection = new MySqlConnection("SERVER=localhost; DATABASE=employees;UID=root;PASSWORD=");
    EmployeeDataContext emp = new EmployeeDataContext(connection);
    
    var lastSalaries = emp.Salaries.OrderBy(
        Expression.Lambda>(Expression.Property(expression = Expression.Parameter(typeof(Salary), "s"), 
        (MethodInfo) methodof(Salary.get_EmpNo)), new ParameterExpression[] { expression }))
        .ThenByDescending(Expression.Lambda>(Expression.Property(expression2 = Expression.Parameter(typeof(Salary), "s"), 
        (MethodInfo) methodof(Salary.get_ToDate)), new ParameterExpression[] { expression2 }))
        .GroupBy(Expression.Lambda>(Expression.Property(expression3 = Expression.Parameter(typeof(Salary), "s"), 
        (MethodInfo) methodof(Salary.get_EmpNo)), new ParameterExpression[] { expression3 }))
        .Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType0, Salary>..ctor, 
        <>f__AnonymousType0, Salary>), new Expression[] { 
            expression4 = Expression.Parameter(typeof(IGrouping), "grp"), 
            Expression.Call(null, (MethodInfo) methodof(Enumerable.First), new Expression[] { expression4 }) }, 
            new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_grp, 
                <>f__AnonymousType0, Salary>), 
                (MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, 
                <>f__AnonymousType0, Salary>) }), new ParameterExpression[] { expression4 }))
                .Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0,
                    Salary>, double>..ctor, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>),
     new Expression[] { expression5 = Expression.Parameter(typeof(<>f__AnonymousType0, Salary>), "<>h__TransparentIdentifier0"), 
     Expression.Call(null, (MethodInfo) methodof(Queryable.Average), 
     new Expression[] { Expression.Call(null, (MethodInfo) methodof(Queryable.Select), 
     new Expression[] { Expression.Property(Expression.Constant(emp), (MethodInfo) methodof(EmployeeDataContext.get_Salaries)), 
         Expression.Quote(Expression.Lambda>(Expression.Property(expression6 = Expression.Parameter(typeof(Salary), "s"),
         (MethodInfo) methodof(Salary.get_Salary1)), new ParameterExpression[] { expression6 })) }) }) }, 
     new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>),
         (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_averageSalary, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>) }),
     new ParameterExpression[] { expression5 })).Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType2..ctor, <>f__AnonymousType2), 
         new Expression[] { Expression.Property(Expression.Property(Expression.Property(expression7 = Expression.Parameter(typeof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>),
     "<>h__TransparentIdentifier1"), (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)), 
         (MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, <>f__AnonymousType0, Salary>)), (MethodInfo) methodof(Salary.get_EmpNo)),
     Expression.Property(Expression.Property(Expression.Property(expression7, (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)), 
         (MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, <>f__AnonymousType0, Salary>)), (MethodInfo) methodof(Salary.get_Salary1)), Expression.GreaterThan(Expression.Property(expression7, 
             (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_averageSalary, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)),
     Expression.Convert(Expression.Property(Expression.Property(Expression.Property(expression7, (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)), 
         (MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, <>f__AnonymousType0, Salary>)),
        (MethodInfo) methodof(Salary.get_Salary1)), typeof(double))) }, new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType2.get_EmpNo, <>f__AnonymousType2),
        (MethodInfo) methodof(<>f__AnonymousType2.get_Salary1, <>f__AnonymousType2), 
        (MethodInfo) methodof(<>f__AnonymousType2.get_MoreOrLess, <>f__AnonymousType2) }), 
        new ParameterExpression[] { expression7 })).Take(10);
    
    foreach (object obj2 in lastSalaries)
    {
        Console.WriteLine(obj2);
    }

Listing 12.3

I like it ;)

HOWTO: Repair Logitech M325 Mouse

FixIt says that you will find single screw under CE label. It isn't always true.