Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  mconsole_user.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */


#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include "mconsole.h"

static struct mconsole_command commands[] = {
 /*
 * With uts namespaces, uts information becomes process-specific, so
 * we need a process context.  If we try handling this in interrupt
 * context, we may hit an exiting process without a valid uts
 * namespace.
 */

 { "version", mconsole_version, MCONSOLE_PROC },
 { "halt", mconsole_halt, MCONSOLE_PROC },
 { "reboot", mconsole_reboot, MCONSOLE_PROC },
 { "config", mconsole_config, MCONSOLE_PROC },
 { "remove", mconsole_remove, MCONSOLE_PROC },
 { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
 { "help", mconsole_help, MCONSOLE_INTR },
 { "cad", mconsole_cad, MCONSOLE_INTR },
 { "stop", mconsole_stop, MCONSOLE_PROC },
 { "go", mconsole_go, MCONSOLE_INTR },
 { "log", mconsole_log, MCONSOLE_INTR },
 { "proc", mconsole_proc, MCONSOLE_PROC },
 { "stack", mconsole_stack, MCONSOLE_INTR },
};

/* Initialized in mconsole_init, which is an initcall */
char mconsole_socket_name[256];

static int mconsole_reply_v0(struct mc_request *req, char *reply)
{
 struct iovec iov;
 struct msghdr msg;

 iov.iov_base = reply;
 iov.iov_len = strlen(reply);

 msg.msg_name = &(req->origin);
 msg.msg_namelen = req->originlen;
 msg.msg_iov = &iov;
 msg.msg_iovlen = 1;
 msg.msg_control = NULL;
 msg.msg_controllen = 0;
 msg.msg_flags = 0;

 return sendmsg(req->originating_fd, &msg, 0);
}

static struct mconsole_command *mconsole_parse(struct mc_request *req)
{
 struct mconsole_command *cmd;
 int i;

 for (i = 0; i < ARRAY_SIZE(commands); i++) {
  cmd = &commands[i];
  if (!strncmp(req->request.data, cmd->command,
       strlen(cmd->command))) {
   return cmd;
  }
 }
 return NULL;
}

#ifndef MIN
#define MIN(a,b) ((a)<(b) ? (a):(b))
#endif

#define STRINGX(x) #x
#define STRING(x) STRINGX(x)

int mconsole_get_request(int fd, struct mc_request *req)
{
 int len;

 req->originlen = sizeof(req->origin);
 req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
       (struct sockaddr *) req->origin, &req->originlen);
 if (req->len < 0)
  return 0;

 req->originating_fd = fd;

 if (req->request.magic != MCONSOLE_MAGIC) {
  /* Unversioned request */
  len = MIN(sizeof(req->request.data) - 1,
     strlen((char *) &req->request));
  memmove(req->request.data, &req->request, len);
  req->request.data[len] = '\0';

  req->request.magic = MCONSOLE_MAGIC;
  req->request.version = 0;
  req->request.len = len;

  mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
      "not supported by this driver");
  return 0;
 }

 if (req->request.len >= MCONSOLE_MAX_DATA) {
  mconsole_reply(req, "Request too large", 1, 0);
  return 0;
 }
 if (req->request.version != MCONSOLE_VERSION) {
  mconsole_reply(req, "This driver only supports version "
          STRING(MCONSOLE_VERSION) " clients", 1, 0);
 }

 req->request.data[req->request.len] = '\0';
 req->cmd = mconsole_parse(req);
 if (req->cmd == NULL) {
  mconsole_reply(req, "Unknown command", 1, 0);
  return 0;
 }

 return 1;
}

int mconsole_reply_len(struct mc_request *req, const char *str, int total,
         int err, int more)
{
 /*
 * XXX This is a stack consumption problem.  It'd be nice to
 * make it global and serialize access to it, but there are a
 * ton of callers to this function.
 */

 struct mconsole_reply reply;
 int len, n;

 do {
  reply.err = err;

  /* err can only be true on the first packet */
  err = 0;

  len = MIN(total, MCONSOLE_MAX_DATA - 1);

  if (len == total) reply.more = more;
  else reply.more = 1;

  memcpy(reply.data, str, len);
  reply.data[len] = '\0';
  total -= len;
  str += len;
  reply.len = len + 1;

  len = sizeof(reply) + reply.len - sizeof(reply.data);

  n = sendto(req->originating_fd, &reply, len, 0,
      (struct sockaddr *) req->origin, req->originlen);

  if (n < 0)
   return -errno;
 } while (total > 0);
 return 0;
}

int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
{
 return mconsole_reply_len(req, str, strlen(str), err, more);
}


int mconsole_unlink_socket(void)
{
 unlink(mconsole_socket_name);
 return 0;
}

static int notify_sock = -1;

int mconsole_notify(char *sock_name, int type, const void *data, int len)
{
 struct sockaddr_un target;
 struct mconsole_notify packet;
 int n, err = 0;

 lock_notify();
 if (notify_sock < 0) {
  notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
  if (notify_sock < 0) {
   err = -errno;
   printk(UM_KERN_ERR "mconsole_notify - socket failed, "
          "errno = %d\n", errno);
  }
 }
 unlock_notify();

 if (err)
  return err;

 target.sun_family = AF_UNIX;
 strcpy(target.sun_path, sock_name);

 packet.magic = MCONSOLE_MAGIC;
 packet.version = MCONSOLE_VERSION;
 packet.type = type;
 len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
 packet.len = len;
 memcpy(packet.data, data, len);

 err = 0;
 len = sizeof(packet) + packet.len - sizeof(packet.data);
 n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
     sizeof(target));
 if (n < 0) {
  err = -errno;
  printk(UM_KERN_ERR "mconsole_notify - sendto failed, "
         "errno = %d\n", errno);
 }
 return err;
}

Messung V0.5
C=97 H=94 G=95

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge