Репозитории ALT
S: | 1.3.59-alt4 |
5.1: | 1.3.29-alt2 |
4.1: | 1.3.29-alt2 |
4.0: | 1.3.29-alt2 |
3.0: | 1.2.24-alt5 |
+backports: | 1.3.29-alt0.M30.1 |
Группа :: Система/Настройка/Загрузка и инициализация
Пакет: chkconfig
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: chkconfig-1.3.26-owl-fixes.patch
Скачать
Скачать
diff -upk.orig chkconfig-1.3.25.orig/Makefile chkconfig-1.3.25/Makefile
--- chkconfig-1.3.25.orig/Makefile 2005-02-23 04:22:53 +0000
+++ chkconfig-1.3.25/Makefile 2005-12-22 20:03:58 +0000
@@ -14,7 +14,7 @@ ALTDIR = /var/lib/alternatives
ALTDATADIR = /etc/alternatives
SUBDIRS = po
-OBJS=chkconfig.o leveldb.o
+OBJS=chkconfig.o leveldb.o xmalloc.o
NTOBJS=ntsysv.o leveldb.o
all: subdirs $(PROG) ntsysv alternatives
@@ -26,7 +26,7 @@ subdirs:
done && test -z "$$fail"
chkconfig: $(OBJS)
- $(CC) $(LDFLAGS) -o chkconfig $(OBJS) -Wl,-Bstatic -lpopt -Wl,-Bdynamic
+ $(CC) $(LDFLAGS) -o chkconfig $(OBJS) -lpopt
alternativs: alternatives.o
diff -upk.orig chkconfig-1.3.25.orig/chkconfig.c chkconfig-1.3.25/chkconfig.c
--- chkconfig-1.3.25.orig/chkconfig.c 2005-11-30 19:45:33 +0000
+++ chkconfig-1.3.25/chkconfig.c 2005-12-22 20:32:08 +0000
@@ -10,24 +10,26 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
-
-static char *progname;
+#include <limits.h>
#define _(String) gettext((String))
+#define progname program_invocation_short_name
#include "leveldb.h"
+#include "xmalloc.h"
-static void usage(void) {
- fprintf(stderr, _("%s version %s - Copyright (C) 1997-2000 Red Hat, Inc.\n"), progname, VERSION);
- fprintf(stderr, _("This may be freely redistributed under the terms of "
+static void __attribute__ ((__noreturn__)) usage(int rc) {
+ FILE *fp = rc ? stderr : stdout;
+ fprintf(fp, _("%s version %s - Copyright (C) 1997-2000 Red Hat, Inc.\n"), progname, VERSION);
+ fprintf(fp, _("This may be freely redistributed under the terms of "
"the GNU Public License.\n"));
- fprintf(stderr, "\n");
- fprintf(stderr, _("usage: %s --list [name]\n"), progname);
- fprintf(stderr, _(" %s --add <name>\n"), progname);
- fprintf(stderr, _(" %s --del <name>\n"), progname);
- fprintf(stderr, _(" %s [--level <levels>] <name> %s\n"), progname, "<on|off|reset|resetpriorities>");
+ fprintf(fp, "\n");
+ fprintf(fp, _("usage: %s --list [name]\n"), progname);
+ fprintf(fp, _(" %s --add <name>\n"), progname);
+ fprintf(fp, _(" %s --del <name>\n"), progname);
+ fprintf(fp, _(" %s [--level <levels>] <name> %s\n"), progname, "<on|off|reset|resetpriorities>");
- exit(1);
+ exit(rc);
}
static void readServiceError(int rc, char * name) {
@@ -43,9 +45,17 @@ static void readServiceError(int rc, cha
exit(1);
}
+static int checkUnprivileged(void) {
+ if (getuid()) {
+ fprintf(stderr, "%s",
+ _("This function is not available for unprivileged user.\n"));
+ return 1;
+ }
+ return 0;
+}
+
static int delServiceOne(char *name, int level) {
- int i, rc;
- glob_t globres;
+ int rc;
struct service s;
if ((rc = readServiceInfo(name, &s, 0))) {
@@ -54,33 +64,25 @@ static int delServiceOne(char *name, int
}
if (s.type == TYPE_XINETD) return 0;
-
- if (!findServiceEntries(name, level, &globres)) {
- for (i = 0; i < globres.gl_pathc; i++)
- unlink(globres.gl_pathv[i]);
- if (globres.gl_pathc) globfree(&globres);
- }
+ cleanServiceEntry(name, level);
return 0;
}
static int delService(char * name) {
- int level, i, rc;
- glob_t globres;
+ int level, rc;
struct service s;
+ if (checkUnprivileged())
+ return 1;
+
if ((rc = readServiceInfo(name, &s, 0))) {
readServiceError(rc, name);
return 1;
}
if (s.type == TYPE_XINETD) return 0;
- for (level = 0; level < 7; level++) {
- if (!findServiceEntries(name, level, &globres)) {
- for (i = 0; i < globres.gl_pathc; i++)
- unlink(globres.gl_pathv[i]);
- if (globres.gl_pathc) globfree(&globres);
- }
- }
+ for (level = 0; level < 7; level++)
+ cleanServiceEntry(name, level);
return 0;
}
@@ -149,6 +151,26 @@ static int frobOneDependencies(struct se
}
+static int skipDirEntry(struct dirent * ent) {
+ const char *dn;
+
+ /* Skip any file starting with a . */
+ if (ent->d_name[0] == '.')
+ return 1;
+
+ /* Skip files with known bad extensions */
+ if ((dn = strrchr(ent->d_name, '.')) != NULL &&
+ (!strcmp(dn, ".rpmsave") || !strcmp(dn, ".rpmnew")
+ || !strcmp(dn, ".rpmorig") || !strcmp(dn, ".swp")))
+ return 1;
+
+ dn = ent->d_name + strlen(ent->d_name) - 1;
+ if (*dn == '~' || *dn == ',')
+ return 1;
+
+ return 0;
+}
+
/* LSB-style dependency frobber. Calculates a usable start priority
* and stop priority.
* This algorithm will almost certainly break horribly at some point. */
@@ -158,7 +180,7 @@ static void frobDependencies(struct serv
struct stat sb;
struct service *servs = NULL;
int numservs = 0;
- char fn[1024];
+ char fn[PATH_MAX];
int nResolved = 0;
if (!(dir = opendir(RUNLEVELS "/init.d"))) {
@@ -168,21 +190,10 @@ static void frobDependencies(struct serv
}
while ((ent = readdir(dir))) {
- const char *dn;
-
- /* Skip any file starting with a . */
- if (ent->d_name[0] == '.') continue;
-
- /* Skip files with known bad extensions */
- if ((dn = strrchr(ent->d_name, '.')) != NULL &&
- (!strcmp(dn, ".rpmsave") || !strcmp(dn, ".rpmnew") || !strcmp(dn, ".rpmorig") || !strcmp(dn, ".swp")))
- continue;
-
- dn = ent->d_name + strlen(ent->d_name) - 1;
- if (*dn == '~' || *dn == ',')
+ if (skipDirEntry(ent))
continue;
- sprintf(fn, RUNLEVELS "/init.d/%s", ent->d_name);
+ snprintf(fn, sizeof(fn), RUNLEVELS "/init.d/%s", ent->d_name);
if (stat(fn, &sb)) {
continue;
}
@@ -212,6 +223,9 @@ static int addService(char * name) {
int i, rc;
struct service s;
+ if (checkUnprivileged())
+ return 1;
+
if ((rc = readServiceInfo(name, &s, 0))) {
readServiceError(rc, name);
return 1;
@@ -301,17 +315,16 @@ static int listService(char * item) {
DIR * dir;
struct dirent * ent;
struct stat sb;
- char fn[1024];
+ char fn[PATH_MAX];
char **services;
int i;
int numServices = 0;
int numServicesAlloced;
- int err = 0;
if (item) return showServiceInfo(item, 0);
numServicesAlloced = 10;
- services = malloc(sizeof(*services) * numServicesAlloced);
+ services = xmalloc(sizeof(*services) * numServicesAlloced);
if (!(dir = opendir(RUNLEVELS "/init.d"))) {
fprintf(stderr, _("failed to open %s/init.d: %s\n"), RUNLEVELS,
@@ -320,21 +333,10 @@ static int listService(char * item) {
}
while ((ent = readdir(dir))) {
- const char *dn;
-
- /* Skip any file starting with a . */
- if (ent->d_name[0] == '.') continue;
-
- /* Skip files with known bad extensions */
- if ((dn = strrchr(ent->d_name, '.')) != NULL &&
- (!strcmp(dn, ".rpmsave") || !strcmp(dn, ".rpmnew") || !strcmp(dn, ".rpmorig") || !strcmp(dn, ".swp")))
+ if (skipDirEntry(ent))
continue;
- dn = ent->d_name + strlen(ent->d_name) - 1;
- if (*dn == '~' || *dn == ',')
- continue;
-
- sprintf(fn, RUNLEVELS "/init.d/%s", ent->d_name);
+ snprintf(fn, sizeof(fn), RUNLEVELS "/init.d/%s", ent->d_name);
if (stat(fn, &sb)) {
fprintf(stderr, _("error reading info for service %s: %s\n"),
ent->d_name, strerror(errno));
@@ -365,35 +367,19 @@ static int listService(char * item) {
closedir(dir);
- if (isXinetdEnabled()) {
+ if (isXinetdEnabled() && (dir = opendir(XINETDDIR))) {
struct service *s, *t;
printf("\n");
printf(_("xinetd based services:\n"));
- if (!(dir = opendir(XINETDDIR))) {
- fprintf(stderr, _("failed to open directory %s: %s\n"),
- XINETDDIR, strerror(err));
- return 1;
- }
numServices = 0;
numServicesAlloced = 10;
- s = malloc(sizeof (*s) * numServicesAlloced);
+ s = xmalloc(sizeof (*s) * numServicesAlloced);
while ((ent = readdir(dir))) {
- const char *dn;
-
- /* Skip any file starting with a . */
- if (ent->d_name[0] == '.') continue;
+ if (skipDirEntry(ent))
+ continue;
- /* Skip files with known bad extensions */
- if ((dn = strrchr(ent->d_name, '.')) != NULL &&
- (!strcmp(dn, ".rpmsave") || !strcmp(dn, ".rpmnew") || !strcmp(dn, ".rpmorig") || !strcmp(dn, ".swp")))
- continue;
-
- dn = ent->d_name + strlen(ent->d_name) - 1;
- if (*dn == '~' || *dn == ',')
- continue;
-
if (numServices == numServicesAlloced) {
numServicesAlloced += 10;
s = realloc(s, numServicesAlloced * sizeof (*s));
@@ -405,9 +391,10 @@ static int listService(char * item) {
qsort(s, numServices, sizeof(*s), xinetdNameCmp);
t = s;
for (i = 0; i < numServices; i++, s++) {
- char *tmp = malloc(strlen(s->name) + 5);
+ char *tmp = xmalloc(strlen(s->name) + 2);
sprintf(tmp,"%s:",s->name);
printf("\t%-15s\t%s\n", tmp, s->levels ? _("on") : _("off"));
+ free(tmp);
}
closedir(dir);
free(t);
@@ -461,7 +448,7 @@ int setService(char * name, int where, i
return 0;
}
-int main(int argc, char ** argv) {
+int main(int argc, const char ** argv) {
int listItem = 0, addItem = 0, delItem = 0;
int rc, i, x;
int LSB = 0;
@@ -480,10 +467,9 @@ int main(int argc, char ** argv) {
{ 0, 0, 0, 0, 0 }
};
- if ((progname = strrchr(argv[0], '/')) != NULL)
- progname++;
- else
- progname = argv[0];
+ if (argc < 1)
+ progname = "chkconfig";
+
if (!strcmp(progname,"install_initd")) {
addItem++;
LSB++;
@@ -497,6 +483,9 @@ int main(int argc, char ** argv) {
bindtextdomain("chkconfig","/usr/share/locale");
textdomain("chkconfig");
+ if (argc < 1)
+ usage(EXIT_FAILURE);
+
optCon = poptGetContext("chkconfig", argc, argv, optionsTable, 0);
poptReadDefaultConfig(optCon, 1);
@@ -512,7 +501,8 @@ int main(int argc, char ** argv) {
exit(0);
}
- if (help || argc == 1) usage();
+ if (help) usage(EXIT_SUCCESS);
+ if (argc <= 1) usage(EXIT_FAILURE);
if ((listItem + addItem + delItem) > 1) {
fprintf(stderr, _("only one of --list, --add, or --del may be "
@@ -524,7 +514,7 @@ int main(int argc, char ** argv) {
char * name = (char *)poptGetArg(optCon);
if (!name || !*name || poptGetArg(optCon))
- usage();
+ usage(EXIT_FAILURE);
if (LSB)
name = basename(name);
@@ -532,7 +522,7 @@ int main(int argc, char ** argv) {
} else if (delItem) {
char * name = (char *)poptGetArg(optCon);
- if (!name || !*name || poptGetArg(optCon)) usage();
+ if (!name || !*name || poptGetArg(optCon)) usage(EXIT_FAILURE);
if (LSB)
name = basename(name);
@@ -540,7 +530,7 @@ int main(int argc, char ** argv) {
} else if (listItem) {
char * item = (char *)poptGetArg(optCon);
- if (item && poptGetArg(optCon)) usage();
+ if (item && poptGetArg(optCon)) usage(EXIT_FAILURE);
return listService(item);
} else {
@@ -549,13 +539,16 @@ int main(int argc, char ** argv) {
int where = 0, level = -1;
if (!name) {
- usage();
+ usage(EXIT_FAILURE);
}
if (levels) {
where = parseLevels(levels, 0);
- if (where == -1) usage();
+ if (where == -1) usage(EXIT_FAILURE);
}
+ if (checkUnprivileged())
+ return 1;
+
if (!state) {
if (where) {
rc = x = 0;
@@ -577,7 +570,7 @@ int main(int argc, char ** argv) {
}
rc = readServiceInfo(name, &s, 0);
if (rc)
- usage();
+ usage(EXIT_FAILURE);
if (s.type == TYPE_XINETD) {
if (isOn("xinetd",level))
return !s.levels;
@@ -592,10 +585,8 @@ int main(int argc, char ** argv) {
else if (!strcmp(state, "reset"))
return setService(name, where, -1);
else
- usage();
+ usage(EXIT_FAILURE);
}
- usage();
-
- return 1;
+ usage(EXIT_FAILURE);
}
diff -upk.orig chkconfig-1.3.25.orig/leveldb.c chkconfig-1.3.25/leveldb.c
--- chkconfig-1.3.25.orig/leveldb.c 2005-11-08 22:18:38 +0000
+++ chkconfig-1.3.25/leveldb.c 2005-12-22 20:26:31 +0000
@@ -5,12 +5,12 @@
#include <glob.h>
#include <libintl.h>
#include <locale.h>
-#include <sys/mman.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
/* Changes
1998-09-22 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
@@ -21,30 +21,28 @@
#define _(String) gettext((String))
#include "leveldb.h"
+#include "xmalloc.h"
int parseLevels(char * str, int emptyOk) {
- char * chptr = str;
+ char * chptr;
int rc = 0;
- if (!str || !strlen(str))
+ if (!str || !*str)
return emptyOk ? 0 : -1;
- while (*chptr) {
+ for (chptr = str; *chptr; ++chptr) {
if (!isdigit(*chptr) || *chptr > '6') return -1;
rc |= 1 << (*chptr - '0');
- chptr++;
}
return rc;
}
int readDescription(char *start, char *bufstop, char **english_desc, char **serv_desc) {
- char english;
- char my_lang_loaded = 0;
- char is_my_lang = 0;
+ int english;
+ int is_my_lang = 0;
char * lang = getenv ("LANG");
- char * final_parenthesis;
- char * end, *next;
+ char * end, *next, *desc;
int i;
english = *start == ':';
@@ -55,6 +53,8 @@ int readDescription(char *start, char *b
next = end + 1;
if (!english) {
+ char * final_parenthesis;
+
if (*start != '(') {
return 1;
}
@@ -67,33 +67,30 @@ int readDescription(char *start, char *b
}
is_my_lang = lang ? strncmp (lang, start, strlen (lang)) == 0 : 0;
- start = final_parenthesis + 2;
- } else ++start;
-
- while (isspace(*start) && start < end) start++;
- if (start == end) {
- return 1;
- }
- {
- char* desc = malloc(end - start + 1);
- strncpy(desc, start, end - start);
- desc[end - start] = '\0';
-
- start = next;
+ start = final_parenthesis + 1;
+ if (*start == ':')
+ ++start;
+ } else ++start;
+
+ while (start < end && isspace(*start)) start++;
+ if (start >= end) return 1;
+
+ desc = xmalloc(end - start + 1);
+ strncpy(desc, start, end - start);
+ desc[end - start] = '\0';
- while (desc[strlen(desc) - 1] == '\\') {
+ for (start = next; desc[strlen(desc) - 1] == '\\'; start = next) {
desc[strlen(desc) - 1] = '\0';
- start = next;
- while (isspace(*start) && start < bufstop) start++;
- if (start == bufstop || *start != '#') {
+ while (start < bufstop && isspace(*start)) start++;
+ if (start >= bufstop || *start != '#') {
return 1;
}
start++;
- while (isspace(*start) && start < bufstop) start++;
- if (start == bufstop) {
+ while (start < bufstop && isspace(*start)) start++;
+ if (start >= bufstop) {
return 1;
}
@@ -104,38 +101,62 @@ int readDescription(char *start, char *b
next = end + 1;
i = strlen(desc);
- desc = realloc(desc, i + end - start + 1);
+ desc = xrealloc(desc, i + end - start + 1);
strncat(desc, start, end - start);
- desc[i + end - start] = '\0';
-
- start = next;
- }
+ }
- if (desc) {
- if (my_lang_loaded) {
- free(desc);
- } else if (is_my_lang) {
- if (*serv_desc)
- free(*serv_desc);
-
- *serv_desc = desc;
- return 0;
- } else if (english) {
- if (*serv_desc)
- free(*serv_desc);
+ if (desc) {
+ if (is_my_lang) {
+ free(*serv_desc);
+ *serv_desc = desc;
+ } else if (english) {
+ *serv_desc = xfree(*serv_desc);
+ free (*english_desc);
+ *english_desc = desc;
+ } else
+ desc = xfree (desc);
+ }
+ return 0;
+}
- if (*english_desc)
- free (*english_desc);
+static ssize_t
+read_loop(int fd, char *buffer, size_t count)
+{
+ ssize_t offset = 0;
+
+ while (count > 0)
+ {
+ ssize_t block =
+ TEMP_FAILURE_RETRY(read(fd, &buffer[offset], count));
+
+ if (block <= 0)
+ return offset ? : block;
+ offset += block;
+ count -= block;
+ }
+ return offset;
+}
- *english_desc = desc;
- } else free (desc);
- }
- }
- return 0;
+static ssize_t
+write_loop(int fd, const char *buffer, size_t count)
+{
+ ssize_t offset = 0;
+
+ while (count > 0)
+ {
+ ssize_t block =
+ TEMP_FAILURE_RETRY(write(fd, &buffer[offset], count));
+
+ if (block <= 0)
+ return offset ? : block;
+ offset += block;
+ count -= block;
+ }
+ return offset;
}
int readXinetdServiceInfo(char *name, struct service * service, int honorHide) {
- char * filename = alloca(strlen(name) + strlen(XINETDDIR) + 50);
+ char * filename;
int fd;
struct service serv = {
name: NULL,
@@ -152,56 +173,57 @@ int readXinetdServiceInfo(char *name, st
};
struct stat sb;
char * buf, *ptr;
- char * eng_desc = NULL, *start;
+ char * eng_desc = NULL, *end_buf;
- snprintf(filename, strlen(name)+strlen(XINETDDIR)+50, XINETDDIR "/%s", name);
+ if (strlen(name) > PATH_MAX)
+ return -1;
+ filename = alloca(strlen(name) + strlen(XINETDDIR) + 50);
+ sprintf(filename, "%s/%s", XINETDDIR, name);
if ((fd = open(filename, O_RDONLY)) < 0) return -1;
- fstat(fd,&sb);
- if (! S_ISREG(sb.st_mode)) return -1;
- buf = malloc(sb.st_size+1);
- if (read(fd,buf,sb.st_size)!=sb.st_size) {
+ if (fstat(fd,&sb) || !S_ISREG(sb.st_mode)) {
close(fd);
+ return -1;
+ }
+ if (!(buf = malloc(sb.st_size+1))) {
+ close(fd);
+ return -1;
+ }
+ if (read_loop(fd, buf, sb.st_size) != sb.st_size) {
free(buf);
+ close(fd);
return -1;
}
close(fd);
- serv.name = strdup(name);
- buf[sb.st_size] = '\0';
- start = buf;
- while (buf) {
+ end_buf = buf + sb.st_size;
+ *end_buf = '\0';
+ serv.name = xstrdup(name);
+ for (; buf && buf[0]; buf = ptr) {
ptr = strchr(buf,'\n');
if (*buf == '#') {
buf++;
- while (isspace(*buf) && buf < ptr) buf++;
- if (!strncmp(buf,"default:", 9)) {
+ while (isspace(*buf) && (!ptr || buf < ptr)) buf++;
+ if (!strncmp(buf,"default:", 8)) {
buf+=8;
- while(isspace(*buf)) buf++;
- if (!strncmp(buf+9,"on",2)) {
+ while (isspace(*buf) && (!ptr || buf < ptr)) buf++;
+ if (!strncmp(buf,"on",2)) {
serv.enabled = 1;
} else {
serv.enabled = 0;
}
} else if (!strncmp(buf,"description:",12)) {
buf+=11;
- if (readDescription(buf,start+sb.st_size,
- &serv.desc,&eng_desc)) {
- if (serv.desc) free(serv.desc);
+ if (readDescription(buf, end_buf,
+ &eng_desc, &serv.desc)) {
+ serv.desc = xfree(serv.desc);
}
- if (!serv.desc) {
- if (eng_desc)
- serv.desc = eng_desc;
- } else if (eng_desc)
- free (eng_desc);
}
if (ptr) {
- *ptr = '\0';
ptr++;
}
- buf = ptr;
continue;
}
- while (isspace(*buf) && buf < ptr) buf++;
+ while (isspace(*buf) && (!ptr || buf < ptr)) buf++;
if (!strncmp(buf,"disable", 7)) {
buf = strstr(buf,"=");
if (buf)
@@ -220,20 +242,25 @@ int readXinetdServiceInfo(char *name, st
}
}
if (ptr) {
- *ptr = '\0';
ptr++;
}
- buf = ptr;
}
+
+ if (!serv.desc) {
+ if (eng_desc)
+ serv.desc = eng_desc;
+ } else
+ eng_desc = xfree (eng_desc);
+
*service = serv;
return 0;
}
int readServiceInfo(char * name, struct service * service, int honorHide) {
- char * filename = alloca(strlen(name) + strlen(RUNLEVELS) + 50);
+ char * filename;
int fd;
struct stat sb;
- char * bufstart, * bufstop, * start, * end, * next, *tmpbufstart;
+ char * bufstart, * bufstop, * start, * end, * next;
struct service serv = {
name: NULL,
levels: -1,
@@ -247,44 +274,43 @@ int readServiceInfo(char * name, struct
isLSB: 0,
enabled: 0
};
- char overflow;
- char levelbuf[20];
char * english_desc = NULL;
- sprintf(filename, RUNLEVELS "/init.d/%s", name);
+ if (strlen(name) > PATH_MAX)
+ return -1;
+ filename = alloca(strlen(name) + strlen(RUNLEVELS) + 50);
+ sprintf(filename, "%s/init.d/%s", RUNLEVELS, name);
if ((fd = open(filename, O_RDONLY)) < 0) {
return readXinetdServiceInfo(name,service,honorHide);
}
- fstat(fd, &sb);
- bufstart = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (bufstart == ((caddr_t) -1)) {
- close(fd);
+ if (fstat(fd,&sb) || !S_ISREG(sb.st_mode)) {
+ close(fd);
return -1;
}
- tmpbufstart = (char*)malloc(sb.st_size+1);
- if (tmpbufstart == NULL) {
+ if (!(bufstart = malloc(sb.st_size+1))) {
close(fd);
return -1;
}
- memcpy(tmpbufstart, bufstart, sb.st_size);
- munmap(bufstart, sb.st_size);
+ if (read_loop(fd, bufstart, sb.st_size) != sb.st_size) {
+ free(bufstart);
+ close(fd);
+ return -1;
+ }
- bufstart = tmpbufstart;
+ close(fd);
bufstop = bufstart + sb.st_size;
*bufstop = 0;
- close(fd);
-
next = bufstart;
while (next < bufstop && (serv.levels == -1 || !serv.desc)) {
start = next;
- while (isspace(*start) && start < bufstop) start++;
- if (start == bufstop) break;
+ while (start < bufstop && isspace(*start)) start++;
+ if (start >= bufstop) break;
end = strchr(start, '\n');
if (!end)
@@ -295,41 +321,68 @@ int readServiceInfo(char * name, struct
if (*start != '#') continue;
start++;
- if (!strncmp(start, "## BEGIN INIT INFO", 18))
- serv.isLSB = 1;
+ if (!strncmp(start, "## BEGIN INIT INFO", 18)) {
+ serv.isLSB = 1;
+ continue;
+ }
- while (isspace(*start) && start < end) start++;
- if (start == end) continue;
- if (honorHide && !strncmp(start, "hide:", 5)) {
- start += 5;
- while (isspace(*start) && start < end) start++;
- if (start == end || !strncmp(start, "true", 4)) {
- if (serv.desc) free(serv.desc);
+ while (start < end && isspace(*start)) start++;
+ if (start >= end) continue;
+ if (honorHide && !strncmp(start, "hide:", 5) && (start += 5)) {
+ while (start < end && isspace(*start)) start++;
+ if (start >= end || !strncmp(start, "true", 4)) {
+ serv.desc = xfree(serv.desc);
free(bufstart);
return 1;
}
}
- if (!strncmp(start, "chkconfig:", 10)) {
+ if (!strncmp(start, "chkconfig:", 10) && (start += 10)) {
int spri, kpri;
+ char overflow;
+ char * level_end;
- start += 10;
- while (isspace(*start) && start < end) start++;
- if (start == end) {
- if (serv.desc) free(serv.desc);
+ while (start < end && isspace(*start)) start++;
+ if (start >= end) {
+ serv.desc = xfree(serv.desc);
free(bufstart);
return 1;
}
- if ((sscanf(start, "%s %d %d%c", levelbuf,
- &spri, &kpri, &overflow) != 4) ||
+ for (level_end = start;
+ level_end < end && *level_end && !isspace(*level_end);
+ ++level_end)
+ ;
+ if (level_end <= start || level_end >= end) {
+ serv.desc = xfree(serv.desc);
+ free(bufstart);
+ return 1;
+ } else if (serv.levels == -1) {
+ char buf[level_end - start + 1];
+
+ memcpy(buf, start, level_end - start);
+ buf[level_end - start] = '\0';
+ if (!strcmp(buf, "-"))
+ serv.levels = 0;
+ else
+ serv.levels = parseLevels(buf, 0);
+ }
+ if (serv.levels == -1) {
+ serv.desc = xfree(serv.desc);
+ free(bufstart);
+ return 1;
+ }
+ start = level_end;
+ while (start < end && isspace(*start)) start++;
+ if ((sscanf(start, "%d %d%c",
+ &spri, &kpri, &overflow) != 3) ||
!isspace(overflow)) {
- if (serv.desc) free(serv.desc);
+ serv.desc = xfree(serv.desc);
free(bufstart);
return 1;
}
if (spri > 99 || kpri > 99 || kpri < 0 || spri < 0) {
- if (serv.desc) free(serv.desc);
+ serv.desc = xfree(serv.desc);
free(bufstart);
return 1;
}
@@ -337,28 +390,15 @@ int readServiceInfo(char * name, struct
serv.sPriority = spri;
if (serv.kPriority == -1)
serv.kPriority = kpri;
-
- if (serv.levels == -1) {
- if (!strcmp(levelbuf, "-"))
- serv.levels = 0;
- else
- serv.levels = parseLevels(levelbuf, 0);
- }
- if (serv.levels == -1) {
- if (serv.desc) free(serv.desc);
- free(bufstart);
- return 1;
- }
- } else if (!strncmp(start, "description", 11) ||
- !strncmp(start, "Description:", 12) ||
- !strncmp(start, "Short-Description:", 18)) {
- if (readDescription(start+11, bufstop, &english_desc, &serv.desc)) {
- if (serv.desc) free(serv.desc);
+ } else if ((!strncmp(start, "description", 11) && (start += 11)) ||
+ (!strncmp(start, "Description:", 12) && (start += 11)) ||
+ (!strncmp(start, "Short-Description:", 18) && (start += 17))) {
+ if (readDescription(start, bufstop, &english_desc, &serv.desc)) {
+ serv.desc = xfree(serv.desc);
}
- } else if (!strncmp(start, "Default-Start:", 14)) {
+ } else if (!strncmp(start, "Default-Start:", 14) && (start += 14)) {
char *t;
- start+=14;
while (1) {
int lev;
@@ -371,10 +411,9 @@ int readServiceInfo(char * name, struct
serv.levels = 0;
serv.levels |= 1 << lev;
}
- } else if (!strncmp(start, "Default-Stop:", 13)) {
+ } else if (!strncmp(start, "Default-Stop:", 13) && (start += 13)) {
char *t;
- start+=13;
while (1) {
int lev;
@@ -387,14 +426,13 @@ int readServiceInfo(char * name, struct
serv.levels = 0;
serv.levels &= ~(1 << lev);
}
- } else if (!strncmp(start, "Required-Start:", 15)) {
+ } else if (!strncmp(start, "Required-Start:", 15) && (start += 15)) {
char *t;
int numdeps = 0;
- start+=15;
while (1) {
- while (*start && isspace(*start) && start < end) start++;
- if (start == end)
+ while (start < end && isspace(*start)) start++;
+ if (start >= end)
break;
t = start;
while (*t && !isspace(*t) && t < end) t++;
@@ -403,23 +441,19 @@ int readServiceInfo(char * name, struct
t++;
}
numdeps++;
- serv.startDeps = realloc(serv.startDeps,
+ serv.startDeps = xrealloc(serv.startDeps,
(numdeps + 1) * sizeof(char *));
- serv.startDeps[numdeps-1] = strdup(start);
+ serv.startDeps[numdeps-1] = xstrdup(start);
serv.startDeps[numdeps] = NULL;
- if (!t || t >= end)
- break;
- else
- start = t;
+ start = t;
}
- } else if (!strncmp(start, "Required-Stop:", 14)) {
+ } else if (!strncmp(start, "Required-Stop:", 14) && (start += 14)) {
char *t;
int numdeps = 0;
- start+=14;
while (1) {
- while (*start && isspace(*start) && start < end) start++;
- if (start == end)
+ while (start < end && isspace(*start)) start++;
+ if (start >= end)
break;
t = start;
while (*t && !isspace(*t) && t < end) t++;
@@ -428,23 +462,19 @@ int readServiceInfo(char * name, struct
t++;
}
numdeps++;
- serv.stopDeps = realloc(serv.stopDeps,
+ serv.stopDeps = xrealloc(serv.stopDeps,
(numdeps + 1) * sizeof(char *));
- serv.stopDeps[numdeps-1] = strdup(start);
+ serv.stopDeps[numdeps-1] = xstrdup(start);
serv.stopDeps[numdeps] = NULL;
- if (!t || t >= end)
- break;
- else
- start = t;
+ start = t;
}
- } else if (!strncmp(start, "Provides:", 9)) {
+ } else if (!strncmp(start, "Provides:", 9) && (start += 9)) {
char *t;
int numdeps = 0;
- start+=9;
while (1) {
- while (*start && isspace(*start) && start < end) start++;
- if (start == end)
+ while (start < end && isspace(*start)) start++;
+ if (start >= end)
break;
t = start;
while (*t && !isspace(*t) && t < end) t++;
@@ -453,35 +483,32 @@ int readServiceInfo(char * name, struct
t++;
}
numdeps++;
- serv.provides = realloc(serv.provides,
+ serv.provides = xrealloc(serv.provides,
(numdeps + 1) * sizeof(char *));
- serv.provides[numdeps-1] = strdup(start);
+ serv.provides[numdeps-1] = xstrdup(start);
serv.provides[numdeps] = NULL;
- if (!t || t >= end)
- break;
- else
- start = t;
+ start = t;
}
}
}
- free(bufstart);
+ bufstart = xfree(bufstart);
if (!serv.desc) {
if (english_desc)
serv.desc = english_desc;
- } else if (english_desc)
- free (english_desc);
+ } else
+ english_desc = xfree (english_desc);
if ((serv.levels == -1 ) || !serv.desc) {
return 1;
}
- serv.name = strdup(name);
+ serv.name = xstrdup(name);
if (!serv.provides) {
- serv.provides = malloc(2 * sizeof(char *));
- serv.provides[0] = strdup(name);
+ serv.provides = xmalloc(2 * sizeof(char *));
+ serv.provides[0] = xstrdup(name);
serv.provides[1] = NULL;
}
@@ -511,24 +538,27 @@ int currentRunlevel(void) {
}
int findServiceEntries(char * name, int level, glob_t * globresptr) {
- char match[200];
+ char *match;
glob_t globres;
int rc;
- sprintf(match, "%s/rc%d.d/[SK][0-9][0-9]%s", RUNLEVELS, level, name);
+ xasprintf(&match, "%s/rc%d.d/[SK][0-9][0-9]%s", RUNLEVELS, level, name);
rc = glob(match, GLOB_ERR | GLOB_NOSORT, NULL, &globres);
if (rc && rc != GLOB_NOMATCH) {
fprintf(stderr, _("failed to glob pattern %s: %s\n"), match,
strerror(errno));
+ free(match);
return 1;
} else if (rc == GLOB_NOMATCH) {
globresptr->gl_pathc = 0;
+ free(match);
return 0;
}
*globresptr = globres;
+ free(match);
return 0;
}
@@ -547,6 +577,7 @@ int isConfigured(char * name, int level)
int isOn(char * name, int level) {
glob_t globres;
+ int rc;
if (level == -1) {
level = currentRunlevel();
@@ -559,43 +590,43 @@ int isOn(char * name, int level) {
if (findServiceEntries(name, level, &globres))
exit(1);
- if (!globres.gl_pathc || !strstr(globres.gl_pathv[0], "/S"))
+ if (!globres.gl_pathc)
return 0;
+ rc = !!strstr(globres.gl_pathv[0], "/S");
globfree(&globres);
- return 1;
+
+ return rc;
}
int setXinetdService(struct service s, int on) {
- int oldfd, newfd;
- char oldfname[100], newfname[100];
- char tmpstr[50];
- char *buf, *ptr, *tmp;
+ int fd = -1, rc = -1;
+ char *oldfname = NULL, *newfname = NULL;
+ char *bufstart = NULL, *bufstop, *buf, *ptr, *tmp;
struct stat sb;
if (on == -1) {
on = s.enabled ? 1 : 0;
}
- snprintf(oldfname,100,"%s/%s",XINETDDIR,s.name);
- if ( (oldfd = open(oldfname,O_RDONLY)) == -1 ) {
- return -1;
- }
- fstat(oldfd,&sb);
- buf = malloc(sb.st_size+1);
- if (read(oldfd,buf,sb.st_size)!=sb.st_size) {
- close(oldfd);
- free(buf);
- return -1;
+ xasprintf(&oldfname, "%s/%s", XINETDDIR, s.name);
+ if ((fd = open(oldfname, O_RDONLY)) < 0)
+ goto setXinetdService_done;
+ if (fstat(fd,&sb) || !S_ISREG(sb.st_mode))
+ goto setXinetdService_done;
+ if (!(bufstart = malloc(sb.st_size+1)))
+ goto setXinetdService_done;
+ if (read_loop(fd, bufstart, sb.st_size) != sb.st_size)
+ goto setXinetdService_done;
+ close(fd), fd = -1;
+ bufstop = bufstart + sb.st_size;
+ *bufstop = '\0';
+
+ xasprintf(&newfname, "%s.XXXXXX", oldfname);
+ if ((fd = mkstemp(newfname)) < 0) {
+ newfname = xfree(newfname);
+ goto setXinetdService_done;
}
- close(oldfd);
- buf[sb.st_size] = '\0';
- snprintf(newfname,100,"%s/%s.XXXXXX",XINETDDIR,s.name);
- newfd = mkstemp(newfname);
- if (newfd == -1) {
- free(buf);
- return -1;
- }
- while (buf) {
+ for (buf = bufstart; buf && buf < bufstop; buf = ptr) {
tmp = buf;
ptr = strchr(buf,'\n');
if (ptr) {
@@ -603,47 +634,64 @@ int setXinetdService(struct service s, i
ptr++;
}
while (isspace(*buf)) buf++;
- if (strncmp(buf,"disable", 7) && strlen(buf)) {
- write(newfd,tmp,strlen(tmp));
- write(newfd,"\n",1);
- if (buf[0] == '{') {
- snprintf(tmpstr,50,"\tdisable\t= %s", on ? "no" : "yes");
- write(newfd,tmpstr,strlen(tmpstr));
- write(newfd,"\n",1);
- }
+ if (!buf[0] || !strncmp(buf,"disable", 7))
+ continue;
+ if (write_loop(fd,tmp,strlen(tmp)) != strlen(tmp) ||
+ write_loop(fd,"\n",1) != 1)
+ goto setXinetdService_done;
+ if (buf[0] == '{') {
+ const char *prefix = "\tdisable\t= ";
+ const char *yesno = on ? "no\n" : "yes\n";
+ if (write_loop(fd,prefix,strlen(prefix)) != strlen(prefix) ||
+ write_loop(fd,yesno,strlen(yesno)) != strlen(yesno))
+ goto setXinetdService_done;
}
- buf = ptr;
}
- close(newfd);
- chmod(newfname,0644);
+ fchmod(fd, sb.st_mode & 0666);
+ close(fd), fd = -1;
unlink(oldfname);
- return(rename(newfname,oldfname));
+ rc = rename(newfname,oldfname);
+
+ setXinetdService_done:
+ if (rc && newfname)
+ unlink(newfname);
+ if (fd >= 0) close(fd);
+ free(newfname);
+ free(bufstart);
+ free(oldfname);
+ return rc;
+}
+
+void cleanServiceEntry(char *name, int level) {
+ int i;
+ glob_t globres;
+
+ if (!findServiceEntries(name, level, &globres) && globres.gl_pathc) {
+ for (i = 0; i < globres.gl_pathc; ++i)
+ unlink(globres.gl_pathv[i]);
+ globfree(&globres);
+ }
}
int doSetService(struct service s, int level, int on) {
int priority = on ? s.sPriority : s.kPriority;
- char linkname[200];
- char linkto[200];
- glob_t globres;
- int i;
+ char *linkname, *linkto;
+ int rc;
- if (!findServiceEntries(s.name, level, &globres)) {
- for (i = 0; i < globres.gl_pathc; i++)
- unlink(globres.gl_pathv[i]);
- if (globres.gl_pathc) globfree(&globres);
- }
+ cleanServiceEntry(s.name, level);
- sprintf(linkname, "%s/rc%d.d/%c%02d%s", RUNLEVELS, level,
+ xasprintf(&linkname, "%s/rc%d.d/%c%02d%s", RUNLEVELS, level,
on ? 'S' : 'K', priority, s.name);
- sprintf(linkto, "../init.d/%s", s.name);
+ xasprintf(&linkto, "../init.d/%s", s.name);
unlink(linkname); /* just in case */
- if (symlink(linkto, linkname)) {
+ if ((rc = symlink(linkto, linkname))) {
fprintf(stderr, _("failed to make symlink %s: %s\n"), linkname,
strerror(errno));
- return 1;
}
- return 0;
+ free(linkto);
+ free(linkname);
+ return !!rc;
}
diff -upk.orig chkconfig-1.3.25.orig/leveldb.h chkconfig-1.3.25/leveldb.h
--- chkconfig-1.3.25.orig/leveldb.h 2002-03-13 07:09:04 +0000
+++ chkconfig-1.3.25/leveldb.h 2005-12-22 20:03:24 +0000
@@ -33,5 +33,6 @@ int doSetService(struct service s, int l
int findServiceEntries(char * name, int level, glob_t * globresptr);
int readXinetdServiceInfo(char *name, struct service *service, int honorHide);
int setXinetdService(struct service s, int on);
+void cleanServiceEntry(char *name, int level);
#endif
diff -upk.orig chkconfig-1.3.25.orig/xmalloc.c chkconfig-1.3.25/xmalloc.c
--- chkconfig-1.3.25.orig/xmalloc.c 1970-01-01 00:00:00 +0000
+++ chkconfig-1.3.25/xmalloc.c 2005-12-18 17:04:40 +0000
@@ -0,0 +1,80 @@
+
+/*
+ Copyright (C) 2002 Dmitry V. Levin <ldv@altlinux.org>
+
+ Dynamic memory allocation with error checking.
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+
+#include "xmalloc.h"
+
+void *
+xmalloc(size_t size)
+{
+ void *r = malloc(size);
+
+ if (!r)
+ error(EXIT_FAILURE, errno, "malloc");
+ return r;
+}
+
+void *
+xfree(void *ptr)
+{
+ free(ptr);
+
+ return NULL;
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+ void *r = realloc(ptr, size);
+
+ if (!r)
+ error(EXIT_FAILURE, errno, "realloc");
+ return r;
+}
+
+char *
+xstrdup(const char *s)
+{
+ size_t len = strlen(s);
+ char *r = xmalloc(len + 1);
+
+ memcpy(r, s, len + 1);
+ return r;
+}
+
+char *
+xasprintf(char **ptr, const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ if (vasprintf(ptr, fmt, arg) < 0)
+ error(EXIT_FAILURE, errno, "vasprintf");
+ va_end(arg);
+
+ return *ptr;
+}
diff -upk.orig chkconfig-1.3.25.orig/xmalloc.h chkconfig-1.3.25/xmalloc.h
--- chkconfig-1.3.25.orig/xmalloc.h 1970-01-01 00:00:00 +0000
+++ chkconfig-1.3.25/xmalloc.h 2005-12-18 17:04:17 +0000
@@ -0,0 +1,32 @@
+
+/*
+ Copyright (C) 2002 Dmitry V. Levin <ldv@altlinux.org>
+
+ Dynamic memory allocation with error checking.
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef __XMALLOC_H__
+#define __XMALLOC_H__
+
+extern void *xmalloc(size_t size);
+extern void *xfree(void *ptr);
+extern void *xrealloc(void *ptr, size_t size);
+extern char *xstrdup(const char *s);
+extern char *xasprintf(char **ptr, const char *fmt, ...)
+ __attribute__ ((__format__(__printf__, 2, 3)));
+
+#endif /* __XMALLOC_H__ */