Import "getconf" as a UNIX utility

This commit is contained in:
Pierre Pronchery 2020-12-20 03:03:59 +01:00
parent 2368fa4e02
commit 5ee1732a03
2 changed files with 215 additions and 1 deletions

209
src/getconf.c Normal file
View File

@ -0,0 +1,209 @@
/* $Id$ */
/* Copyright (c) 2020 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Unix utils */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <limits.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* constants */
#ifndef PROGNAME
# define PROGNAME "getconf"
#endif
/* getconf */
/* private */
/* types */
typedef struct _getconf_catalog
{
int name;
char const * string;
} getconf_catalog;
/* constants */
static const getconf_catalog _getconf_catalog_confstr[] =
{
#ifdef _CS_PATH
{ _CS_PATH, "_CS_PATH" },
#endif
};
static const getconf_catalog _getconf_catalog_limits[] =
{
#ifdef NGROUPS_MAX
{ NGROUPS_MAX, "NGROUPS_MAX" },
#endif
};
static const getconf_catalog _getconf_catalog_pathconf[] =
{
#ifdef _PC_FILESIZEBITS
{ _PC_FILESIZEBITS, "FILESIZEBITS" },
#endif
#ifdef _PC_LINK_MAX
{ _PC_LINK_MAX, "LINK_MAX" },
#endif
#ifdef _PC_MAX_CANON
{ _PC_MAX_CANON, "MAX_CANON" },
#endif
#ifdef _PC_MAX_INPUT
{ _PC_MAX_INPUT, "MAX_INPUT" },
#endif
#ifdef _PC_NAME_MAX
{ _PC_NAME_MAX, "NAME_MAX" },
#endif
#ifdef _PC_PATH_MAX
{ _PC_PATH_MAX, "PATH_MAX" },
#endif
#ifdef _PC_PIPE_BUF
{ _PC_PIPE_BUF, "PIPE_BUF" },
#endif
};
/* prototypes */
static int _getconf(char const * specification, char const * var,
char const * path);
static int _getconf_error(char const * message, int ret);
static int _usage(void);
/* functions */
/* getconf */
static int _getconf_confstr(char const * var);
static int _getconf_limits(char const * var);
static int _getconf_pathconf(char const * var, char const * path);
static int _getconf(char const * specification, char const * var,
char const * path)
{
if(path != NULL)
return _getconf_pathconf(var, path);
if(strncmp(var, "_SC_", 4) == 0)
return _getconf_confstr(var);
return _getconf_limits(var);
}
static int _getconf_confstr(char const * var)
{
size_t i;
size_t cnt = sizeof(_getconf_catalog_confstr)
/ sizeof(*_getconf_catalog_confstr);
char * buf;
for(i = 0; i < cnt; i++)
if(strcmp(_getconf_catalog_confstr[i].string, var) == 0)
break;
if(i == cnt)
return _getconf_error(var, -ENOENT);
/* obtain the required size */
if((cnt = confstr(_getconf_catalog_confstr[i].name, NULL, 0)) == 0)
return _getconf_error(var, 2);
if((buf = malloc(cnt)) == NULL)
return _getconf_error(var, 2);
if((cnt = confstr(_getconf_catalog_confstr[i].name, buf, cnt)) == 0)
{
free(buf);
return _getconf_error(var, 2);
}
printf("%s\n", buf);
free(buf);
return 0;
}
static int _getconf_limits(char const * var)
{
size_t i;
size_t cnt = sizeof(_getconf_catalog_limits)
/ sizeof(*_getconf_catalog_limits);
for(i = 0; i < cnt; i++)
if(strcmp(_getconf_catalog_limits[i].string, var) == 0)
break;
if(i == cnt)
return _getconf_error(var, -ENOENT);
printf("%d\n", _getconf_catalog_limits[i].name);
return 0;
}
static int _getconf_pathconf(char const * var, char const * path)
{
size_t i;
size_t cnt = sizeof(_getconf_catalog_pathconf)
/ sizeof(*_getconf_catalog_pathconf);
long value;
for(i = 0; i < cnt; i++)
if(strcmp(_getconf_catalog_pathconf[i].string, var) == 0)
break;
if(i == cnt)
return _getconf_error(var, -ENOENT);
if((value = pathconf(path, _getconf_catalog_pathconf[i].name)) < 0)
return _getconf_error(var, 2);
printf("%ld\n", value);
return 0;
}
/* error */
static int _getconf_error(char const * message, int ret)
{
fputs(PROGNAME ": ", stderr);
if(ret < 0)
{
fprintf(stderr, "%s%s%s\n", (message != NULL) ? message : "",
(message != NULL) ? ": " : "", strerror(-ret));
return -ret;
}
perror(message);
return ret;
}
/* usage */
static int _usage(void)
{
fputs("Usage: " PROGNAME " [-v specification] system_var\n"
" " PROGNAME " [-v specification] path_var pathname\n", stderr);
return 1;
}
/* main */
int main(int argc, char * argv[])
{
int o;
char const * specification = NULL;
while((o = getopt(argc, argv, "v:")) != -1)
switch(o)
{
case 'v':
specification = optarg;
break;
default:
return _usage();
}
if(optind + 1 != argc && optind + 2 != argc)
return _usage();
return (_getconf(specification, argv[optind], argv[optind + 1]) == 0)
? 0 : 2;
}

View File

@ -1,4 +1,4 @@
targets=basename,cat,chgrp,chmod,chown,cksum,cmp,cp,date,df,dirname,du,echo,false,file,find,grep,head,id,kill,link,ln,locale,logname,ls,mkdir,mkfifo,more,mv,nice,pr,printf,ps,pwd,renice,rm,rmdir,sleep,strings,tail,test,time,touch,true,tty,uname,uniq,unlink,wc,who
targets=basename,cat,chgrp,chmod,chown,cksum,cmp,cp,date,df,dirname,du,echo,false,file,find,getconf,grep,head,id,kill,link,ln,locale,logname,ls,mkdir,mkfifo,more,mv,nice,pr,printf,ps,pwd,renice,rm,rmdir,sleep,strings,tail,test,time,touch,true,tty,uname,uniq,unlink,wc,who
cflags=-W -Wall -g -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
ldflags=-pie -Wl,-z,relro -Wl,-z,now
dist=Makefile,common.c
@ -87,6 +87,11 @@ type=binary
sources=find.c
install=$(BINDIR)
[getconf]
type=binary
sources=getconf.c
install=$(BINDIR)
[grep]
type=binary
sources=grep.c