The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Сетевой демон"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Сетевой демон"  
Сообщение от lytdybr email(ok) on 17-Окт-07, 18:47 
Имеется программка под винду - вызывается из ком. строки и отправляет конфигурацию компьютера на указанную машину. Требуется написать демона, который бы данные от нее принимал и писал в файл.
Затык произошел в том, что данные пишутся в файл в странном виде. Но это точно не кодировка: коверкаются все символы, даже латиница, а iconv выдает: iconv: illegal input sequence at position 737.
К тому же, когда я слежу за сетью сниффером - все выглядит нормально, то есть читабельным текстом.
Прошу помочь - не знаю где копать.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Сетевой демон"  
Сообщение от angra (ok) on 17-Окт-07, 18:55 
Вы что издеваетесь или действительно считаете всех способными на расстоянии прочитать ваш код, поток данных и результирующий файл?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Сетевой демон"  
Сообщение от lytdybr (ok) on 18-Окт-07, 11:43 
>Вы что издеваетесь или действительно считаете всех способными на расстоянии прочитать ваш
>код, поток данных и результирующий файл?

Виноват, протупил. Вот код. Использовал мануалы отсюда: http://symmetrica.net/unix-linux
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <signal.h>

int BecomeDaemonProcess (void);
int DoCleanup (void);
int ConfigureSignalHandlers (void);
int BindPassiveSocket (int, int *const);
int AcceptConnection (const int);
int HandleConnection (const int);
int WriteToSocket (const int, const char *const, const size_t);
int ReadLine (const int, char *const, const size_t, size_t *const);
void Handler (int);

volatile    sig_atomic_t    GracefulShutdown    = 0;
volatile    sig_atomic_t    HupSignalCaught        = 0;
const        char*            cApplicationName    = "Computer Configuration Storage Daemon";
const        char*            cLockFilePath        = "/var/run/ccsd.pid";
            char            cOutputBuffer[16];
            int                iLockFileDescriptor = -1;
            int                iResult;
            int                BlockSignals[]        = {SIGUSR2, SIGALRM, SIGPIPE, SIGTSTP, SIGPROF, SIGCHLD};
            int                HandleSignals[]        = {SIGUSR1, SIGHUP, SIGTERM, SIGILL, SIGTRAP, SIGQUIT, SIGABRT, SIGIOT, SIGBUS, SIGFPE, SIGSEGV, SIGSTKFLT, SIGCONT, SIGPWR, SIGSYS};
            int                gMasterSocket        = -1;
const        int                iListenPort            = 9997;
volatile    pid_t            DaemonPID;
volatile    int                iMaxFileDescriptors = 0;
struct        sigaction        SignalAction;
            sigset_t        SigMask;

int main (int argc, char *argv[])    {
    if (argc > 1)    {
        int fd, len;
        char pid_buf[16];
        
        if ((fd = open (cLockFilePath, O_RDONLY)) < 0)    {
            perror ("Couldn't find lock file");
            exit (fd);
        }
        
        len = read (fd, pid_buf, 16);
        syslog (LOG_LOCAL0|LOG_INFO, "%c", pid_buf);
        pid_buf [len] = 0;
        DaemonPID = atoi (pid_buf);
        
        if (!strcmp (argv[1], "stop"))    {
            syslog (LOG_LOCAL0|LOG_INFO, "Received STOP command - %d.", DaemonPID);
            kill (DaemonPID, SIGTERM);
            exit (EXIT_SUCCESS);
        }
        
        if (!strcmp (argv[1], "restart"))    {
            kill (DaemonPID, SIGHUP);
            exit (EXIT_SUCCESS);
        }
        
        printf ("Usage: %s [stop|restart]\n", argv[0]);
        exit (EXIT_FAILURE);
    }
    if ((iResult = BecomeDaemonProcess ()) < 0)    {
        perror ("Failed to deamonize.");
        unlink (cLockFilePath);
        exit (EXIT_FAILURE);
    }
    
    if ((iResult = ConfigureSignalHandlers()) < 0)    {
        perror ("Failed to configure signal handlers.");
        unlink (cLockFilePath);
        exit (EXIT_FAILURE);
    }
    
    if ((iResult = BindPassiveSocket(iListenPort, &gMasterSocket)) < 0)    {
        perror ("Failed to bind passive socket.");
        unlink (cLockFilePath);
        exit (EXIT_FAILURE);
    }
    
    do {
        //action
        if ((AcceptConnection (gMasterSocket)) < 0)    {
            syslog (LOG_LOCAL0|LOG_INFO, "AcceptConnection failed, ERROR #%d", errno);
            unlink (cLockFilePath);
            exit (EXIT_FAILURE);
        }
        if ((GracefulShutdown == 1) && (HupSignalCaught == 0))    {
            break;
        }
        
        GracefulShutdown = HupSignalCaught = 0;
    } while (1);
}

int BecomeDaemonProcess (void)    {
    char cPIDString[7];
    int iCurrentPID;
    int LockResult;
    int i, j, k;
    struct flock Lock;
    
    iMaxFileDescriptors = sysconf (_SC_OPEN_MAX);
    
    switch (iCurrentPID = fork ())    {
        case 0:
            //Child process
            break;
        case -1:
            fprintf (stderr, "Error: initial fork failed: %s\n", strerror (errno));
            return -1;
            break;
        default:
            exit (0);
            break;
    }
    
    //umask (0);
    DaemonPID = (int) getpid();
    sprintf (cPIDString, "%d\n", DaemonPID);
    openlog (cApplicationName, LOG_NOWAIT, LOG_LOCAL0);
    if ((iLockFileDescriptor = creat (cLockFilePath, 0644)) < 0)    {
        syslog (LOG_LOCAL0|LOG_INFO, "Couldn't open lock file, ERROR #%d", errno);
        return EXIT_FAILURE;
    }
    
    Lock.l_type = F_WRLCK;
    Lock.l_whence = SEEK_SET;
    Lock.l_start = Lock.l_start = 0;
    Lock.l_pid = 0;
    
    if ((LockResult = fcntl (iLockFileDescriptor, F_SETLK, &Lock)) < 0)    {
        syslog (LOG_LOCAL0|LOG_INFO, "Couldn't set lock to file %s, ERROR #%d", cLockFilePath, errno);
    }
    
    if (write (iLockFileDescriptor, cPIDString, strlen(cPIDString)) <= 0)    {
        syslog (LOG_LOCAL0|LOG_INFO, "Couldn't write PID to lock file, ERROR #%d", errno);
    }
    
    if (setsid () < 0)    {
        syslog (LOG_LOCAL0|LOG_INFO, "Couldn't get session ID (SID) from Kernel, ERROR #%d", errno);
        return EXIT_FAILURE;
    }
    
    if (chdir ("/") < 0)    {
        syslog (LOG_LOCAL0|LOG_INFO, "Couldn't change directory to /, ERROR #%d", errno);
        return EXIT_FAILURE;
    }

    // Specific Daemon Initialization
    
    syslog (LOG_LOCAL0|LOG_INFO, "Started with PID #%d", DaemonPID);
    
    return EXIT_SUCCESS;
}

int DoCleanup (void)    {
    int i, j, k;
    
    for (i = 0; i <= iMaxFileDescriptors; i++)    {
        if (i != iLockFileDescriptor)    {
            close (i);
        }
    }
    
    
    // TODO: Add socket close
    
    closelog ();
}

int ConfigureSignalHandlers (void)    {
    int i, j, k;

    sigemptyset (&SigMask);
    for (i = 0; i < 7; i++)    {
        sigaddset (&SigMask, *(BlockSignals + i));
    }
    
    SignalAction.sa_handler = Handler;
    SignalAction.sa_mask    = SigMask;
    SignalAction.sa_flags    = 0;
    sigaction (SIGUSR1, &SignalAction, NULL);
    for (i = 0; i < 16; i++)    {
        sigaction (*(HandleSignals + i), &SignalAction, NULL);
    }
    return EXIT_SUCCESS;
}

void Handler (int Signal)    {
    syslog  (LOG_LOCAL0|LOG_INFO, "Received signal %d", Signal);
    switch (Signal)    {
        case SIGUSR1:
            syslog (LOG_LOCAL0|LOG_INFO, "Stopped gracefully");
            GracefulShutdown = 1;
            break;
        case SIGHUP:
            syslog (LOG_LOCAL0|LOG_INFO, "HUP signal caught");
            GracefulShutdown = HupSignalCaught = 1;
            break;
        case SIGTERM:
            DoCleanup();
            exit (EXIT_SUCCESS);
            break;
        default:
            #ifdef _GNU_SOURCE
            syslog (LOG_LOCAL0|LOG_INFO, "Caught signal %s - exiting", strsignal(Signal));
            #else
            syslog (LOG_LOCAL0|LOG_INFO, "Caught signal %d - exiting", Signal);
            #endif
            DoCleanup ();
            exit (0);
            break;
    }
}

int BindPassiveSocket (int Port, int *const BoundSocket)    {
    struct sockaddr_in            SocketAddrIn;
    int                            Socket, OptionValue;
    size_t                        OptionLength;
    
    memset (&SocketAddrIn.sin_zero, 0, 8);
    
    SocketAddrIn.sin_port = htons (Port);
    SocketAddrIn.sin_family = AF_INET;
    SocketAddrIn.sin_addr.s_addr = htonl (INADDR_ANY);
    
    if ((Socket = socket (PF_INET, SOCK_STREAM, 0)) < 0)    {
        return -1;
    }
    
    OptionValue = 1;
    OptionLength = sizeof(int);
    
    setsockopt (Socket, SOL_SOCKET, SO_REUSEADDR, &OptionValue, OptionLength);
    if ((bind (Socket, (struct sockaddr *)&SocketAddrIn, sizeof (struct sockaddr_in))) < 0)    {
        return -1;
    }
    
    if ((listen (Socket, SOMAXCONN)) < 0)    {
        return -1;
    }
    
    *BoundSocket = Socket;
    
    return 0;
}

int AcceptConnection (const int Master)    {
    int                    Proceed = 1, Slave, ReturnValue = 0;
    struct sockaddr_in    Client;
    socklen_t            ClientLength;
    
    while ((Proceed == 1) && (GracefulShutdown == 0))    {
        ClientLength = sizeof (Client);
        Slave = accept (Master, (struct sockaddr *)&Client, &ClientLength);
        
        if (Slave < 0)    {
            if (errno == EINTR)    {
                continue;
            }
            syslog (LOG_LOCAL0|LOG_INFO, "accept() failed: %m\n");
            Proceed = 0;
            ReturnValue = -1;
        } else {
            ReturnValue = HandleConnection (Slave);
            if (ReturnValue)    {
                Proceed = 0;
            }
        }
    }
    
    return ReturnValue;
}

int HandleConnection (const int Slave)    {
    char                ReadBuffer[1025];
    const char *                DataFile = "/home/nikitad/cppapp/data.txt";
    size_t                BytesRead;
    const size_t        BufferLength = 1025;
    int                    ReturnValue;
    int                    DataFileDescr;
    
    DataFileDescr = open (DataFile, O_WRONLY|O_CREAT);
    ReturnValue = ReadLine (Slave, ReadBuffer, BufferLength, &BytesRead);
    if ((write (DataFileDescr, ReadBuffer, BufferLength)) < 0)    {
        syslog (LOG_LOCAL0|LOG_INFO, "Couldn't write data to file, ERROR #%d: %s", errno, strerror (errno));
    }
    
    if (ReturnValue == 0)    {
        WriteToSocket (Slave, ReadBuffer, BytesRead);
    }
    
    return ReturnValue;
}

int ReadLine (const int Socket, char *const Buffer, const size_t Length, size_t *const Read)    {
    int                 Done = 0, ReturnValue = 0;
    char                Character, LastCharacter = 0;
    size_t                BytesSoFar = 0;
    ssize_t                ReadResult;
    
    do    {
        ReadResult = recv (Socket, &Character, 1, 0);
        
        switch (ReadResult)    {
                case -1:
                if (errno = EINTR)    {
                    Done = 1;
                    ReturnValue = -1;
                }
                break;
            case 0:
                Done = 1;
                ReturnValue = 0;
                break;
            case 1:
                Buffer[BytesSoFar] = Character;
                BytesSoFar += ReadResult;
                
                if (BytesSoFar >= Length)    {
                    Done = 1;
                    ReturnValue = -1;
                }
                
                if ((Character == '\n') && (LastCharacter == '\r'))    {
                    Done = 1;
                }
                
                LastCharacter = Character;
                break;
        }
    } while (!Done);
    
    Buffer[BytesSoFar] = 0;
    *Read = BytesSoFar;
    
    return ReturnValue;
}

int WriteToSocket (const int Socket, const char *const Buffer, const size_t Length)    {
    size_t                BytesWritten = 0;
    ssize_t                WriteResult;
    int                    ReturnValue = 0, Done = 0;
    
    do    {
        WriteResult = send (Socket, Buffer + BytesWritten, Length - BytesWritten, 0);
        if (WriteResult == -1)    {
            if (errno == EINTR)    {
                WriteResult = 0;
            } else {
                Done = 1;
                ReturnValue = 1;
            }
        } else {
            BytesWritten += WriteResult;
            if (WriteResult = 0)    {
                Done = 1;
            }
        }
    } while (!Done);
    
    return ReturnValue;
}

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Сетевой демон"  
Сообщение от jd (??) on 19-Окт-07, 07:08 
* Аплодирую стоя автору этого кода. (равно как и автору поста)...

Это наверное самая сложная реализация такой простой задачи, которую только мог родить человеческий мозг.

По существу же:

> ReturnValue = ReadLine (Slave, ReadBuffer, BufferLength, &BytesRead);
> if ((write (DataFileDescr, ReadBuffer, BufferLength)) < 0) {

Тут нужно использовать в качестве третьего агрумента write(2) не BufferLength, а BytesRead. Тогда всё будет в порядке: HandleConnection() читает одну(!) строчку и записывает её в файл - всё, как написано и результат (приведённый вами ниже) это подтверждает. Остальная часть записанного файла - просто мусор из оперативной памяти.

NOTE: То, что вам что-то ответили (я имею в виду этот ответ) - это скорее всего чистая случайность. Просто мне было немного скучно и я решил почитать этот огромный и бестолковый код. Ничего личного.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Сетевой демон"  
Сообщение от lytdybr (ok) on 19-Окт-07, 15:38 
>[оверквотинг удален]
>Тут нужно использовать в качестве третьего агрумента write(2) не BufferLength, а BytesRead.
>Тогда всё будет в порядке: HandleConnection() читает одну(!) строчку и записывает
>её в файл - всё, как написано и результат (приведённый вами
>ниже) это подтверждает. Остальная часть записанного файла - просто мусор из
>оперативной памяти.
>
>NOTE: То, что вам что-то ответили (я имею в виду этот ответ)
>- это скорее всего чистая случайность. Просто мне было немного скучно
>и я решил почитать этот огромный и бестолковый код. Ничего личного.
>

Да ничего, хорошо что сказал, ибо я подозревал, что тут афтор перемудрил. Сейчас буду переделывать чтобы выглядело не так страшно.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Сетевой демон"  
Сообщение от lytdybr (ok) on 18-Окт-07, 11:49 
Файл.
[General]
��������ܐ�5��qZ�������ܐ�hܐ��ܐ�3
�������ݐ�E��qZ���ܐ������qZ������4����

�����ܐ�m?�������ݐ�7���ݐ�,���,����� ݐ�
�z��hݐ�y����<���<��                           ��/�<��ii
                     ����#F�������ݐ�B�����������я췀��ݐ��ݐ��ސ�à=Xû·   (\æ·°     €ˆø·�   ”±           í  ¨û·Xû·ç·¨çæ·ø≥æ·   ô¿ü·û·œÞ�¿ôïù·│   HÞ│Ìæ·„Þ�¿≤«û·Ô<ç·Å†¹Éü·¬Éü·8û· �¿␋üû·├…¸Éü·ô¿ü·      äÞ�¿ôïù·Ï†␋␋
                                                û·  ß�¿B¯û·␋üû·├…¸Éü·ô¿ü·   ┐Å ÔÞ�¿ÔÞ�¿Äß�¿µéZñXû·   (\æ·\Uæ·ôÞ�¿´éZñäß�¿FX78��X��u���������������ߐ��ߐ������ߐ�<���8�����ߐ�<���8���ߐ����������u� ����Z� �������S�FX7!@8���ߐ�ա��H���X��N�x���X������������������R�������u���x�����������x���C��d���x���

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Сетевой демон"  
Сообщение от phpcoder email(??) on 18-Окт-07, 11:08 
>iconv: illegal input sequence at position 737

iconv так обычно жалуется когда в одной локали нет символов из другой. Например, в cp1251 есть специальные ёлочные кавычки, а в koi8-r их нет. Соответственно он не знает как перекодировать. Помогает ключик -c, обычно (или '-r ?').

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру