Browse Source

Add ./tarball_archive/symon-2.84.tar.gz

Wictor Lund 3 years ago
parent
commit
6d9ce55f7d

+ 13 - 2
symon/CHANGELOG

@@ -1,3 +1,16 @@
+14/01/2012 - 2.84
+
+   - platform/Linux/disk probes now handles '/' in arguments (Bostjan Skufca)
+
+   - platform/FreeBSD/disk probes now allow args not in '/dev' (Edho Arief),
+     and support diskname by ufs name, ufs id, gpt id.
+
+   - platform/FreeBSD/sm_mem.c: sysctl call could overwrite swap count (Edho
+     Arief)
+
+   - platform/NetBSD/Makefile.inc: update linker flags for finding librrd in
+     /usr/pkg
+
 01/05/2011 - 2.83
 
    - Added flukso probe
@@ -292,8 +305,6 @@
 
    - Added initial support for Linux: cpu and if.
 
-   - Textual: INSTALL (Hiddo Hut)
-
    - Removed net_iso from symon.c (Hans Kremers)
 
    - Time since last update gets checked in symon.c to ensure correct

+ 1 - 1
symon/Makefile.inc

@@ -1,4 +1,4 @@
-V=2.83
+V=2.84
 
 AR?=	ar
 CC?=	cc

+ 1 - 1
symon/lib/Makefile

@@ -5,7 +5,7 @@ OS!=uname -s
 SRCSsym=   	error.c lex.c xmalloc.c net.c data.c
 OBJSsym+=	${SRCSsym:R:S/$/.o/g}
 
-SRCSprobe=      percentages.c smart.c
+SRCSprobe=      diskbyname.c percentages.c smart.c
 OBJSprobe+=     ${SRCSprobe:R:S/$/.o/g}
 
 CFLAGS+=-I../platform/${OS} -I.

+ 15 - 11
symon/platform/Linux/diskbyname.c → symon/lib/diskbyname.c

@@ -32,6 +32,7 @@
 #include <sys/types.h>
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <string.h>
 #include <strings.h>
@@ -60,6 +61,7 @@ checkdisk(const char *spath, char *dpath, size_t maxlen)
         return 0;
     }
 
+    /* Walk one link, if it is there */
     if (S_ISLNK(buffer.st_mode)) {
         if ((r = realpath(spath, NULL))) {
             strlcpy(diskname, r, sizeof(diskname));
@@ -72,7 +74,12 @@ checkdisk(const char *spath, char *dpath, size_t maxlen)
     } else
         strlcpy(diskname, spath, sizeof(diskname));
 
-    if (S_ISBLK(buffer.st_mode) && !S_ISLNK(buffer.st_mode)) {
+    /*
+     * No more links from here; also note the lack of further checks on the
+     * stat structure. For linux we should now be looking at a block device,
+     * for FreeBSD this should be a character device.
+     */
+    if (!S_ISLNK(buffer.st_mode)) {
         result = strlcpy(dpath, diskname, maxlen);
         return result;
     }
@@ -86,27 +93,24 @@ checkdisk(const char *spath, char *dpath, size_t maxlen)
  * Resolve a logical disk name <spath> to it's block device name
  * <dpath>. <dpath> is preallocated and can hold <maxlen> characters. <spath>
  * can refer to a disk via 1) an absolute path or 2) a diskname relative to
- * /dev, or 3) a diskname relative to the /dev/disk/by-* directories.
+ * /dev in various forms defined in platform specific DISK_PATHS.
  */
 size_t
 diskbyname(const char *spath, char *dpath, size_t maxlen)
 {
     char diskname[MAX_PATH_LEN];
     size_t size;
-    char *l[] = {
-        "/dev/%s",
-        "/dev/disk/by-id/%s",
-        "/dev/disk/by-label/%s",
-        "/dev/disk/by-uuid/%s",
-        "/dev/disk/by-path/%s",
-        NULL
-    };
+#ifdef DISK_PATHS
+    char *l[] =  DISK_PATHS;
+#else
+    char *l[] = { "/dev/%s", NULL };
+#endif
     int i;
 
     if (spath == NULL)
         return 0;
 
-    if (strchr(spath, '/'))
+    if (strchr(spath, '/') == spath)
         return checkdisk(spath, dpath, maxlen);
 
     for (i = 0; l[i] != NULL; i++) {

+ 5 - 0
symon/lib/diskbyname.h

@@ -0,0 +1,5 @@
+#ifndef _SYMON_LIB_DISKBYNAME_H
+#define _SYMON_LIB_DISKBYNAME_H
+size_t
+diskbyname(const char *spath, char *dpath, size_t maxlen);
+#endif /* _SYMON_LIB_DISKBYNAME_H */

+ 4 - 0
symon/platform/FreeBSD/platform.h

@@ -6,6 +6,7 @@
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/dkstat.h>
+#include <sys/param.h>
 #include <sys/resource.h>
 
 #include <net/if.h>
@@ -18,6 +19,9 @@
 #define SA_LEN(x)       ((x)->sa_len)
 #define SS_LEN(x)       ((x)->ss_len)
 
+#define DISK_PATHS { "/dev/%s", "/dev/ufs/%s", "/dev/ufsid/%s", "/dev/gpt/%s", NULL }
+#define MAX_PATH_LEN MAXPATHLEN
+
 union stream_parg {
     struct {
         long time1[CPUSTATES];

+ 21 - 3
symon/platform/FreeBSD/sm_df.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2005 Marc Balmer
+ * Copyright (c) 2012 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,6 +53,7 @@
 
 #include "error.h"
 #include "symon.h"
+#include "diskbyname.h"
 
 /* Globals for this module start with df_ */
 static struct statfs *df_stats = NULL;
@@ -60,10 +62,26 @@ static int df_parts = 0;
 void
 init_df(struct stream *st)
 {
-    strlcpy(st->parg.df.rawdev, "/dev/", sizeof(st->parg.df.rawdev));
-    strlcat(st->parg.df.rawdev, st->arg, sizeof(st->parg.df.rawdev));
+    int n;
+    char drivename[SYMON_DFNAMESIZE];
+
+    if (st->arg == NULL)
+        fatal("df: need a <disk device|name> argument");
+
+    if (diskbyname(st->arg, drivename, sizeof(drivename)) == 0)
+        fatal("df: '%.200s' is not a disk device", st->arg);
 
-    info("started module df(%.200s)", st->arg);
+    gets_df();
+
+    for (n = 0; n < df_parts; n++) {
+        if (!strncmp(df_stats[n].f_mntfromname, drivename, SYMON_DFNAMESIZE)) {
+            strlcpy(st->parg.df.rawdev, drivename, sizeof(st->parg.df.rawdev));
+            info("started module df(%.200s)", st->arg);
+            return;
+        }
+    }
+
+    warning("df(%.200s) failed (no such device)", st->arg);
 }
 
 void

+ 29 - 2
symon/platform/FreeBSD/sm_io.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2005 J. Martin Petersen
+ * Copyright (c) 2012 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,6 +54,7 @@
 
 #include "error.h"
 #include "symon.h"
+#include "diskbyname.h"
 
 static struct statinfo io_stats;
 static int io_numdevs = 0;
@@ -66,13 +68,38 @@ privinit_io()
 void
 init_io(struct stream *st)
 {
+    unsigned int i;
+    struct devstat *ds;
+    char drivename[MAX_PATH_LEN];
+
+    if (st->arg == NULL)
+        fatal("io: need a <device>|<devicename> argument");
+
+    if (diskbyname(st->arg, drivename, MAX_PATH_LEN) == 0)
+        fatal("io: '%.200s' is not a <device>|<devicename>", st->arg);
+
     io_stats.dinfo = malloc(sizeof(struct devinfo));
     if (io_stats.dinfo == NULL) {
         fatal("io: could not allocate memory");
     }
 
     io_stats.dinfo->mem_ptr = NULL;
-    info("started module io(%.200s)", st->arg);
+
+    gets_io();
+
+    for (i = 0; i < io_numdevs; i++) {
+        ds = &io_stats.dinfo->devices[i];
+
+        if (strncmp(ds->device_name, st->arg, strlen(ds->device_name)) == 0 &&
+            strlen(ds->device_name) < strlen(st->arg) &&
+            isdigit(st->arg[strlen(ds->device_name)]) &&
+            atoi(&st->arg[strlen(ds->device_name)]) == ds->unit_number) {
+            info("started module io(%.200s)", st->arg);
+            return;
+        }
+    }
+
+    warning("io(%.200s): not found", st->arg);
 }
 
 void
@@ -108,7 +135,7 @@ get_io(char *symon_buf, int maxlen, struct stream *st)
     unsigned int i;
     struct devstat *ds;
 
-    for (i=0; i < io_numdevs; i++) {
+    for (i = 0; i < io_numdevs; i++) {
         ds = &io_stats.dinfo->devices[i];
 
         if (strncmp(ds->device_name, st->arg, strlen(ds->device_name)) == 0 &&

+ 4 - 4
symon/platform/FreeBSD/sm_mem.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004      Matthew Gream
- * Copyright (c) 2001-2008 Willem Dijkstra
+ * Copyright (c) 2001-2012 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,12 +111,12 @@ void
 gets_mem()
 {
 #ifdef HAS_XSWDEV
-    int i;
     u_int vmnswp_dat;
-    size_t vmnswp_siz;
+    u_long vmnswp_siz;
+    int i;
 #endif
     u_long physmem_dat;
-    size_t physmem_siz;
+    u_long physmem_siz;
 
     bzero(&me_vmtotal, sizeof(me_vmtotal));
 

+ 8 - 7
symon/platform/FreeBSD/sm_smart.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Willem Dijkstra
+ * Copyright (c) 2009-2012 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 #include "error.h"
 #include "xmalloc.h"
 #include "smart.h"
+#include "diskbyname.h"
 
 #ifdef HAS_IOCATAREQUEST
 #ifndef HAS_ATA_SMART_CMD
@@ -51,7 +52,7 @@
 #endif
 /* per drive storage structure */
 struct smart_device {
-    char name[MAXPATHLEN];
+    char name[MAX_PATH_LEN];
     int fd;
     int type;
     int failed;
@@ -66,7 +67,7 @@ void
 init_smart(struct stream *st)
 {
     int i;
-    char drivename[MAXPATHLEN];
+    char drivename[MAX_PATH_LEN];
     struct ata_ioc_request *p;
 
     if (sizeof(struct smart_values) != DISK_BLOCK_LEN) {
@@ -77,12 +78,12 @@ init_smart(struct stream *st)
         fatal("smart: need a <device> argument");
     }
 
-    bzero(drivename, MAXPATHLEN);
-    snprintf(drivename, MAXPATHLEN, "/dev/%s", st->arg);
+    if (diskbyname(st->arg, drivename, sizeof(drivename)) == 0)
+        fatal("smart: '%.200s' is not a disk device", st->arg);
 
     /* look for drive in our global table */
     for (i = 0; i < smart_cur; i++) {
-        if (strncmp(smart_devs[i].name, drivename, MAXPATHLEN) == 0) {
+        if (strncmp(smart_devs[i].name, drivename, MAX_PATH_LEN) == 0) {
             st->parg.smart = i;
             return;
         }
@@ -104,7 +105,7 @@ init_smart(struct stream *st)
     }
 
     /* store drivename in new block */
-    snprintf(smart_devs[smart_cur].name, MAXPATHLEN, "%s", drivename);
+    snprintf(smart_devs[smart_cur].name, MAX_PATH_LEN, "%s", drivename);
 
     /* populate ata command header */
     p = &smart_devs[smart_cur].cmd;

+ 1 - 3
symon/platform/Linux/Makefile.inc

@@ -7,6 +7,4 @@ BINDIR?=bin
 
 INSTALLUSER?=root
 INSTALLGROUPFILE?=bin
-INSTALLGROUPDIR?=bin
-
-PLATFORM_SRC=diskbyname.c
+INSTALLGROUPDIR?=bin

+ 1 - 3
symon/platform/Linux/platform.h

@@ -42,6 +42,7 @@ union semun {
 #define CP_STEAL     7
 
 #define MAX_PATH_LEN       1024
+#define DISK_PATHS         { "/dev/%s", "/dev/disk/by-id/%s", "/dev/disk/by-label/%s", "/dev/disk/by-uuid/%s", "/dev/disk/by-path/%s", NULL }
 #define DISK_BLOCK_LEN     512
 
 #define SENSOR_FAN       0
@@ -75,7 +76,4 @@ union stream_parg {
     char io[MAX_PATH_LEN];
 };
 
-extern size_t
-diskbyname(const char *spath, char *dpath, size_t maxlen);
-
 #endif

+ 3 - 2
symon/platform/Linux/sm_df.c

@@ -47,6 +47,7 @@
 #include "conf.h"
 #include "error.h"
 #include "symon.h"
+#include "diskbyname.h"
 
 void
 init_df(struct stream *st)
@@ -61,7 +62,7 @@ init_df(struct stream *st)
     if (st->arg == NULL)
         fatal("df: need a <disk device|name> argument");
 
-    if ((diskbyname(st->arg, drivename, sizeof(drivename)) == 0))
+    if (diskbyname(st->arg, drivename, sizeof(drivename)) == 0)
         fatal("df: '%.200s' is not a disk device", st->arg);
 
     while ((mount = getmntent(fp))) {
@@ -75,7 +76,7 @@ init_df(struct stream *st)
 
     endmntent(fp);
 
-    fatal("df(.200s): not mounted", st->arg);
+    warning("df(%.200s): not mounted", st->arg);
 }
 
 void

+ 2 - 1
symon/platform/Linux/sm_io.c

@@ -49,6 +49,7 @@
 #include "xmalloc.h"
 #include "error.h"
 #include "symon.h"
+#include "diskbyname.h"
 
 /* Globals for this module start with io_ */
 static void *io_buf = NULL;
@@ -90,7 +91,7 @@ init_io(struct stream *st)
     if (st->arg == NULL)
         fatal("io: need a <device>|<devicename> argument");
 
-    if ((diskbyname(st->arg, &st->parg.io[0], MAX_PATH_LEN) == 0))
+    if (diskbyname(st->arg, &st->parg.io[0], MAX_PATH_LEN) == 0)
         fatal("io: '%.200s' is not a <device>|<devicename>", st->arg);
 
     /* devices are named sdX, not /dev/sdX */

+ 2 - 1
symon/platform/Linux/sm_smart.c

@@ -44,6 +44,7 @@
 #include "error.h"
 #include "xmalloc.h"
 #include "smart.h"
+#include "diskbyname.h"
 
 #ifndef HAS_HDDRIVECMDHDR
 typedef unsigned char task_ioreg_t;
@@ -95,7 +96,7 @@ init_smart(struct stream *st)
     if (st->arg == NULL)
         fatal("smart: need a <disk device|name> argument");
 
-    if ((diskbyname(st->arg, drivename, sizeof(drivename)) == 0))
+    if (diskbyname(st->arg, drivename, sizeof(drivename)) == 0)
         fatal("smart: '%.200s' is not a disk device", st->arg);
 
     /* look for drive in our global table */

+ 1 - 1
symon/platform/NetBSD/Makefile.inc

@@ -1,2 +1,2 @@
 RRDDIR?=/usr/pkg
-LIBS=-lutil
+LIBS=-lutil -Wl -R${RRDDIR}/lib

+ 3 - 1
symon/platform/NetBSD/platform.h

@@ -6,6 +6,7 @@
 #include <sys/queue.h>
 #include <sys/sched.h>
 #include <sys/types.h>
+#include <sys/param.h>
 
 #include <net/if.h>
 
@@ -22,7 +23,8 @@ union semun {
         int val;
 };
 
-#define MAX_PATH_LEN FILENAME_MAX
+#define MAX_PATH_LEN MAXPATHLEN
+
 union stream_parg {
     struct {
         int64_t time[CPUSTATES];

+ 10 - 2
symon/platform/NetBSD/sm_df.c

@@ -51,6 +51,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "diskbyname.h"
 #include "error.h"
 #include "symon.h"
 
@@ -61,8 +62,15 @@ static int df_parts = 0;
 void
 init_df(struct stream *st)
 {
-    strlcpy(st->parg.df.rawdev, "/dev/", sizeof(st->parg.df.rawdev));
-    strlcat(st->parg.df.rawdev, st->arg, sizeof(st->parg.df.rawdev));
+    char drivename[MAX_PATH_LEN];
+
+    if (st->arg == NULL)
+        fatal("io: need a <disk device|name> argument");
+
+    if (diskbyname(st->arg, drivename, sizeof(drivename)) == 0)
+        fatal("io: '%.200s' is not a disk device", st->arg);
+
+    strlcpy(st->parg.df.rawdev, drivename, sizeof(st->parg.df.rawdev));
 
     info("started module df(%.200s)", st->arg);
 }

+ 1 - 1
symon/platform/NetBSD/sm_io.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007      Willem Dijkstra
+ * Copyright (c) 2007-2012 Willem Dijkstra
  * Copyright (c) 2004      Matthew Gream
  * All rights reserved.
  *

+ 14 - 25
symon/platform/NetBSD/sm_smart.c

@@ -46,6 +46,7 @@
 #include "error.h"
 #include "xmalloc.h"
 #include "smart.h"
+
 /* ata command register set for requesting smart values */
 static struct atareq smart_cmd = {
   ATACMD_READ, /* flags */
@@ -69,16 +70,13 @@ static struct smart_device {
     int type;
     int failed;
     struct smart_values data;
-};
-
-static struct smart_device *smart_devs = NULL;
+} *smart_devs = NULL;
 static int smart_size = 0;
 
 void
 init_smart(struct stream *st)
 {
     int i;
-    char drivename[MAX_PATH_LEN];
     struct smart_device *sd;
 
     if (sizeof(struct smart_values) != DISK_BLOCK_LEN) {
@@ -89,12 +87,9 @@ init_smart(struct stream *st)
         fatal("smart: need a <device> argument");
     }
 
-    bzero(drivename, MAX_PATH_LEN);
-    snprintf(drivename, MAX_PATH_LEN, "/dev/%s", st->arg);
-
     /* look for drive in our global table */
     for (i = 0; i < smart_size; i++) {
-        if (strncmp(smart_devs[i].name, drivename, MAX_PATH_LEN) == 0) {
+        if (strncmp(smart_devs[i].name, st->arg, MAX_PATH_LEN) == 0) {
             st->parg.smart = i;
             return;
         }
@@ -106,22 +101,18 @@ init_smart(struct stream *st)
     sd = &smart_devs[smart_size - 1];
     bzero(sd, sizeof(struct smart_device));
 
-    /* rewire all bufferlocations, as our addresses may have changed */
-    for (i = 0; i < smart_size; i++)
-        smart_devs[i].cmd.databuf = (caddr_t)&smart_devs[i].data;
-
     /* store drivename in new block */
-    snprintf(sd->name, MAX_PATH_LEN, "%s", drivename);
+    snprintf(sd->name, MAX_PATH_LEN, "%s", st->arg);
 
     /* store filedescriptor to device */
-    if ((sd->fd = opendisk(drivename, O_RDONLY | O_NONBLOCK, sd->name, sizeof(sd->name), 0)) == -1) {
+    if ((sd->fd = opendisk(st->arg, O_RDONLY | O_NONBLOCK, sd->name, sizeof(sd->name), 0)) == -1) {
         if (errno == ENOENT) {
             /* Device does not exist, retry using cooked name semantics */
-            if ((sd->fd = opendisk(drivename, O_RDONLY | O_NONBLOCK, sd->name, sizeof(sd->name), 1)) == -1) {
-                fatal("smart: could not open '%s' for read", drivename);
+            if ((sd->fd = opendisk(st->arg, O_RDONLY | O_NONBLOCK, sd->name, sizeof(sd->name), 1)) == -1) {
+                fatal("smart: could not open '%s' for read", st->arg);
             }
         } else {
-            fatal("smart: could not open '%s' for read", drivename);
+            fatal("smart: could not open '%s' for read", st->arg);
         }
     }
 
@@ -141,15 +132,15 @@ gets_smart()
         /* populate ata command header */
         memcpy(&cmd, (void *) &smart_cmd, sizeof(struct atareq));
         cmd.databuf = (caddr_t)&smart_devs[i].data;
-        
-        if (ioctl(smart_devs[i].fd, ATAIOCCOMMAND, &smart_devs[i].cmd)) {
+
+        if (ioctl(smart_devs[i].fd, ATAIOCCOMMAND, &cmd)) {
             warning("smart: ioctl for drive '%s' failed: %d",
                     &smart_devs[i].name, errno);
             smart_devs[i].failed = 1;
         }
 
         /* check ATA command completion status */
-        switch (smart_devs[i].cmd.retsts) {
+        switch (cmd.retsts) {
             case ATACMD_OK:
                 break;
             case ATACMD_TIMEOUT:
@@ -161,14 +152,14 @@ gets_smart()
                 smart_devs[i].failed = 1;
                 break;
             case ATACMD_ERROR:
-                if (smart_devs[i].cmd.error & WDCE_ABRT)
+                if (cmd.error & WDCE_ABRT)
                     warning("smart: ATA device '%s' returned Aborted Command", &smart_devs[i].name);
                 else
-                    warning("smart: ATA device '%s' returned error register %0x", &smart_devs[i].name, smart_devs[i].cmd.error);
+                    warning("smart: ATA device '%s' returned error register %0x", &smart_devs[i].name, cmd.error);
                 smart_devs[i].failed = 1;
                 break;
             default:
-                warning("smart: ATAIOCCOMMAND returned unknown result code %d for drive '%s'", smart_devs[i].cmd.retsts, &smart_devs[i].name);
+                warning("smart: ATAIOCCOMMAND returned unknown result code %d for drive '%s'", cmd.retsts, &smart_devs[i].name);
                 smart_devs[i].failed = 1;
                 break;
         }
@@ -178,8 +169,6 @@ gets_smart()
          * footprint and the amount of datajuggling we need to do; we would
          * rather ignore the checksums.
          */
-
-        smart_devs[i].failed = 0;
     }
     return;
 }

+ 3 - 0
symon/platform/OpenBSD/platform.h

@@ -7,6 +7,7 @@
 #include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/syslimits.h>
 #include <net/if.h>
 
 #include "sylimits.h"
@@ -16,6 +17,8 @@
 #define SA_LEN(x)       ((x)->sa_len)
 #define SS_LEN(x)       ((x)->ss_len)
 
+#define MAX_PATH_LEN PATH_MAX
+
 union stream_parg {
     struct {
         long time1[CPUSTATES];

+ 1 - 2
symon/symon/Makefile

@@ -12,8 +12,7 @@ MODS!=	( for s in ../platform/stub/sm_*.c; do \
 		fi; fi; \
 	  done )
 
-EXTRA_SRC=${PLATFORM_SRC:S,^,../platform/${OS}/,g}
-SRCS=	symon.c readconf.c symonnet.c ${MODS} ${EXTRA_SRC}
+SRCS=	symon.c readconf.c symonnet.c ${MODS}
 OBJS+=	${SRCS:R:S/$/.o/g}
 CFLAGS+=-I../lib -I../platform/${OS} -I.
 

+ 4 - 2
symon/symux/symux.c

@@ -54,6 +54,8 @@
 #include "share.h"
 #include "xmalloc.h"
 
+#include "platform.h"
+
 __BEGIN_DECLS
 void exithandler();
 void huphandler(int);
@@ -136,8 +138,8 @@ main(int argc, char *argv[])
         case 'f':
             if (optarg && optarg[0] != '/') {
                 /* cfg path needs to be absolute, we will be a daemon soon */
-                cfgpath = xmalloc(MAXPATHLEN);
-                if ((cfgpath = getcwd(cfgpath, MAXPATHLEN)) == NULL)
+                cfgpath = xmalloc(MAX_PATH_LEN);
+                if ((cfgpath = getcwd(cfgpath, MAX_PATH_LEN)) == NULL)
                     fatal("could not get working directory");
 
                 maxstringlen = strlen(cfgpath) + 1 + strlen(optarg) + 1;