Wednesday, September 18, 2013

Qmail starting error "alert: cannot start: unable to open mutex"

If you are getting this error message when you try to start qmail-send - most probably you are moving qmail from old installation to a new server.

The problem comes from missing diretories (and files) which are on most distributions links and when you archive it the real directories will not be trasfered.

Directory is /var/qmail/queue and as you can see from the example bellow it is just a symlink to another directory (example is from NetBSD qmail package):

 # ls -la /var/qmail      
drwxr-xr-x   2 root  wheel  512 Sep 18 15:25 .
drwxr-xr-x  26 root  wheel  512 Aug 24 22:11 ..
lrwxr-xr-x   1 root  wheel   24 Jul 16 04:36 alias -> /usr/pkg/etc/qmail/alias
lrwxr-xr-x   1 root  wheel   12 Jul 16 04:36 bin -> /usr/pkg/bin
lrwxr-xr-x   1 root  wheel   34 Jul 16 04:36 boot -> /usr/pkg/share/examples/qmail/boot
lrwxr-xr-x   1 root  wheel   26 Jul 16 04:36 control -> /usr/pkg/etc/qmail/control
lrwxr-xr-x   1 root  wheel   24 Jul 16 04:36 doc -> /usr/pkg/share/doc/qmail
lrwxr-xr-x   1 root  wheel   12 Jul 16 04:36 man -> /usr/pkg/man
lrwxr-xr-x   1 root  wheel   16 Jul 16 04:36 queue -> /var/spool/qmail
lrwxr-xr-x   1 root  wheel   24 Jul 16 04:36 users -> /usr/pkg/etc/qmail/users

So the real directory is "queue -> /var/spool/qmail" and here is the listing of subdirs:

# ls -la
drwxr-xr-x  11 qmailq  qmail  512 Sep 18 15:34 .
drwxr-xr-x   8 root    wheel  512 Jul 16 04:36 ..
drwx------   2 qmails  qmail  512 Sep  9 15:11 bounce
drwx------  25 qmails  qmail  512 Jan 19  2008 info
drwx------   2 qmailq  qmail  512 Sep 18 13:55 intd
drwx------  25 qmails  qmail  512 Jan 19  2008 local
drwxr-x---   2 qmailq  qmail  512 Jan 19  2008 lock
drwxr-x---  25 qmailq  qmail  512 Jan 19  2008 mess
drwx------   2 qmailq  qmail  512 Sep 18 13:55 pid
drwx------  25 qmails  qmail  512 Jan 19  2008 remote
drwxr-x---   2 qmailq  qmail  512 Sep 18 13:55 todo


Make sure to transfer this directory to the new server and also chown the dirs with correct permissions.

The actual error is caused by missing file sendmutex which resides in /var/spool/qmail/lock/ directory

# ls -la /var/spool/qmail/lock
total 12
drwxr-x---   2 qmailq  qmail   512 Jan 19  2008 .
drwxr-xr-x  11 qmailq  qmail   512 Sep 18 15:34 ..
-rw-------   1 qmails  qmail     0 Jan 19  2008 sendmutex
-rw-r--r--   1 qmailr  qmail  1024 Sep 16 09:39 tcpto


If this file does not exist just create it with the following command (make sure also to change the file owner):
# touch /var/qmail/queue/lock/sendmutex
# chown qmails:qmail /var/qmail/queue/lock/sendmutex


Saturday, September 7, 2013

ТУ Габрово, КСТ, задача 7, страница 79

КСТ, Задача (страница 79, задача 7):

Да се създаде програма, която въвежда символен низ. Да се преобразуват буквите му: от малки в големи и от големи в малки. За целта могат да се използват функциите isupper, islower, toupper, tolower от ctype.h

Таблица на съответствията

Наименование
Описание
broiach
Целочислена променлива, използвана за брояч на цикъл
buf(1024)
Буфер за символният низ със големина 1024 байта
p
Указател, нужен за функцията strchr()
tmp
Временна променлива тип «символ» (char)


Source Code на решението на задачата:

/* Author: Nikolay Hristov, 28.08.2013
 * Използвана литература:
 * - NetBSD Library Functions Manual, NetBSD 4.0, December 24, 2004
 * - Програмният език C, второ издание, Brian Kernigham, Dennis Richie,
 * издателство ZeST Pres, 2004 */

#include <stdio.h>
/* strchr() */
#include <string.h>
/* isupper(), islower(), toupper(), tolower() */
#include <ctype.h>

int main(void){

    int broiach;     /* ... */
    char buf[1024];    /* буфер */
    char *p;     /* указател, нужен за функцията strchr() */
    char tmp;    /* временна променлива тип char, нужен за isupper()/islower() */

    printf("Въведете текст за конвертиране: ");
    /* четем от стандартния вход (stdin) символен низ със размер
     * buf в случая 1024 bytes */
    while(fgets(buf, sizeof(buf), stdin)){
        /* Функцията strchr връща указател към търсения от нас символ.
         * Търсим символа 'нов ред' ('\n') и ако не открие такъв - връща NULL.
         * Ако не открие 'нов ред' в низа, това означава, че е въведен
         * низ > размера на буфера buf (в случая 1024 bytes), което означава,
         * че е натиснат Enter след края на буфера (въведени са минимум 
         * 1025 символа. */
        if((p = strchr(buf, '\n')) == NULL){
            printf("Въведен е прекалено дълъг низ.\n");
            return 1;
        }

        /* При откриване на съвпадение с 'нов ред' ('\n'),
         * функцията strchr връща указател към тази част от масива.
         * Задължително терминираме низа с s \0 */
        
        *p = '\0';
        
        /* Отпечатваме орогиналният низ */
        printf("Въведен низ    : %s\n", buf);
        
        /* Инициализираме броячът  */
        broiach = 0;

        /* Цикъл, който обхожда целия низ, докато стигне \0 */    
        while(buf[broiach]){
            /* Тък като islower/isupper работят само с char, 
             * обхождаме целия низ символ по символ */
            tmp = buf[broiach];

            /* Ако символа е с малки букви ... */
            if(islower(tmp)){
                /* правим ги на ГОЛЕМИ БУКВИ. */
                buf[broiach] = toupper(buf[broiach]);
            }

            /* Ако символа е с ГОЛЕМИ БУКВИ ... */
            if(isupper(tmp)){
                /* ПРАВИМ ГИ НА малки букви. */
                buf[broiach] = tolower(buf[broiach]);
            }

            /* Отиваме на следващия символ */
            broiach++;
        }

        /* Отпечатваме конвертирания текст */
        printf("Конвертиран низ: %s\n", buf);
        /* Очакваме ново въвеждане */
        printf("Въведете текст за конвертиране: ");
    }
}