~ubuntu-branches/ubuntu/lucid/rsyslog/lucid-updates

« back to all changes in this revision

Viewing changes to tools/omfile.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2009-06-23 12:12:43 UTC
  • mfrom: (1.1.11 upstream) (3.2.8 sid)
  • Revision ID: james.westby@ubuntu.com-20090623121243-d2fejarzidywnn17
Tags: 4.2.0-1
* New upstream release of the now stable v4 branch.
  - Fix warnings when /etc/rsyslog.d/ is empty. Closes: #530228
* debian/patches/imudp_multiple_udp_sockets.patch
  - Removed, merged upstream.
* debian/rsyslog.default
  - Set default compat mode to '4'.
* debian/rsyslog.logcheck.ignore.server
  - Update logcheck rules files to also ignore rsyslogd and imklog stop
    messages.
* debian/control
  - Bump Standards-Version to 3.8.2. No further changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include <unistd.h>
45
45
#include <sys/file.h>
46
46
 
 
47
#ifdef OS_SOLARIS
 
48
#       include <fcntl.h>
 
49
#endif
 
50
 
47
51
#include "syslogd.h"
48
52
#include "syslogd-types.h"
49
53
#include "srUtils.h"
128
132
BEGINdbgPrintInstInfo
129
133
CODESTARTdbgPrintInstInfo
130
134
        if(pData->bDynamicName) {
131
 
                printf("[dynamic]\n\ttemplate='%s'"
 
135
                dbgprintf("[dynamic]\n\ttemplate='%s'"
132
136
                       "\tfile cache size=%d\n"
133
137
                       "\tcreate directories: %s\n"
134
138
                       "\tfile owner %d, group %d\n"
142
146
                        pData->bFailOnChown ? "yes" : "no"
143
147
                        );
144
148
        } else { /* regular file */
145
 
                printf("%s", pData->f_fname);
 
149
                dbgprintf("%s", pData->f_fname);
146
150
                if (pData->fd == -1)
147
 
                        printf(" (unused)");
 
151
                        dbgprintf(" (unused)");
148
152
        }
149
153
ENDdbgPrintInstInfo
150
154
 
174
178
        }
175
179
 
176
180
        iDynaFileCacheSize = iNewVal;
177
 
        dbgprintf("DynaFileCacheSize changed to %d.\n", iNewVal);
 
181
        DBGPRINTF("DynaFileCacheSize changed to %d.\n", iNewVal);
178
182
 
179
183
        RETiRet;
180
184
}
244
248
         */
245
249
        pData->f_sizeLimitCmd = (char*) pOch->cmdOnSizeLimit;
246
250
 
247
 
RUNLOG_VAR("%p", pszTplName);
248
251
        iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts,
249
252
                                       (pszTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pszTplName);
250
253
 
298
301
 
299
302
        free(pCmd);
300
303
 
301
 
        pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
 
304
        pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC,
302
305
                        pData->fCreateMode);
303
306
 
304
307
        actualFileSize = lseek(pData->fd, 0, SEEK_END);
327
330
        if(pCache[iEntry] == NULL)
328
331
                FINALIZE;
329
332
 
330
 
        dbgprintf("Removed entry %d for file '%s' from dynaCache.\n", iEntry,
 
333
        DBGPRINTF("Removed entry %d for file '%s' from dynaCache.\n", iEntry,
331
334
                pCache[iEntry]->pName == NULL ? "[OPEN FAILED]" : (char*)pCache[iEntry]->pName);
332
335
        /* if the name is NULL, this is an improperly initilized entry which
333
336
         * needs to be discarded. In this case, neither the file is to be closed
349
352
}
350
353
 
351
354
 
 
355
/* This function frees all dynamic file name cache entries and closes the
 
356
 * relevant files. Part of Shutdown and HUP processing.
 
357
 * rgerhards, 2008-10-23
 
358
 */
 
359
static inline void dynaFileFreeCacheEntries(instanceData *pData)
 
360
{
 
361
        register int i;
 
362
        ASSERT(pData != NULL);
 
363
 
 
364
        BEGINfunc;
 
365
        for(i = 0 ; i < pData->iCurrCacheSize ; ++i) {
 
366
                dynaFileDelCacheEntry(pData->dynCache, i, 1);
 
367
        }
 
368
        ENDfunc;
 
369
}
 
370
 
 
371
 
352
372
/* This function frees the dynamic file name cache.
353
373
 */
354
374
static void dynaFileFreeCache(instanceData *pData)
355
375
{
356
 
        register int i;
357
376
        ASSERT(pData != NULL);
358
377
 
359
378
        BEGINfunc;
360
 
        for(i = 0 ; i < pData->iCurrCacheSize ; ++i) {
361
 
                dynaFileDelCacheEntry(pData->dynCache, i, 1);
362
 
        }
363
 
 
 
379
        dynaFileFreeCacheEntries(pData);
364
380
        if(pData->dynCache != NULL)
365
381
                d_free(pData->dynCache);
366
382
        ENDfunc;
367
383
}
368
384
 
369
385
 
370
 
/* This is a shared code for both static and dynamic files.
 
386
/* This is now shared code for all types of files. It simply prepares
 
387
 * file access, which, among others, means the the file wil be opened
 
388
 * and any directories in between will be created (based on config, of
 
389
 * course). -- rgerhards, 2008-10-22
 
390
 * changed to iRet interface - 2009-03-19
371
391
 */
372
 
static void prepareFile(instanceData *pData, uchar *newFileName)
 
392
static rsRetVal
 
393
prepareFile(instanceData *pData, uchar *newFileName)
373
394
{
 
395
        DEFiRet;
 
396
        if(pData->fileType == eTypePIPE) {
 
397
                pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK|O_CLOEXEC);
 
398
                FINALIZE; /* we are done in this case */
 
399
        }
 
400
 
374
401
        if(access((char*)newFileName, F_OK) == 0) {
375
402
                /* file already exists */
376
 
                pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
 
403
                pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC,
377
404
                                pData->fCreateMode);
378
405
        } else {
379
406
                pData->fd = -1;
380
407
                /* file does not exist, create it (and eventually parent directories */
381
408
                if(pData->bCreateDirs) {
382
 
                        /* we fist need to create parent dirs if they are missing
 
409
                        /* We first need to create parent dirs if they are missing.
383
410
                         * We do not report any errors here ourselfs but let the code
384
411
                         * fall through to error handler below.
385
412
                         */
386
413
                        if(makeFileParentDirs(newFileName, strlen((char*)newFileName),
387
414
                             pData->fDirCreateMode, pData->dirUID,
388
415
                             pData->dirGID, pData->bFailOnChown) != 0) {
389
 
                                return; /* we give up */
 
416
                                ABORT_FINALIZE(RS_RET_ERR); /* we give up */
390
417
                        }
391
418
                }
392
419
                /* no matter if we needed to create directories or not, we now try to create
393
420
                 * the file. -- rgerhards, 2008-12-18 (based on patch from William Tisater)
394
421
                 */
395
 
                pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
 
422
                pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC,
396
423
                                pData->fCreateMode);
397
424
                if(pData->fd != -1) {
398
425
                        /* check and set uid/gid */
399
426
                        if(pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) {
400
427
                                /* we need to set owner/group */
401
 
                                if(fchown(pData->fd, pData->fileUID,
402
 
                                          pData->fileGID) != 0) {
 
428
                                if(fchown(pData->fd, pData->fileUID, pData->fileGID) != 0) {
403
429
                                        if(pData->bFailOnChown) {
404
430
                                                int eSave = errno;
405
431
                                                close(pData->fd);
413
439
                        }
414
440
                }
415
441
        }
 
442
finalize_it:
 
443
        /* this was "pData->fd != 0", which I think was a bug. I guess 0 was intended to mean
 
444
         * non-open file descriptor. Anyhow, I leave this comment for the time being to that if
 
445
         * problems surface, one at least knows what happened. -- rgerhards, 2009-03-19
 
446
         */
 
447
        if(pData->fd != -1 && isatty(pData->fd)) {
 
448
                DBGPRINTF("file %d is a tty file\n", pData->fd);
 
449
                pData->fileType = eTypeTTY;
 
450
                untty();
 
451
        }
 
452
 
 
453
        RETiRet;
416
454
}
417
455
 
418
456
 
431
469
        int i;
432
470
        int iFirstFree;
433
471
        dynaFileCacheEntry **pCache;
 
472
        
 
473
        BEGINfunc
434
474
 
435
475
        ASSERT(pData != NULL);
436
476
        ASSERT(newFileName != NULL);
486
526
                /* we need to allocate memory for the cache structure */
487
527
                pCache[iFirstFree] = (dynaFileCacheEntry*) calloc(1, sizeof(dynaFileCacheEntry));
488
528
                if(pCache[iFirstFree] == NULL) {
489
 
                        dbgprintf("prepareDynfile(): could not alloc mem, discarding this request\n");
 
529
                        DBGPRINTF("prepareDynfile(): could not alloc mem, discarding this request\n");
490
530
                        return -1;
491
531
                }
492
532
        }
493
533
 
494
534
        /* Ok, we finally can open the file */
495
 
        prepareFile(pData, newFileName);
 
535
        prepareFile(pData, newFileName); /* ignore exact error, we check fd below */
496
536
 
497
537
        /* file is either open now or an error state set */
498
538
        if(pData->fd == -1) {
500
540
                 * message. Otherwise, we could run into a never-ending loop. The bad
501
541
                 * news is that we also lose errors on startup messages, but so it is.
502
542
                 */
503
 
                if(iMsgOpts & INTERNAL_MSG)
504
 
                        dbgprintf("Could not open dynaFile, discarding message\n");
505
 
                else
 
543
                if(iMsgOpts & INTERNAL_MSG) {
 
544
                        DBGPRINTF("Could not open dynaFile, discarding message\n");
 
545
                } else {
506
546
                        errmsg.LogError(0, NO_ERRCODE, "Could not open dynamic file '%s' - discarding message", (char*)newFileName);
 
547
                }
507
548
                dynaFileDelCacheEntry(pCache, iFirstFree, 1);
508
549
                pData->iCurrElt = -1;
509
550
                return -1;
513
554
        pCache[iFirstFree]->pName = (uchar*)strdup((char*)newFileName); /* TODO: check for NULL (very unlikely) */
514
555
        pCache[iFirstFree]->lastUsed = time(NULL);
515
556
        pData->iCurrElt = iFirstFree;
516
 
        dbgprintf("Added new entry %d for file cache, file '%s'.\n",
517
 
                iFirstFree, newFileName);
 
557
        DBGPRINTF("Added new entry %d for file cache, file '%s'.\n", iFirstFree, newFileName);
 
558
 
 
559
        ENDfunc
518
560
 
519
561
        return 0;
520
562
}
527
569
static rsRetVal writeFile(uchar **ppString, unsigned iMsgOpts, instanceData *pData)
528
570
{
529
571
        off_t actualFileSize;
 
572
        int iLenWritten;
530
573
        DEFiRet;
531
574
 
532
575
        ASSERT(pData != NULL);
536
579
         */
537
580
        if(pData->bDynamicName) {
538
581
                if(prepareDynFile(pData, ppString[1], iMsgOpts) != 0)
539
 
                        ABORT_FINALIZE(RS_RET_ERR);
 
582
                        ABORT_FINALIZE(RS_RET_SUSPENDED); /* whatever the failure was, we need to retry */
 
583
        }
 
584
        
 
585
        if(pData->fd == -1) {
 
586
                rsRetVal iRetLocal;
 
587
                iRetLocal = prepareFile(pData, pData->f_fname);
 
588
                if((iRetLocal != RS_RET_OK) || (pData->fd == -1))
 
589
                        ABORT_FINALIZE(RS_RET_SUSPENDED); /* whatever the failure was, we need to retry */
540
590
        }
541
591
 
542
592
        /* create the message based on format specified */
572
622
                }
573
623
        }
574
624
 
575
 
        if (write(pData->fd, ppString[0], strlen((char*)ppString[0])) < 0) {
 
625
        iLenWritten = write(pData->fd, ppString[0], strlen((char*)ppString[0]));
 
626
//dbgprintf("lenwritten: %d\n", iLenWritten);
 
627
        if(iLenWritten < 0) {
576
628
                int e = errno;
577
 
 
578
 
                /* If a named pipe is full, just ignore it for now
579
 
                   - mrn 24 May 96 */
580
 
                if (pData->fileType == eTypePIPE && e == EAGAIN)
581
 
                        ABORT_FINALIZE(RS_RET_OK);
582
 
 
583
 
                /* If the filesystem is filled up, just ignore
584
 
                 * it for now and continue writing when possible
585
 
                 * based on patch for sysklogd by Martin Schulze on 2007-05-24
586
 
                 */
587
 
                if (pData->fileType == eTypeFILE && e == ENOSPC)
588
 
                        ABORT_FINALIZE(RS_RET_OK);
589
 
 
590
 
                (void) close(pData->fd);
591
 
                /*
592
 
                 * Check for EBADF on TTY's due to vhangup()
 
629
                char errStr[1024];
 
630
                rs_strerror_r(errno, errStr, sizeof(errStr));
 
631
                DBGPRINTF("log file (%d) write error %d: %s\n", pData->fd, e, errStr);
 
632
 
 
633
                /* If a named pipe is full, we suspend this action for a while */
 
634
                if(pData->fileType == eTypePIPE && e == EAGAIN)
 
635
                        ABORT_FINALIZE(RS_RET_SUSPENDED);
 
636
 
 
637
                close(pData->fd);
 
638
                pData->fd = -1; /* tell that fd is no longer open! */
 
639
                if(pData->bDynamicName && pData->iCurrElt != -1) {
 
640
                        /* in this case, we need to invalidate the name in the cache, too
 
641
                         * otherwise, an invalid fd may show up if we had a file name change.
 
642
                         * rgerhards, 2009-03-19
 
643
                         */
 
644
                        pData->dynCache[pData->iCurrElt]->fd = -1;
 
645
                }
 
646
                /* Check for EBADF on TTY's due to vhangup()
593
647
                 * Linux uses EIO instead (mrn 12 May 96)
594
648
                 */
595
 
                if ((pData->fileType == eTypeTTY || pData->fileType == eTypeCONSOLE)
 
649
                if((pData->fileType == eTypeTTY || pData->fileType == eTypeCONSOLE)
596
650
#ifdef linux
597
 
                        && e == EIO) {
 
651
                        && e == EIO
598
652
#else
599
 
                        && e == EBADF) {
 
653
                        && e == EBADF
600
654
#endif
601
 
                        pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_NOCTTY);
 
655
                        ) {
 
656
                        pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_NOCTTY|O_CLOEXEC);
602
657
                        if (pData->fd < 0) {
603
 
                                iRet = RS_RET_DISABLE_ACTION;
 
658
                                iRet = RS_RET_SUSPENDED;
604
659
                                errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname);
605
660
                        } else {
606
661
                                untty();
607
662
                                goto again;
608
663
                        }
609
664
                } else {
610
 
                        iRet = RS_RET_DISABLE_ACTION;
 
665
                        iRet = RS_RET_SUSPENDED;
611
666
                        errno = e;
612
667
                        errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname);
613
668
                }
641
696
 
642
697
BEGINdoAction
643
698
CODESTARTdoAction
644
 
        dbgprintf(" (%s)\n", pData->f_fname);
645
 
        /* pData->fd == -1 is an indicator that the we couldn't
646
 
         * open the file at startup. For dynaFiles, this is ok,
647
 
         * all others are doomed.
648
 
         */
649
 
        if(pData->bDynamicName || (pData->fd != -1))
650
 
                iRet = writeFile(ppString, iMsgOpts, pData);
 
699
        DBGPRINTF(" (%s)\n", pData->f_fname);
 
700
        iRet = writeFile(ppString, iMsgOpts, pData);
651
701
ENDdoAction
652
702
 
653
703
 
675
725
        } else {
676
726
                pData->bSyncFile = bEnableSync ? 1 : 0;
677
727
        }
678
 
 
679
728
        pData->f_sizeLimit = 0; /* default value, use outchannels to configure! */
680
729
 
681
730
        switch (*p)
693
742
                        pData->bDynamicName = 0;
694
743
                        pData->fCreateMode = fCreateMode; /* preserve current setting */
695
744
                        pData->fDirCreateMode = fDirCreateMode; /* preserve current setting */
696
 
                        pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
 
745
                        pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC,
697
746
                                         pData->fCreateMode);
698
747
                }
699
748
                break;
730
779
                if((pData->dynCache = (dynaFileCacheEntry**)
731
780
                    calloc(iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))) == NULL) {
732
781
                        iRet = RS_RET_OUT_OF_MEMORY;
733
 
                        dbgprintf("Could not allocate memory for dynaFileCache - selector disabled.\n");
 
782
                        DBGPRINTF("Could not allocate memory for dynaFileCache - selector disabled.\n");
734
783
                }
735
784
                break;
736
785
 
764
813
                pData->dirUID = dirUID;
765
814
                pData->dirGID = dirGID;
766
815
 
767
 
                if(pData->fileType == eTypePIPE) {
768
 
                        pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK);
769
 
                } else {
770
 
                        prepareFile(pData, pData->f_fname);
771
 
                }
 
816
                /* at this stage, we ignore the return value of prepareFile, this is taken
 
817
                 * care of in later steps. -- rgerhards, 2009-03-19
 
818
                 */
 
819
                prepareFile(pData, pData->f_fname);
772
820
                        
773
 
                if ( pData->fd < 0 ){
 
821
                if(pData->fd < 0 ) {
774
822
                        pData->fd = -1;
775
 
                        dbgprintf("Error opening log file: %s\n", pData->f_fname);
776
 
                        errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname);
 
823
                        DBGPRINTF("Error opening log file: %s\n", pData->f_fname);
 
824
                        errmsg.LogError(0, RS_RET_NO_FILE_ACCESS, "Could no open output file '%s'", pData->f_fname);
777
825
                        break;
778
826
                }
779
 
                if (isatty(pData->fd)) {
780
 
                        pData->fileType = eTypeTTY;
781
 
                        untty();
782
 
                }
783
 
                if (strcmp((char*) p, _PATH_CONSOLE) == 0)
 
827
                if(strcmp((char*) p, _PATH_CONSOLE) == 0)
784
828
                        pData->fileType = eTypeCONSOLE;
785
829
                break;
786
830
        default:
815
859
}
816
860
 
817
861
 
 
862
BEGINdoHUP
 
863
CODESTARTdoHUP
 
864
        if(pData->bDynamicName) {
 
865
                dynaFileFreeCacheEntries(pData);
 
866
                pData->iCurrElt = -1; /* invalidate current element */
 
867
        } else {
 
868
                if(pData->fd != -1) {
 
869
                        close(pData->fd);
 
870
                        pData->fd = -1;
 
871
                }
 
872
        }
 
873
ENDdoHUP
 
874
 
 
875
 
818
876
BEGINmodExit
819
877
CODESTARTmodExit
820
878
        if(pszTplName != NULL)
825
883
BEGINqueryEtryPt
826
884
CODESTARTqueryEtryPt
827
885
CODEqueryEtryPt_STD_OMOD_QUERIES
 
886
CODEqueryEtryPt_doHUP
828
887
ENDqueryEtryPt
829
888
 
830
889