#include "inc.h"
#include "conv.h"
static void setup(int, char **, Cmd_info *);
static void setcom(Cmd_info *, Cmd_func);
static void usage(void);
static void sigexit(int sig);
static int notfound(Cmd_info *);
static void check_swap();
const char *
_ar_msg(Msg mid)
{
return (gettext(MSG_ORIG(mid)));
}
void
establish_sighandler(void (*handler)())
{
static const int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
int i;
if (handler == SIG_IGN) {
for (i = 0; signum[i]; i++)
(void) signal(signum[i], SIG_IGN);
} else {
for (i = 0; signum[i]; i++)
if (signal(signum[i], SIG_IGN) != SIG_IGN)
(void) signal(signum[i], handler);
}
}
int
main(int argc, char **argv, char *envp[])
{
int fd;
Cmd_info *cmd_info;
int ret;
char *new = NULL;
#ifndef XPG4
(void) conv_check_native(argv, envp);
#endif
(void) setlocale(LC_ALL, MSG_ORIG(MSG_STR_EMPTY));
(void) textdomain(MSG_ORIG(MSG_SUNW_OST_SGS));
establish_sighandler(sigexit);
cmd_info = (Cmd_info *)calloc(1, sizeof (Cmd_info));
if (cmd_info == NULL) {
int err = errno;
(void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err));
exit(1);
}
if (argc < 2)
usage();
if (argv[1][0] != '-') {
new = (char *)malloc(strlen(argv[1]) + 2);
if (new == NULL) {
int err = errno;
(void) fprintf(stderr, MSG_INTL(MSG_MALLOC),
strerror(err));
exit(1);
}
(void) strcpy(new, MSG_ORIG(MSG_STR_HYPHEN));
(void) strcat(new, argv[1]);
argv[1] = new;
}
setup(argc, argv, cmd_info);
if (cmd_info->opt_flgs & z_FLAG)
check_swap();
cmd_info->modified = (cmd_info->opt_flgs & s_FLAG);
fd = getaf(cmd_info);
if (fd == -1) {
boolean_t req_arg = (cmd_info->opt_flgs & (d_FLAG | m_FLAG |
p_FLAG | t_FLAG | x_FLAG)) != 0;
boolean_t req_r = (cmd_info->opt_flgs & r_FLAG) &&
(cmd_info->opt_flgs & (a_FLAG | b_FLAG));
boolean_t req_s = (cmd_info->opt_flgs & s_FLAG) &&
(cmd_info->opt_flgs & (r_FLAG | q_FLAG)) == 0;
if (req_arg || req_r || req_s) {
(void) fprintf(stderr, MSG_INTL(MSG_NOT_FOUND_AR),
cmd_info->arnam);
exit(1);
}
}
(*cmd_info->comfun)(cmd_info);
if (cmd_info->modified) {
writefile(cmd_info);
} else
(void) close(fd);
ret = notfound(cmd_info);
if (cmd_info->opt_flgs & z_FLAG)
check_swap();
free(new);
free(cmd_info);
return (ret);
}
static void
setup(int argc, char *argv[], Cmd_info *cmd_info)
{
int Vflag = 0;
int c;
int usage_err = 0;
while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
switch (c) {
case 'a':
cmd_info->opt_flgs |= a_FLAG;
cmd_info->ponam = trim(optarg);
break;
case 'b':
case 'i':
cmd_info->opt_flgs |= b_FLAG;
cmd_info->ponam = trim(optarg);
break;
case 'c':
cmd_info->opt_flgs |= c_FLAG;
break;
case 'd':
setcom(cmd_info, dcmd);
cmd_info->opt_flgs |= d_FLAG;
break;
case 'l':
break;
case 'm':
setcom(cmd_info, mcmd);
cmd_info->opt_flgs |= m_FLAG;
break;
case 'p':
setcom(cmd_info, pcmd);
cmd_info->opt_flgs |= p_FLAG;
break;
case 'q':
setcom(cmd_info, qcmd);
cmd_info->opt_flgs |= q_FLAG;
break;
case 'r':
setcom(cmd_info, rcmd);
cmd_info->opt_flgs |= r_FLAG;
break;
case 's':
cmd_info->opt_flgs |= s_FLAG;
break;
case 'S':
cmd_info->opt_flgs |= S_FLAG;
break;
case 't':
setcom(cmd_info, tcmd);
cmd_info->opt_flgs |= t_FLAG;
break;
case 'u':
cmd_info->opt_flgs |= u_FLAG;
break;
case 'v':
cmd_info->opt_flgs |= v_FLAG;
break;
case 'x':
setcom(cmd_info, xcmd);
cmd_info->opt_flgs |= x_FLAG;
break;
case 'z':
cmd_info->opt_flgs |= z_FLAG;
break;
case 'V':
if (Vflag == 0) {
(void) fprintf(stderr,
MSG_ORIG(MSG_FMT_VERSION),
(const char *)SGU_PKG,
(const char *)SGU_REL);
Vflag++;
}
break;
case 'C':
cmd_info->opt_flgs |= C_FLAG;
break;
case 'M':
break;
case 'T':
cmd_info->opt_flgs |= T_FLAG;
break;
case ':':
(void) fprintf(stderr, MSG_INTL(MSG_USAGE_OPERAND),
optopt);
usage_err++;
break;
case '?':
(void) fprintf(stderr, MSG_INTL(MSG_USAGE_OPTION),
optopt);
usage_err++;
break;
}
}
if (usage_err || argc - optind < 1)
usage();
cmd_info->arnam = argv[optind];
cmd_info->namv = &argv[optind+1];
cmd_info->namc = argc - optind - 1;
if (cmd_info->comfun == NULL) {
if ((cmd_info->opt_flgs & s_FLAG) != 0) {
if ((cmd_info->opt_flgs & ~(s_FLAG | v_FLAG)) != 0) {
(void) fprintf(stderr,
MSG_INTL(MSG_USAGE_S_BAD_ARG));
exit(1);
}
if (cmd_info->namc > 0) {
(void) fprintf(stderr,
MSG_INTL(MSG_USAGE_S_EXTRA_AR));
exit(1);
}
setcom(cmd_info, tcmd);
} else if ((cmd_info->opt_flgs & (d_FLAG | r_FLAG | q_FLAG |
s_FLAG | t_FLAG | p_FLAG | m_FLAG | x_FLAG)) == 0) {
(void) fprintf(stderr, MSG_INTL(MSG_USAGE_REQ_FLAG));
exit(1);
}
}
}
static void
setcom(Cmd_info *cmd_info, Cmd_func *fun)
{
if (cmd_info->comfun != NULL) {
(void) fprintf(stderr, MSG_INTL(MSG_USAGE_TOO_MANY));
exit(1);
}
cmd_info->comfun = fun;
}
static void
usage(void)
{
(void) fprintf(stderr, MSG_INTL(MSG_USAGE));
exit(1);
}
static void
sigexit(int sig)
{
exit(100);
}
static int
notfound(Cmd_info *cmd_info)
{
int i, n;
n = 0;
for (i = 0; i < cmd_info->namc; i++)
if (cmd_info->namv[i]) {
(void) fprintf(stderr, MSG_INTL(MSG_NOT_FOUND_FILE),
cmd_info->namv[i]);
n++;
}
return (n);
}
static void
check_swap(void)
{
(void) system(MSG_ORIG(MSG_CMD_SWAP));
}