summaryrefslogtreecommitdiff
path: root/lib/lanplus/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lanplus/helper.c')
-rw-r--r--lib/lanplus/helper.c480
1 files changed, 480 insertions, 0 deletions
diff --git a/lib/lanplus/helper.c b/lib/lanplus/helper.c
new file mode 100644
index 0000000..51e39c8
--- /dev/null
+++ b/lib/lanplus/helper.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <io.h>
+#include <signal.h>
+#include <inttypes-win.h>
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h> /* For TIOCNOTTY */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#endif
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#else
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_TTY "/dev/tty"
+#endif
+
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/helper.h>
+#include <ipmitool/log.h>
+
+extern int verbose;
+
+#ifdef MOVED
+/* moved to subs.c */
+uint32_t buf2long(uint8_t * buf)
+{
+ return (uint32_t)(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]);
+}
+
+uint16_t buf2short(uint8_t * buf)
+{
+ return (uint16_t)(buf[1] << 8 | buf[0]);
+}
+
+const char * buf2str(uint8_t * buf, int len)
+{
+ static char str[1024];
+ int i;
+
+ if (len <= 0 || len > 1024)
+ return NULL;
+
+ memset(str, 0, 1024);
+
+ for (i=0; i<len; i++)
+ sprintf(str+i+i, "%2.2x", buf[i]);
+
+ str[len*2] = '\0';
+
+ return (const char *)str;
+}
+
+/* moved to util/ipmilanplus.c for better control */
+#ifdef STATIC
+extern FILE *fplog; /*see util/ipmicmd.c ++++*/
+#endif
+void printbuf(const uint8_t * buf, int len, const char * desc)
+{
+ int i;
+ FILE *fp = stderr;
+
+ if (len <= 0) return;
+ if (verbose < 1) return;
+#ifdef STATIC
+ if (fplog != NULL) fp = fplog; /*++++*/
+#endif
+ fprintf(fp, "%s (%d bytes)\r\n", desc, len);
+ for (i=0; i<len; i++) {
+ if (((i%16) == 0) && (i != 0))
+ fprintf(fp, "\r\n");
+ fprintf(fp, " %2.2x", buf[i]);
+ }
+ fprintf(fp, "\r\n");
+}
+
+const char * val2str(uint16_t val, const struct valstr *vs)
+{
+ static char un_str[32];
+ int i;
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (vs[i].val == val)
+ return vs[i].str;
+ }
+
+ memset(un_str, 0, 32);
+ snprintf(un_str, 32, "Unknown (0x%x)", val);
+
+ return un_str;
+}
+
+const char * oemval2str(uint16_t oem, uint16_t val,
+ const struct oemvalstr *vs)
+{
+ static char un_str[32];
+ int i;
+
+ for (i = 0; vs[i].oem != 0x00 && vs[i].str != NULL; i++) {
+ /* FIXME: for now on we assume PICMG capability on all IANAs */
+ if
+ (
+ (
+ vs[i].oem == oem
+ ||
+ vs[i].oem == IPMI_OEM_PICMG
+ )
+ &&
+ vs[i].val == val
+ )
+ {
+ return vs[i].str;
+ }
+ }
+
+ memset(un_str, 0, 32);
+ snprintf(un_str, 32, "OEM reserved #%02x", val);
+
+ return un_str;
+}
+
+uint16_t str2val(const char *str, const struct valstr *vs)
+{
+ int i;
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (strcasecmp(vs[i].str, str) == 0)
+ return vs[i].val;
+ }
+
+ return vs[i].val;
+}
+#else
+uint32_t buf2long(uint8_t * buf);
+uint16_t buf2short(uint8_t * buf);
+const char * buf2str(uint8_t * buf, int len);
+void printbuf(const uint8_t * buf, int len, const char * desc);
+const char * val2str(uint16_t val, const struct valstr *vs);
+const char * oemval2str(uint16_t oem, uint16_t val,
+ const struct oemvalstr *vs);
+uint16_t str2val(const char *str, const struct valstr *vs);
+#endif
+
+/* print_valstr - print value string list to log or stdout
+ *
+ * @vs: value string list to print
+ * @title: name of this value string list
+ * @loglevel: what log level to print, -1 for stdout
+ */
+void
+print_valstr(const struct valstr * vs, const char * title, int loglevel)
+{
+ int i;
+
+ if (vs == NULL)
+ return;
+
+ if (title != NULL) {
+ if (loglevel < 0)
+ printf("\n%s:\n\n", title);
+ else
+ lprintf(loglevel, "\n%s:\n", title);
+ }
+
+ if (loglevel < 0) {
+ printf(" VALUE\tHEX\tSTRING\n");
+ printf("==============================================\n");
+ } else {
+ lprintf(loglevel, " VAL\tHEX\tSTRING");
+ lprintf(loglevel, "==============================================");
+ }
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (loglevel < 0) {
+ if (vs[i].val < 256)
+ printf(" %d\t0x%02x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
+ else
+ printf(" %d\t0x%04x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
+ } else {
+ if (vs[i].val < 256)
+ lprintf(loglevel, " %d\t0x%02x\t%s", vs[i].val, vs[i].val, vs[i].str);
+ else
+ lprintf(loglevel, " %d\t0x%04x\t%s", vs[i].val, vs[i].val, vs[i].str);
+ }
+ }
+
+ if (loglevel < 0)
+ printf("\n");
+ else
+ lprintf(loglevel, "");
+}
+
+/* print_valstr_2col - print value string list in two columns to log or stdout
+ *
+ * @vs: value string list to print
+ * @title: name of this value string list
+ * @loglevel: what log level to print, -1 for stdout
+ */
+void
+print_valstr_2col(const struct valstr * vs, const char * title, int loglevel)
+{
+ int i;
+
+ if (vs == NULL)
+ return;
+
+ if (title != NULL) {
+ if (loglevel < 0)
+ printf("\n%s:\n\n", title);
+ else
+ lprintf(loglevel, "\n%s:\n", title);
+ }
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (vs[i+1].str == NULL) {
+ /* last one */
+ if (loglevel < 0) {
+ printf(" %4d %-32s\n", vs[i].val, vs[i].str);
+ } else {
+ lprintf(loglevel, " %4d %-32s\n", vs[i].val, vs[i].str);
+ }
+ }
+ else {
+ if (loglevel < 0) {
+ printf(" %4d %-32s %4d %-32s\n",
+ vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
+ } else {
+ lprintf(loglevel, " %4d %-32s %4d %-32s\n",
+ vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
+ }
+ i++;
+ }
+ }
+
+ if (loglevel < 0)
+ printf("\n");
+ else
+ lprintf(loglevel, "");
+}
+
+/* ipmi_csum - calculate an ipmi checksum
+ *
+ * @d: buffer to check
+ * @s: position in buffer to start checksum from
+ */
+uint8_t
+ipmi_csum(uint8_t * d, int s)
+{
+ uint8_t c = 0;
+ for (; s > 0; s--, d++)
+ c += *d;
+ return -c;
+}
+
+/* ipmi_open_file - safely open a file for reading or writing
+ *
+ * @file: filename
+ * @rw: read-write flag, 1=write
+ *
+ * returns pointer to file handler on success
+ * returns NULL on error
+ */
+FILE *
+ipmi_open_file(const char * file, int rw)
+{
+#ifndef WIN32
+ struct stat st1, st2;
+#endif
+ FILE * fp;
+
+ /* verify existence */
+#ifdef WIN32
+ if (1 == 0)
+#else
+ if (lstat(file, &st1) < 0)
+#endif
+ {
+ if (rw) {
+ /* does not exist, ok to create */
+ fp = fopen(file, "w");
+ if (fp == NULL) {
+ lperror(LOG_ERR, "Unable to open file %s "
+ "for write", file);
+ return NULL;
+ }
+ /* created ok, now return the descriptor */
+ return fp;
+ } else {
+ lprintf(LOG_ERR, "File %s does not exist", file);
+ return NULL;
+ }
+ }
+
+#ifndef ENABLE_FILE_SECURITY
+ if (!rw) {
+ /* on read skip the extra checks */
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+ lperror(LOG_ERR, "Unable to open file %s", file);
+ return NULL;
+ }
+ return fp;
+ }
+#endif
+
+#ifndef WIN32
+ /* it exists - only regular files, not links */
+ if (S_ISREG(st1.st_mode) == 0) {
+ lprintf(LOG_ERR, "File %s has invalid mode: %d",
+ file, st1.st_mode);
+ return NULL;
+ }
+
+ /* allow only files with 1 link (itself) */
+ if (st1.st_nlink != 1) {
+ lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
+ file, (int)st1.st_nlink);
+ return NULL;
+ }
+#endif
+
+ fp = fopen(file, rw ? "w+" : "r");
+ if (fp == NULL) {
+ lperror(LOG_ERR, "Unable to open file %s", file);
+ return NULL;
+ }
+
+#ifndef WIN32
+ /* stat again */
+ if (fstat(fileno(fp), &st2) < 0) {
+ lperror(LOG_ERR, "Unable to stat file %s", file);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* verify inode */
+ if (st1.st_ino != st2.st_ino) {
+ lprintf(LOG_ERR, "File %s has invalid inode: %d != %d",
+ file, st1.st_ino, st2.st_ino);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* verify owner */
+ if (st1.st_uid != st2.st_uid) {
+ lprintf(LOG_ERR, "File %s has invalid user id: %d != %d",
+ file, st1.st_uid, st2.st_uid);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* verify inode */
+ if (st2.st_nlink != 1) {
+ lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
+ file, st2.st_nlink);
+ fclose(fp);
+ return NULL;
+ }
+#endif
+
+ return fp;
+}
+
+void
+ipmi_start_daemon(struct ipmi_intf *intf)
+{
+#ifndef WIN32
+ pid_t pid;
+ int fd, i;
+#ifdef SIGHUP
+ sigset_t sighup;
+#endif
+
+ /* if we are started from init no need to become daemon */
+ if (getppid() == 1)
+ return;
+
+#ifdef SIGHUP
+ sigemptyset(&sighup);
+ sigaddset(&sighup, SIGHUP);
+ if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
+ fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
+ signal(SIGHUP, SIG_IGN);
+#endif
+#ifdef SIGTTOU
+ signal(SIGTTOU, SIG_IGN);
+#endif
+#ifdef SIGTTIN
+ signal(SIGTTIN, SIG_IGN);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, SIG_IGN);
+#endif
+#ifdef SIGTSTP
+ signal(SIGTSTP, SIG_IGN);
+#endif
+
+ pid = (pid_t) fork();
+ if (pid < 0 || pid > 0)
+ exit(0);
+
+#if defined(SIGTSTP) && defined(TIOCNOTTY)
+ if (setpgid(0, getpid()) == -1)
+ exit(1);
+ if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
+ ioctl(fd, TIOCNOTTY, NULL);
+ close(fd);
+ }
+#else
+ if (setpgid(0, 0) == -1)
+ exit(1);
+ pid = (pid_t) fork();
+ if (pid < 0 || pid > 0)
+ exit(0);
+#endif
+
+ i = chdir("/");
+ umask(0);
+
+ for (fd=0; fd<64; fd++) {
+ if (fd != intf->fd)
+ close(fd);
+ }
+
+ fd = open("/dev/null", O_RDWR);
+ i = dup(0);
+ i = dup(0);
+#endif
+}