/*
 * Copyright 1998-2003 by Albert Cahalan; all rights resered.
 * This file may be used subject to the terms and conditions of the
 * GNU Library General Public License Version 2, or any later version
 * at your option, as published by the Free Software Foundation.
 * 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 Library General Public License for more details.
 */
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "sig.h"

/* Linux signals:
 *
 * SIGSYS is required by Unix98.
 * SIGEMT is part of SysV, BSD, and ancient UNIX tradition.
 *
 * They are provided by these Linux ports: alpha, mips, sparc, and sparc64.
 * You get SIGSTKFLT and SIGUNUSED instead on i386, m68k, ppc, and arm.
 * (this is a Linux & libc bug -- both must be fixed)
 *
 * Total garbage: SIGIO SIGINFO SIGIOT SIGLOST SIGCLD
 *                 (popular ones are handled as aliases)
 * Nearly garbage: SIGSTKFLT SIGUNUSED (nothing else to fill slots)
 */

/* Linux 2.3.29 replaces SIGUNUSED with the standard SIGSYS signal */
#ifndef SIGSYS
#  warning Standards require that <signal.h> define SIGSYS
#  define SIGSYS SIGUNUSED
#endif

/* If we see both, it is likely SIGSTKFLT (junk) was replaced. */
#ifdef SIGEMT
#  undef SIGSTKFLT
#endif

#ifndef SIGRTMIN
#  warning Standards require that <signal.h> define SIGRTMIN; assuming 32
#  define SIGRTMIN 32
#endif

/* It seems the SPARC libc does not know the kernel supports SIGPWR. */
#ifndef SIGPWR
#  warning Your header files lack SIGPWR. (assuming it is number 29)
#  define SIGPWR 29
#endif

typedef struct mapstruct {
  const char *name;
  int num;
} mapstruct;


static const mapstruct sigtable[] = {
  {"ABRT",   SIGABRT},  /* IOT */
  {"ALRM",   SIGALRM},
  {"BUS",    SIGBUS},
  {"CHLD",   SIGCHLD},  /* CLD */
  {"CONT",   SIGCONT},
#ifdef SIGEMT
  {"EMT",    SIGEMT},
#endif
  {"FPE",    SIGFPE},
  {"HUP",    SIGHUP},
  {"ILL",    SIGILL},
  {"INT",    SIGINT},
  {"KILL",   SIGKILL},
  {"PIPE",   SIGPIPE},
  {"POLL",   SIGPOLL},  /* IO */
  {"PROF",   SIGPROF},
  {"PWR",    SIGPWR},
  {"QUIT",   SIGQUIT},
  {"SEGV",   SIGSEGV},
#ifdef SIGSTKFLT
  {"STKFLT", SIGSTKFLT},
#endif
  {"STOP",   SIGSTOP},
  {"SYS",    SIGSYS},   /* UNUSED */
  {"TERM",   SIGTERM},
  {"TRAP",   SIGTRAP},
  {"TSTP",   SIGTSTP},
  {"TTIN",   SIGTTIN},
  {"TTOU",   SIGTTOU},
  {"URG",    SIGURG},
  {"USR1",   SIGUSR1},
  {"USR2",   SIGUSR2},
  {"VTALRM", SIGVTALRM},
  {"WINCH",  SIGWINCH},
  {"XCPU",   SIGXCPU},
  {"XFSZ",   SIGXFSZ}
};

static const int number_of_signals = sizeof(sigtable)/sizeof(mapstruct);

static int compare_signal_names(const void *a, const void *b){
  return strcasecmp( ((const mapstruct*)a)->name, ((const mapstruct*)b)->name );
}

/* return -1 on failure */
int signal_name_to_number(const char *restrict name){
  long val;
  int offset;

  /* clean up name */
  if(!strncasecmp(name,"SIG",3)) name += 3;

  if(!strcasecmp(name,"CLD")) return SIGCHLD;
  if(!strcasecmp(name,"IO"))  return SIGPOLL;
  if(!strcasecmp(name,"IOT")) return SIGABRT;

  /* search the table */
  {
    const mapstruct ms = {name,0};
    const mapstruct *restrict const ptr = bsearch(
      &ms,
      sigtable,
      number_of_signals,
      sizeof(mapstruct),
      compare_signal_names
    );
    if(ptr) return ptr->num;
  }

  if(!strcasecmp(name,"RTMIN")) return SIGRTMIN;
  if(!strcasecmp(name,"EXIT"))  return 0;
  if(!strcasecmp(name,"NULL"))  return 0;

  offset = 0;
  if(!strncasecmp(name,"RTMIN+",6)){
    name += 6;
    offset = SIGRTMIN;
  }

  /* not found, so try as a number */
  {
    char *endp;
    val = strtol(name,&endp,10);
    if(*endp || endp==name) return -1; /* not valid */
  }
  if(val+SIGRTMIN>127) return -1; /* not valid */
  return val+offset;
}

const char *signal_number_to_name(int signo){
  static char buf[32];
  int n = number_of_signals;
  signo &= 0x7f; /* need to process exit values too */
  while(n--){
    if(sigtable[n].num==signo) return sigtable[n].name;
  }
  if(signo == SIGRTMIN) return "RTMIN";
  if(signo) sprintf(buf, "RTMIN+%d", signo-SIGRTMIN);
  else      strcpy(buf,"0");  /* AIX has NULL; Solaris has EXIT */
  return buf;
}

int print_given_signals(int argc, const char *restrict const *restrict argv, int max_line){
  char buf[1280]; /* 128 signals, "RTMIN+xx" is largest */
  int ret = 0;  /* to be used as exit code by caller */
  int place = 0; /* position on this line */
  int amt;
  if(argc > 128) return 1;
  while(argc--){
    char tmpbuf[16];
    const char *restrict const txt = *argv;
    if(*txt >= '0' && *txt <= '9'){
      long val;
      char *endp;
      val = strtol(txt,&endp,10);
      if(*endp){
        fprintf(stderr, "Signal \"%s\" not known.\n", txt);
        ret = 1;
        goto end;
      }
      amt = sprintf(tmpbuf, "%s", signal_number_to_name(val));
    }else{
      int sno;
      sno = signal_name_to_number(txt);
      if(sno == -1){
        fprintf(stderr, "Signal \"%s\" not known.\n", txt);
        ret = 1;
        goto end;
      }
      amt = sprintf(tmpbuf, "%d", sno);
    }

    if(!place){
      strcpy(buf,tmpbuf);
      place = amt;
      goto end;
    }
    if(amt+place+1 > max_line){
      printf("%s\n", buf);
      strcpy(buf,tmpbuf);
      place = amt;
      goto end;
    }
    sprintf(buf+place, " %s", tmpbuf);
    place += amt+1;
end:
    argv++;
  }
  if(place) printf("%s\n", buf);
  return ret;
}

void pretty_print_signals(void){
  int i = 0;
  while(++i <= number_of_signals){
    int n;
    n = printf("%2d %s", i, signal_number_to_name(i));
    if(i%7) printf("           \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
    else printf("\n");
  }
  if((i-1)%7) printf("\n");
}

void unix_print_signals(void){
  int pos = 0;
  int i = 0;
  while(++i <= number_of_signals){
    if(i-1) printf("%c", (pos>73)?(pos=0,'\n'):(pos++,' ') );
    pos += printf("%s", signal_number_to_name(i));
  }
  printf("\n");
}

/* sanity check */
static int init_signal_list(void) __attribute__((constructor));
static int init_signal_list(void){
  if(number_of_signals != 31){
    fprintf(stderr, "WARNING: %d signals -- adjust and recompile.\n", number_of_signals);
  }
  return 0;
}
