Apache: _default_ virtualhost overlap on port 80

or Apache: _default_ virtualhost overlap on port 443

The size declaration place matters. Apache reads configuration settings from extras directory in alphabetic order. The error will appears if your virtual host was declared before httpd-vhost.conf 
The solution is quite simple. Just add to the httpd.conf before Listen 80 the line

NameVirtualHost *:80

If you use SSL virtual hosts add into httpd-ssl.conf file before Listen 443 the line

NameVirtualHost *:443


Enjoy!

C# IntelliSense plugin for Notepad++ (CSScriptNpp)

This plugin allows convenient editing and execution of the C# code (scripts). It also allows the usual C# IntelliSense and project management tasks to be performed in a way very similar to the MS Visual Studio.
In addition to this, it provides generic debugging functionality (with the integrated Managed Debugger) as well as the ability to prepare C# scripts for the deployment packages (script+engine or self-contained executable).
Typically user opens the C# file with Notepad++ and after presses 'Load' button on the CS-Script toolbar the all features can be accessed through two Notepad++ dockable panels Project and Output panel.



Source: csscriptnpp.codeplex.com

WinSCP failed to open saved session from command line

I would like to save site settings into INI file using portable version of WinSCP and reuse it from console or script file. By default WinSCP has saved session in format [Sessions\myuser@myhost.com], you can see on pic. 1. According to documentation I should open saved session with command
open myuser@myhost.com
But winSCP had trying to connect myhost.com and asked for password.
WinSCP failed to open saved session
pic. 1

Using try-and-fail method I have found that session name should not contain @ . / characters, I have renamed session into myhost_com (pic. 2) and successfully open my stored session with
open myhost_com
pic. 2

Enjoy!

OTRS transfer queue

you can't transfer complete queue to another location in meaning copy all tickets to new location :(
it's possible just move complete queue with all tickets using "Sub-queue of" dropdown, just select new mounting point.



HOWTO copy all tickets to new location.

PLEASE MAKE BACKUP BEFORE ANY CHANGE!

The solution - create  structure at another location and use generic job to move all (open and closed) tickets to new queue. This must be done for all subqueues also.


Enjoy!

nsclient++ and check IIS7 application pools

It exists well-known script for NSClient++ 3.x to check Internet Information Services (IIS) AppPool status. It uses Windows Management Instrumentation (WMI). I didn't find installation instruction for NSClient++ 4.2 and I would like to share my working config.
  • Just save Check_IISv7_AppPool_State.vbs file into scripts directory 
  • modify setting in nsclient.ini file as stays below 
  • restart nsclient service finally

; 
[/modules]
; NRPE server - A simple server that listens for incoming NRPE connection and handles them.
NRPEServer = 1


[/settings/NRPE/server]
allowed hosts = YOUR.NAGIOS.SERVER.ADDRESS
allow arguments = true
allow nasty characters = true
port = 5666
timeout = 60
use ssl = 1
performance data = 1

[/settings/external scripts]
allow arguments = 1
allow nasty characters = 1
timeout = 60

[/settings/external scripts/scripts]
check_iis_defaultapppool=cscript.exe //nologo //T:60 scripts/Check_IISv7_AppPool_State.vbs DefaultAppPool
check_iis_mypool=cscript.exe //nologo //T:60 scripts/Check_IISv7_AppPool_State.vbs "My New Pool"
check_iis_longrunning=cscript.exe //nologo //T:60 scripts/check_IISv7_long_running.vbs 1000 20000

NOTE: Application Pool name with spaces must be quoted as was described in the previous post!

To check settings from nagios server please execute on remotes host
# /usr/local/nagios/libexec/check_nrpe -H IIS.HOST.IP.ADDRESS -t 60 -p 5666 -c check_iis_mypool

If all settings are correct you should see result
OK! My New Pool: STARTED

Enjoy!

OTRS hide junk/spam queue from move list

Problem: OTRS user complains about wrong moved ticket into spam queue when tried to move into another queue.

IMHO 'spam' button is more secure way to mark as spam the ticket, so we need to remove junk/spam queue from dropdown without coding.
You can't just revoke move_into permission from junk/spam queue's group because you lose option 'mark as spam'. And here can help us simple ACL

#hide junk queue
$Self->{TicketAcl}->{'ACL-hide-junk-queue'} = {
 # match properties
 Properties => {
  # all tickets
  Ticket => {

  },
  
  #only on AgentTicketZoom page
  Frontend => {
 Action => [
  'AgentTicketZoom',
 ],
  },
 },
 PossibleNot => {
  # shouldn't be moved into
  Ticket => {
                Queue => ['Junk', 'SPAM'],
            },
  }, 
};

Enjoy!

success story: passing arguments with quoted spaces to check_nrpe from nagios.

I have managed to to pass parameter as twice quoted (“ ‘ param value ‘ “) on nagios side and the command was executed, but it happens only from command line, and i can’t pass parameter from nagios config. In my humble opinion less elegant and non-flexible code is better than non-working solution, as a bad peace is better than a good quarrel. At least it work for me and solution was to hardcoded parameter on nrpe side:
filename with special characters must be quoted with double quotes. Check following command first from command line on remote host
# ./check_file_size.sh -v --maxcrit 100000 "/tmp/Some File Name with Spaces.log"

If command returns filename and file size, the next step to add command to NRPE config. Let’s edit nrpe.cfg and add new command

command[check_file_demo]=/usr/local/nagios/libexec/check_file_size.sh -v --maxcrit 100000 "/tmp/Some File Name with Spaces.log"

save file and execute from command line on remote host

./check_nrpe -H 127.0.0.1 -c check_file_demo

when it works you can use check_nrpe command already from nagios server.

Enjoy!

HOWTO load mysqldump into ms sql


the best way to create new dump file from mysql database without extended inserts and locks with command

> mysqldump --no-create-info --extended-insert=FALSE --skip-add-locks --single-transaction

If you have already existing SQL file created by mysqldump, it contains by default extended inserts.
You can try following perl script to reformat SQL queries.
>  mysqldum2mssql.pl  mysql_dump.sql  > mssql_dump.sql
#!/usr/bin/perl # MySQL dump was created as # >mysqldump -u USER -p  --no-create-info --extended-insert DB_NAME > mysql_dump.sql while(<>){  if(/^(INSERT INTO .*? VALUES)(.*)$/i){    my $insert_into_table = $1;    my $values = $2;    $insert_into_table =~ s/`//g;        (my $table_name = $insert_into_table) =~ m/INSERT INTO (.*?) VALUES/;          my @arr_values = $values =~  m{         \(                  # opening (          (                  # Start capture             (?:             # non-capturing group                 [^()']+     # ignore inner brackets              |  '[^']*'     # skip all between single quotes             )*              # and repeat          )          \)                  # final )        }gx        ;        foreach(@arr_values){         print "$insert_into_table ($_);\n";         print "GO\n";    }  } } 1;
The resulting SQL file contains single insert per line and GO after each line. The file can be loaded into MSSQL compact edition (CE) with utility SqlCeCmd40

Enjoy!

Programming Microsoft® LINQ

I can recommend to learn Programming LINQ the following book [caption id="" align="aligncenter" width="160"] ISBN 978-0735624009[/caption] Get comprehensive guidance for using the Microsoft Language Integrated Query (LINQ) Project with in-depth insights from two experienced developers. Data-rich applications can be difficult to create because of the tremendous differences between query languages used to access data and programming languages commonly used to write applications. This practical guide covers the intricacies of LINQ, a set of extensions to the Visual C# and Visual Basic programming languages. Instead of traversing different language syntaxes required for accessing data from relational and hierarchical data sources, developers will learn how to write queries natively in Visual C# or Visual Basic helping reduce complexity and boost productivity. Written by two experienced developers with strong ties to developer teams at Microsoft, this book describes the LINQ architecture and classes, details the new language features in both C# and Visual Basic, and provides code samples in both languages.
Key Book Benefits:
Delivers an in-depth guidance for using LINQ
Covers architecture, syntax, and classes, illustrating how developers can integrate LINQ into their toolkits
Features code samples in Visual C# (plus Visual Basic in some chapters)

TABLE OF CONTENTS

PART I - LINQ Foundations
1 LINQ Introduction 2 LINQ Syntax Fundamentals 3 LINQ to Objects PART II - LINQ to Relational Data
4 LINQ to SQL: Querying Data 5 LINQ to SQL: Managing Data 6 Tools for LINQ to SQL 7 LINQ to DataSet 8 LINQ to Entities PART III - LINQ and XML
9 LINQ to XML: Managing the XML Infoset 10 LINQ to XML: Querying Nodes PART IV - Advanced LINQ
11 Inside Expression Trees 12 Extending LINQ 13 Parallel LINQ 14 Other LINQ Implementations PART V - AppliedLINQ
15 LINQ in a Multitier Solution 16 LINQ and ASP.NET 17 LINQ and WPF/Silverlight 18 LINQ and the Windows Communication Foundation PART VI - Appendixes
A ADO.NET Entity Framework B C# 3.0: New Language Features C Visual Basic 2008: New Language Features

HOWTO split OTRS into two instances

sometimes you need to split OTRS into two or more instances. You can just backup/restore database,
copy all OTRS files. Change paths, change SystemID and so on!
What to do with articles stored on file system. Should I copy all 20 GB also?
Not really! I can move only necessary files.

First of all let's create directory structure on new instance. SQL can help us with query


SELECT distinct DATE_FORMAT(create_time, 'mkdir %Y\\%m\\%d') a FROM ticket  


save output into batch file and execute it in the directory /otrs/var/article/

Next step to select all articles. Let's suppose we want to move queues with IDs 1,3,5,10 etc.
SELECT CONCAT(DATE_FORMAT(a.create_time, 'move %Y\\%m\\%d\\'),convert(a.id,char(20)), ' C:\\path_to_new_OTRS\\var\\article\\',DATE_FORMAT(a.create_time, '%Y\\%m\\%d\\')) a 
FROM article a JOIN ticket t  ON t.id=a.ticket_id
WHERE  t.queue_id in (1,3,5,10); 


save output again into batch file and execute it in the directory /otrs/var/article/

Enjoy!

Crosstab (Pivot Table) in C# Release 2.0

I have revised old code completly due to lack of custom aggregation. Additional to sum function you can use Average or Count functions. Also you can create you own custom aggregation and pass it as parameter into PivotTable constructor.

Sources are available on GitHub.

How to create pivot table in C# and display it in DataGrid without Excel?



What if we would like to pivot free set? Sample below will pivot any DataTable and produce new DataTable with average values. Data is ready to display in grid.

    using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CrossTab;
using System.Data;
namespace UnitTest
{
[TestClass]
    public class UnitTest1
    {
[TestMethod]
        public void TestMethod1()
        {
            object DBNULL = DBNull.Value;
            DataTable src = new DataTable();
            DataTable dst = null;
            src.Columns.Add("City", typeof(string));
            src.Columns.Add("Product", typeof(string));
            src.Columns.Add("Value", typeof(double));
            
            src.Rows.Add("City A", "Product 1", 1.2);
            src.Rows.Add("City C", "Product 2", 0.3);
            src.Rows.Add("City A", "Product 1", 1.0);
            src.Rows.Add("City B", "Product 3", 2.2);
            src.Rows.Add("City B", "Product 1", 1.5);
            src.Rows.Add("City A", "Product 2", 0.8);
            src.Rows.Add("City A", "Product 4", 1.1);
            PivotTable test = new PivotTable(DemoAverageCalc.Average);
            dst = test.Pivot(src, "Product", "City", "Value");
            CollectionAssert.AreEqual(new object[] { "City A", 1.1, 0.8, DBNULL, 1.1 }, dst.Rows[0].ItemArray);
            CollectionAssert.AreEqual(new object[] { "City B", 1.5, DBNULL, 2.2, DBNULL }, dst.Rows[1].ItemArray);
            CollectionAssert.AreEqual(new object[] { "City C", DBNULL, 0.3, DBNULL, DBNULL }, dst.Rows[2].ItemArray);
        }
    }
}
Custom aggregation
 using System;
using System.Collections;
using System.Text;
namespace UnitTest
{
    public class DemoAverageCalc
    {
        // my inner type is double
        public static object Sum(ArrayList set)
        {
            double ret = 0.0;
            foreach (object t in set)
            {
                if(t is double)
                    ret = ret + (double)t;
            }
            return ret;
        }
        public static object Average(ArrayList set)
        {
            return (double)Sum(set) / (double)set.Count;
        }
    }
}

Enjoy!

Notepad++ and function list feature

Starting from version 6.4.1 Notepad++ doesn't use plugging FunctionList any more, because it's now built-in feature. I have copied short description from origin.




Function List Panel is a zone to display all the function (or method) find in current file. User can use Function List Panel to access to a function definition quickly by double clicking function item on the list. Function List can be customized to list the functions for whichever language. For customizing Function List to recognize your favorite language, please check below.
Function list contains a search engine (by using regular expression) and a panel to display the search result (function list). It is designed to be as generic as possible, and allows user to modify the way to search, or to add new parser for any programming language.
In order to make function list work for your language (if not supported), you should modify functionList.xml. It can be found in %APPDATA%\notepad++\ or in Notepad++ installed directory if you use zip package.

Define your parser and add it by adding node parser in parsers node:
function list parsers

In parser node it contains:
id: unique ID for this parser
displayName: reserved for future use.
comment: Optional. you can make a RE in this attribute in order to identify comment zones. The identified zones will be ignored by search.


There are 3 kinds of parsers: function parserclass parser and mix parser.
Define a function parser if the language has only functions to parse (for example C).
Define a class parser if the language has functions "defined" in a class, but no function defined outside of a class (for example Java).
Define a mix parser if you have function "defined" both inside and outside of a class in a file (for example C++).

A function parser contains only a function node.
A class parser contains only a classRange node.
A mix parser contains both function and classRange nodes.

Function parser


In function node it contains:
mainExpr: it's the regex to get the whole string which contains all the information you need.
displayMode: reserved for future use.
functionName: define a or several RE to get the function name from the result of "mainExpr" attribute of "function" node.
    - nameExpr: 1..N
        - expr: here you define the RE to find the function name.

className: define a or several RE to get the class name from the result of "mainExpr".
    - nameExpr: 1..N
      - expr: here you define the RE to find the function name.
  
Both functionName and className nodes are optional.
If functionName and className are absent, then the found string by mainExpr RE will be processed as function name, and the class name won't be used.


The nodes functionName and className have the same structure, and they have the same parsing behaviour. For example, in the functionName node, we got 2 nameExpr nodes:
If the function parser find the first result by mainExpr attribute, then it will use the first nameExpr to search in the first result, if found (the 2nd result), then it will use the 2nd nameExpr to search in the 2nd result. If found, then the function name is solved.

Class parser


In classRange node it contains:
mainExr: the main whole string to search
displayMode: reserved for future use.
openSymbole & closeSymbole: they are optional. if defined, then the parser will determinate the zone of this class. It find first openSymbole from the first character of found string by mainExpr attribute. then it determinates the end of class by closeSymbole found. The algorithm deals with the several levels of imbrication. for example: {{{}{}}{}}
className: 1 (or more) nameExpr node for determination of class name (from the result of mainExprsearching).
function: search in the class zone by using mainExpr attribute and the functionName nodes.

Mix parser


Mix Parser contains Class parser (classRange node) and Function parser (function node).
Class parser will be applied firstly to find class zones, then function parser will be applied on non-class zones.

Link to Language


<associationMap>
<!-- langID:
L_TEXT: 0     L_PHP: 1        L_C: 2        L_CPP: 3       L_CS: 4         L_OBJC: 5
L_JAVA: 6     L_RC: 7         L_HTML: 8     L_XML: 9       L_MAKEFILE: 10  L_PASCAL: 11
L_BATCH:12    L_INI: 13       L_ASCII: 14   L_USER: 15     L_ASP: 16       L_SQL: 17
L_VB: 18      L_JS: 19        L_CSS: 20     L_PERL: 21     L_PYTHON: 22    L_LUA: 23
L_TEX: 24     L_FORTRAN: 25   L_BASH: 26    L_FLASH: 27    L_NSIS: 28      L_TCL: 29
L_LISP: 30    L_SCHEME: 31    L_ASM: 32     L_DIFF: 33     L_PROPS: 34     L_PS: 35
L_RUBY: 36    L_SMALLTALK:37  L_VHDL: 38    L_KIX: 39      L_AU3: 40       L_CAML: 41
L_ADA: 42     L_VERILOG: 43   L_MATLAB: 44  L_HASKELL: 45  L_INNO: 46      L_SEARCHRESULT: 47
L_CMAKE: 48   L_YAML: 49      L_COBOL 50    L_GUI4CLI: 51  L_D: 52         L_POWERSHELL: 53
L_R: 54       L_JSP: 55
-->
<association langID="1" id="php_function"/>
<association langID="2" id="c_function"/>
<association langID="3" id="c_cpp_function"/>
<association langID="6" id="java"/>
<association langID="9" id="xml_node"/>
<association langID="12" id="batch_label"/>
<association langID="13" id="ini_section"/>
<association langID="19" id="js_function"/>
<association langID="21" id="perl_function"/>
<association langID="28" id="nsis_syntax"/>
<!--
if langID cannot be found above, you can still set the file extensions
<association ext=".my_passer_ext1" id="my_passer_id"/>
<association ext=".my_passer_ext2" id="my_passer_id"/>

for User Defined Languages:
<association userDefinedLangName="my user defined language" id="my_udl_passer_id"/>
<association userDefinedLangName="Autocad" id="my_autocad_passer_id"/>
-->

</associationMap>

Once you finish to defined your parser, you can associate it with Notepad++ internal language id (or with file extension), in order to make it works with the language you want. All you need to do is add associationnode(s) into associationMap node.

In associationMap, it contains:
association: 1 or several nodes to make associations between defined parsers and languages.
    - langID: Notepad++ internal language ID.
    - userDefinedLangName: User Defined Language Name. It makes association between User Defined Language and the parser. If langID is present, this attribute will be ignored.
    - ext: File name extension (should contain '.'). If langID or userDefinedLangName is present, this attribute will be ignored.
    - id: Parser ID.

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!


HOWTO: Repair Logitech M325 Mouse

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