extern int pidof_main(int argc, char **argv) { int opt, n = 0; int single_flag = 0; int fail = 1; /* do normal option parsing */ while ((opt = getopt(argc, argv, "s")) > 0) { switch (opt) { case 's': single_flag = 1; break; default: bb_show_usage(); } } /* Looks like everything is set to go. */ while(optind < argc) { long *pidList; long *pl; pidList = find_pid_by_name(argv[optind]); for(pl = pidList; *pl > 0; pl++) { printf("%s%ld", (n++ ? " " : ""), *pl); fail = 0; if (single_flag) break; } free(pidList); optind++; } printf("\n"); return fail ? EXIT_FAILURE : EXIT_SUCCESS; }
int mknod_main(int argc, char **argv) { mode_t mode; dev_t dev; const char *name; mode = getopt_mk_fifo_nod(argv); argv += optind; argc -= optind; if (argc >= 2) { name = strchr(modes_chars, argv[1][0]); if (name != NULL) { mode |= modes_cubp[(int)(name[4])]; dev = 0; if (*name != 'p') { argc -= 2; if (argc == 2) { /* Autodetect what the system supports; these macros should * optimize out to two constants. */ dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)), xatoul_range(argv[3], 0, minor(UINT_MAX))); } } if (argc == 2) { name = *argv; if (mknod(name, mode, dev) == 0) { return EXIT_SUCCESS; } bb_simple_perror_msg_and_die(name); } } } bb_show_usage(); }
int dos2unix_main(int argc, char *argv[]) { int ConvType = CT_AUTO; int o; //See if we are supposed to be doing dos2unix or unix2dos if (argv[0][0]=='d') { ConvType = CT_DOS2UNIX; } if (argv[0][0]=='u') { ConvType = CT_UNIX2DOS; } // process parameters while ((o = getopt(argc, argv, "du")) != EOF) { switch (o) { case 'd': ConvType = CT_UNIX2DOS; break; case 'u': ConvType = CT_DOS2UNIX; break; default: bb_show_usage(); } } if (optind < argc) { while(optind < argc) if ((o = convert(argv[optind++], ConvType)) < 0) break; } else o = convert(NULL, ConvType); return o; }
int fdformat_main(int argc,char **argv) { int ctrl; int verify; struct stat st; struct floppy_struct param; if (argc < 2) { bb_show_usage(); } verify != bb_getopt_ulflags(argc, argv, "n"); argv += optind; if (stat(*argv,&st) < 0 || access(*argv,W_OK) < 0) { bb_perror_msg_and_die(*argv); } if (!S_ISBLK(st.st_mode)) { bb_error_msg_and_die("%s: not a block device",*argv); /* do not test major - perhaps this was an USB floppy */ } ctrl = bb_xopen(*argv,O_WRONLY); if (ioctl(ctrl,FDGETPRM,(long) ¶m) < 0) { bb_perror_msg_and_die("Could not determine current format type"); } printf("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n", (param.head == 2) ? "Double" : "Single", param.track, param.sect,param.size >> 1); format_disk(ctrl, *argv, ¶m); close(ctrl); if (verify) { verify_disk(*argv, ¶m); } return EXIT_SUCCESS; }
/* ________________________________________________________________________ */ int nslookup_main(int argc, char **argv) { struct hostent *host; /* * initialize DNS structure _res used in printing the default * name server and in the explicit name server option feature. */ res_init(); /* * We allow 1 or 2 arguments. * The first is the name to be looked up and the second is an * optional DNS server with which to do the lookup. * More than 3 arguments is an error to follow the pattern of the * standard nslookup */ if (argc < 2 || *argv[1]=='-' || argc > 3) bb_show_usage(); else if(argc == 3) set_default_dns(argv[2]); server_print(); if (is_ip_address(argv[1])) { host = gethostbyaddr_wrapper(argv[1]); } else { host = xgethostbyname(argv[1]); } hostent_fprint(host, "Name: "); if (host) { return EXIT_SUCCESS; } return EXIT_FAILURE; }
int nslookup_main(int argc, char **argv) { /* We allow 1 or 2 arguments. * The first is the name to be looked up and the second is an * optional DNS server with which to do the lookup. * More than 3 arguments is an error to follow the pattern of the * standard nslookup */ if (argc < 2 || *argv[1] == '-' || argc > 3) bb_show_usage(); /* initialize DNS structure _res used in printing the default * name server and in the explicit name server option feature. */ res_init(); /* rfc2133 says this enables IPv6 lookups */ /* (but it also says "may be enabled in /etc/resolv.conf|) */ /*_res.options |= RES_USE_INET6;*/ if(argc == 3) set_default_dns(argv[2]); server_print(); return print_host(argv[1], "Name:"); }
extern int freeramdisk_main(int argc, char **argv) { int result; int fd; if (argc != 2) { bb_show_usage(); } fd = bb_xopen(argv[1], O_RDWR); result = ioctl(fd, BLKFLSBUF); #ifdef CONFIG_FEATURE_CLEAN_UP close(fd); #endif if (result < 0) { bb_perror_msg_and_die("failed ioctl on %s", argv[1]); } /* Don't bother closing. Exit does * that, so we can save a few bytes */ return EXIT_SUCCESS; }
int od_main(int argc, char **argv) { int ch; int first = 1; char *p; bb_dump_vflag = FIRST; bb_dump_length = -1; while ((ch = getopt(argc, argv, od_opts)) > 0) { if (ch == 'v') { bb_dump_vflag = ALL; } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) { if (first) { first = 0; bb_dump_add("\"%07.7_Ao\n\""); bb_dump_add("\"%07.7_ao \""); } else { bb_dump_add("\" \""); } bb_dump_add(add_strings[(int)od_o2si[(p-od_opts)]]); } else { /* P, p, s, w, or other unhandled */ bb_show_usage(); } } if (!bb_dump_fshead) { bb_dump_add("\"%07.7_Ao\n\""); bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); } argc -= optind; argv += optind; odoffset(argc, &argv); return(bb_dump_dump(argv)); }
int sleep_main(int argc UNUSED_PARAM, char **argv) { duration_t duration; ++argv; if (!*argv) bb_show_usage(); #if ENABLE_FEATURE_FANCY_SLEEP # if ENABLE_FLOAT_DURATION /* undo busybox.c setlocale */ setlocale(LC_NUMERIC, "C"); # endif duration = 0; do { duration += parse_duration_str(*argv); } while (*++argv); sleep_for_duration(duration); #else /* simple */ duration = xatou(*argv); sleep(duration); #endif return EXIT_SUCCESS; }
int date_main(int argc, char **argv) { char *date_str = NULL; char *date_fmt = NULL; int set_time; int utc; time_t tm; unsigned long opt; struct tm tm_time; char *filename = NULL; int ifmt = 0; char *isofmt_arg; char *hintfmt_arg; bb_opt_complementally = "?:d--s:s--d"; opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" USE_FEATURE_DATE_ISOFMT("I::D:"), &date_str, &date_str, &filename USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); set_time = opt & DATE_OPT_SET; utc = opt & DATE_OPT_UTC; if (utc && putenv("TZ=UTC0") != 0) { bb_error_msg_and_die(bb_msg_memory_exhausted); } if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { if (!isofmt_arg) { ifmt = 1; } else { char *isoformats[]={"date","hours","minutes","seconds"}; for(ifmt = 4; ifmt;) if(!strcmp(isofmt_arg,isoformats[--ifmt])) break; } if (!ifmt) { bb_show_usage(); } } /* XXX, date_fmt == NULL from this always */ if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { date_fmt = &argv[optind][1]; /* Skip over the '+' */ } else if (date_str == NULL) { set_time = 1; date_str = argv[optind]; } /* Now we have parsed all the information except the date format which depends on whether the clock is being set or read */ if(filename) { struct stat statbuf; xstat(filename,&statbuf); tm=statbuf.st_mtime; } else time(&tm); memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); /* Zero out fields - take her back to midnight! */ if (date_str != NULL) { tm_time.tm_sec = 0; tm_time.tm_min = 0; tm_time.tm_hour = 0; /* Process any date input to UNIX time since 1 Jan 1970 */ if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) { strptime(date_str, hintfmt_arg, &tm_time); } else if (strchr(date_str, ':') != NULL) { date_conv_ftime(&tm_time, date_str); } else { date_conv_time(&tm_time, date_str); } /* Correct any day of week and day of year etc. fields */ tm_time.tm_isdst = -1; /* Be sure to recheck dst. */ tm = mktime(&tm_time); if (tm < 0) { bb_error_msg_and_die(bb_msg_invalid_date, date_str); } if (utc && putenv("TZ=UTC0") != 0) { bb_error_msg_and_die(bb_msg_memory_exhausted); } /* if setting time, set it */ if (set_time && stime(&tm) < 0) { bb_perror_msg("cannot set date"); } } /* Display output */ /* Deal with format string */ if (date_fmt == NULL) { /* Start with the default case */ date_fmt = (opt & DATE_OPT_RFC2822 ? (utc ? "%a, %d %b %Y %H:%M:%S GMT" : "%a, %d %b %Y %H:%M:%S %z") : "%a %b %e %H:%M:%S %Z %Y"); if (ENABLE_FEATURE_DATE_ISOFMT) { if (ifmt == 4) date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z"; else if (ifmt == 3) date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z"; else if (ifmt == 2) date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z"; else if (ifmt == 1) date_fmt = "%Y-%m-%d"; } } if (*date_fmt == '\0') { /* With no format string, just print a blank line */ *bb_common_bufsiz1=0; } else { /* Handle special conversions */ if (strncmp(date_fmt, "%f", 2) == 0) { date_fmt = "%Y.%m.%d-%H:%M:%S"; } /* Generate output string */ strftime(bb_common_bufsiz1, 200, date_fmt, &tm_time); } puts(bb_common_bufsiz1); return EXIT_SUCCESS; }
int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) { unsigned opt; char *signame; char *startas; char *chuid; #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY // char *retry_arg = NULL; // int retries = -1; char *opt_N; #endif INIT_G(); opt = GETOPT32(argv, "^" "KSbqtma:n:s:u:c:x:p:" IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") /* -K or -S is required; they are mutually exclusive */ /* -p is required if -m is given */ /* -xpun (at least one) is required if -K is given */ /* -xa (at least one) is required if -S is given */ /* -q turns off -v */ "\0" "K:S:K--S:S--K:m?p:K?xpun:S?xa" IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"), LONGOPTS &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) /* We accept and ignore -R <param> / --retry <param> */ IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) ); if (opt & OPT_s) { signal_nr = get_signum(signame); if (signal_nr < 0) bb_show_usage(); } if (!(opt & OPT_a)) startas = execname; if (!execname) /* in case -a is given and -x is not */ execname = startas; if (execname) { G.execname_sizeof = strlen(execname) + 1; G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1); } // IF_FEATURE_START_STOP_DAEMON_FANCY( // if (retry_arg) // retries = xatoi_positive(retry_arg); // ) //argc -= optind; argv += optind; if (userspec) { user_id = bb_strtou(userspec, NULL, 10); if (errno) user_id = xuname2uid(userspec); } /* Both start and stop need to know current processes */ do_procinit(); if (opt & CTX_STOP) { int i = do_stop(); return (opt & OPT_OKNODO) ? 0 : (i <= 0); } if (G.found_procs) { if (!QUIET) printf("%s is already running\n%u\n", execname, (unsigned)G.found_procs->pid); return !(opt & OPT_OKNODO); } #ifdef OLDER_VERSION_OF_X if (execname) xstat(execname, &G.execstat); #endif *--argv = startas; if (opt & OPT_BACKGROUND) { #if BB_MMU bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS + DAEMON_DOUBLE_FORK); /* DAEMON_DEVNULL_STDIO is superfluous - * it's always done by bb_daemonize() */ #else /* Daemons usually call bb_daemonize_or_rexec(), but SSD can do * without: SSD is not itself a daemon, it _execs_ a daemon. * The usual NOMMU problem of "child can't run indefinitely, * it must exec" does not bite us: we exec anyway. */ pid_t pid = xvfork(); if (pid != 0) { /* parent */ /* why _exit? the child may have changed the stack, * so "return 0" may do bad things */ _exit(EXIT_SUCCESS); } /* Child */ setsid(); /* detach from controlling tty */ /* Redirect stdio to /dev/null, close extra FDs */ bb_daemon_helper(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS); #endif } if (opt & OPT_MAKEPID) { /* User wants _us_ to make the pidfile */ write_pidfile(pidfile); } if (opt & OPT_c) { struct bb_uidgid_t ugid; parse_chown_usergroup_or_die(&ugid, chuid); if (ugid.uid != (uid_t) -1L) { struct passwd *pw = xgetpwuid(ugid.uid); if (ugid.gid != (gid_t) -1L) pw->pw_gid = ugid.gid; /* initgroups, setgid, setuid: */ change_identity(pw); } else if (ugid.gid != (gid_t) -1L) { xsetgid(ugid.gid); setgroups(1, &ugid.gid); } } #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY if (opt & OPT_NICELEVEL) { /* Set process priority */ int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2); if (setpriority(PRIO_PROCESS, 0, prio) < 0) { bb_perror_msg_and_die("setpriority(%d)", prio); } } #endif execvp(startas, argv); bb_perror_msg_and_die("can't execute '%s'", startas); }
int ether_wake_main(int argc, char *argv[]) { const char *ifname = "eth0"; char *pass = NULL; unsigned long flags; unsigned char wol_passwd[6]; int wol_passwd_sz = 0; int s; /* Raw socket */ int pktsize; unsigned char outpack[1000]; struct ether_addr eaddr; struct whereto_t whereto; /* who to wake up */ /* handle misc user options */ flags = getopt32(argc, argv, "bi:p:", &ifname, &pass); if (optind == argc) bb_show_usage(); if (pass) wol_passwd_sz = get_wol_pw(pass, wol_passwd); /* create the raw socket */ s = make_socket(); /* now that we have a raw socket we can drop root */ xsetuid(getuid()); /* look up the dest mac address */ get_dest_addr(argv[optind], &eaddr); /* fill out the header of the packet */ pktsize = get_fill(outpack, &eaddr, flags /*& 1 [OPT_BROADCAST]*/); bb_debug_dump_packet(outpack, pktsize); /* Fill in the source address, if possible. */ #ifdef __linux__ { struct ifreq if_hwaddr; strncpy(if_hwaddr.ifr_name, ifname, sizeof(if_hwaddr.ifr_name)); if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname); memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6); # ifdef DEBUG { unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; printf("The hardware address (SIOCGIFHWADDR) of %s is type %d " "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname, if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); } # endif } #endif /* __linux__ */ bb_debug_dump_packet(outpack, pktsize); /* append the password if specified */ if (wol_passwd_sz > 0) { memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz); pktsize += wol_passwd_sz; } bb_debug_dump_packet(outpack, pktsize); /* This is necessary for broadcasts to work */ if (flags /*& 1 [OPT_BROADCAST]*/) { if (setsockopt_broadcast(s) < 0) bb_perror_msg("SO_BROADCAST"); } #if defined(PF_PACKET) { struct ifreq ifr; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) bb_perror_msg_and_die("SIOCGIFINDEX"); memset(&whereto, 0, sizeof(whereto)); whereto.sll_family = AF_PACKET; whereto.sll_ifindex = ifr.ifr_ifindex; /* The manual page incorrectly claims the address must be filled. We do so because the code may change to match the docs. */ whereto.sll_halen = ETH_ALEN; memcpy(whereto.sll_addr, outpack, ETH_ALEN); } #else whereto.sa_family = 0; strcpy(whereto.sa_data, ifname); #endif if (sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto, sizeof(whereto)) < 0) bb_perror_msg(bb_msg_write_error); close(s); return EXIT_SUCCESS; }
int main(int argc, char **argv) #endif { int ret; char *ptr; struct net_config net_config; struct disk_config disk_config; struct stat_config stat_config; int c; int doWarn=0; char *ifName=NULL; #ifdef LOSSTEST int seedSet = 0; int printSeed = 0; #endif #ifdef SIG_UNBLOCK atexit(signalForward); #endif disk_config.fileName=NULL; disk_config.pipeName=NULL; disk_config.flags = 0; net_config.portBase = 9000; net_config.ttl = 1; net_config.flags = 0; net_config.mcastRdv = NULL; net_config.exitWait = 500; net_config.startTimeout = 0; net_config.receiveTimeout = 0; stat_config.statPeriod = DEFLT_STAT_PERIOD; stat_config.printUncompressedPos = -1; stat_config.noProgress = 0; #ifdef WINDOWS /* windows is basically unusable with its default buffer size of 8k...*/ net_config.requestedBufSize = 1024*1024; #else net_config.requestedBufSize = 0; #endif ptr = strrchr(argv[0], '/'); if(!ptr) ptr = argv[0]; else ptr++; net_config.net_if = NULL; if (strcmp(ptr, "init") == 0) { doWarn = 1; disk_config.pipeName = strdup("/bin/gzip -dc"); disk_config.fileName = "/dev/hda"; } while( (c=getopt_l(argc, argv, "b:f:p:P:i:l:M:s:t:w:x:z:dkLnyZ")) != EOF ) { switch(c) { case 'f': disk_config.fileName=optarg; break; case 'i': ifName=optarg; break; case 'p': disk_config.pipeName=optarg; break; case 'P': net_config.portBase = atoi(optarg); break; case 'l': udpc_log = fopen(optarg, "a"); break; case 0x701: stat_config.noProgress = 1; break; case 't': /* ttl */ net_config.ttl = atoi(optarg); break; case 'M': net_config.mcastRdv = strdup(optarg); break; #ifdef BB_FEATURE_UDPCAST_FEC case 'L': fec_license(); break; #endif #ifdef LOSSTEST case 0x601: setWriteLoss(optarg); break; case 0x602: setReadLoss(optarg); break; case 0x603: seedSet=1; srandom(strtoul(optarg,0,0)); break; case 0x604: printSeed=1; break; case 0x605: setReadSwap(optarg); break; #endif case 'd': /* passive */ net_config.flags|=FLAG_PASSIVE; break; case 'n': /* nosync */ disk_config.flags|=FLAG_NOSYNC; break; case 'y': /* sync */ disk_config.flags|=FLAG_SYNC; break; case 'b': /* rcvbuf */ net_config.requestedBufSize=parseSize(optarg); break; case 'k': /* nokbd */ net_config.flags |= FLAG_NOKBD; break; case 'w': /* exit-wait */ net_config.exitWait = atoi(optarg); break; case 's': /* start-timeout */ net_config.startTimeout = atoi(optarg); break; case 0x801: /* receive-timeout */ net_config.receiveTimeout = atoi(optarg); break; case 'z': stat_config.statPeriod = atoi(optarg) * 1000; break; case 'x': stat_config.printUncompressedPos = atoi(optarg); break; case 'Z': net_config.flags |= FLAG_IGNORE_LOST_DATA; break; case '?': #ifndef NO_BB bb_show_usage(); #else usage(argv[0]); #endif } } fprintf(stderr, "Udp-receiver %s\n", version); #ifdef LOSSTEST if(!seedSet) srandomTime(printSeed); #endif signal(SIGINT, intHandler); #ifdef USE_SYSLOG openlog((const char *)"udpcast", LOG_NDELAY|LOG_PID, LOG_SYSLOG); #endif ret= startReceiver(doWarn, &disk_config, &net_config, &stat_config, ifName); if(ret < 0) { fprintf(stderr, "Receiver error\n"); } return ret; }
int ftpgetput_main(int argc, char **argv) { /* content-length of the file */ unsigned long opt; char *port = "ftp"; /* socket to ftp server */ FILE *control_stream; struct sockaddr_in s_in; /* continue a prev transfer (-c) */ ftp_host_info_t *server; int (*ftp_action)(ftp_host_info_t *, FILE *, const char *, char *) = NULL; /* Check to see if the command is ftpget or ftput */ #ifdef CONFIG_FTPPUT # ifdef CONFIG_FTPGET if (bb_applet_name[3] == 'p') { ftp_action = ftp_send; } # else ftp_action = ftp_send; # endif #endif #ifdef CONFIG_FTPGET # ifdef CONFIG_FTPPUT if (bb_applet_name[3] == 'g') { ftp_action = ftp_recieve; } # else ftp_action = ftp_recieve; # endif #endif /* Set default values */ server = xmalloc(sizeof(ftp_host_info_t)); server->user = "******"; server->password = "******"; verbose_flag = 0; /* * Decipher the command line */ bb_applet_long_options = ftpgetput_long_options; opt = bb_getopt_ulflags(argc, argv, "cvu:p:P:", &server->user, &server->password, &port); /* Process the non-option command line arguments */ if (argc - optind != 3) { bb_show_usage(); } if (opt & FTPGETPUT_OPT_CONTINUE) { do_continue = 1; } if (opt & FTPGETPUT_OPT_VERBOSE) { verbose_flag = 1; } /* We want to do exactly _one_ DNS lookup, since some * sites (i.e. ftp.us.debian.org) use round-robin DNS * and we want to connect to only one IP... */ server->s_in = &s_in; bb_lookup_host(&s_in, argv[optind]); s_in.sin_port = bb_lookup_port(port, "tcp", 21); if (verbose_flag) { printf("Connecting to %s[%s]:%d\n", argv[optind], inet_ntoa(s_in.sin_addr), ntohs(s_in.sin_port)); } /* Connect/Setup/Configure the FTP session */ control_stream = ftp_login(server); return(ftp_action(server, control_stream, argv[optind + 1], argv[optind + 2])); }
int addgroup_main(int argc UNUSED_PARAM, char **argv) { #if ENABLE_FEATURE_ADDUSER_TO_GROUP unsigned opts; #endif const char *gid = "0"; /* need to be root */ if (geteuid()) { bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); } /* Syntax: * addgroup group * addgroup --gid num group * addgroup user group * Check for min, max and missing args */ #if ENABLE_FEATURE_ADDUSER_TO_GROUP opts = #endif getopt32long(argv, "^" "g:S" "\0" "-1:?2", addgroup_longopts, &gid ); /* move past the commandline options */ argv += optind; //argc -= optind; #if ENABLE_FEATURE_ADDUSER_TO_GROUP if (argv[1]) { struct group *gr; if (opts & OPT_GID) { /* -g was there, but "addgroup -g num user group" * is a no-no */ bb_show_usage(); } /* check if group and user exist */ xuname2uid(argv[0]); /* unknown user: exit */ gr = xgetgrnam(argv[1]); /* unknown group: exit */ /* check if user is already in this group */ for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) { if (strcmp(argv[0], *(gr->gr_mem)) == 0) { /* user is already in group: do nothing */ return EXIT_SUCCESS; } } if (update_passwd(bb_path_group_file, argv[1], NULL, argv[0]) < 0) { return EXIT_FAILURE; } # if ENABLE_FEATURE_SHADOWPASSWDS update_passwd(bb_path_gshadow_file, argv[1], NULL, argv[0]); # endif } else #endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */ { die_if_bad_username(argv[0]); new_group(argv[0], xatou_range(gid, 0, CONFIG_LAST_ID)); } /* Reached only on success */ return EXIT_SUCCESS; }
/* Called only from main, once */ static int arp_set(char **args) { char *host; struct arpreq req; struct sockaddr sa; int flags; memset(&req, 0, sizeof(req)); host = *args++; if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } /* If a host has more than one address, use the correct one! */ memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr)); /* Fetch the hardware address. */ if (*args == NULL) { bb_error_msg_and_die("need hardware address"); } if (option_mask32 & ARP_OPT_D) { arp_getdevhw(*args++, &req.arp_ha, hw_set ? hw : NULL); } else { if (hw->input(*args++, &req.arp_ha) < 0) { bb_error_msg_and_die("invalid hardware address"); } } /* Check out any modifiers. */ flags = ATF_PERM | ATF_COM; while (*args != NULL) { switch (index_in_strings(options, *args)) { case 0: /* "pub" */ flags |= ATF_PUBL; args++; break; case 1: /* "priv" */ flags &= ~ATF_PUBL; args++; break; case 2: /* "temp" */ flags &= ~ATF_PERM; args++; break; case 3: /* "trail" */ flags |= ATF_USETRAILERS; args++; break; case 4: /* "dontpub" */ #ifdef HAVE_ATF_DONTPUB flags |= ATF_DONTPUB; #else bb_error_msg("feature ATF_DONTPUB is not supported"); #endif args++; break; case 5: /* "auto" */ #ifdef HAVE_ATF_MAGIC flags |= ATF_MAGIC; #else bb_error_msg("feature ATF_MAGIC is not supported"); #endif args++; break; case 6: /* "dev" */ if (*++args == NULL) bb_show_usage(); device = *args; args++; break; case 7: /* "netmask" */ if (*++args == NULL) bb_show_usage(); if (strcmp(*args, "255.255.255.255") != 0) { host = *args; if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); flags |= ATF_NETMASK; } args++; break; default: bb_show_usage(); break; } } /* Fill in the remainder of the request. */ req.arp_flags = flags; strncpy(req.arp_dev, device, sizeof(req.arp_dev)); /* Call the kernel. */ if (option_mask32 & ARP_OPT_v) bb_error_msg("SIOCSARP()"); xioctl(sockfd, SIOCSARP, &req); return 0; }
int less_main(int argc, char **argv) { int keypress; INIT_G(); /* TODO: -x: do not interpret backspace, -xx: tab also */ /* -xxx: newline also */ /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S")); argc -= optind; argv += optind; num_files = argc; files = argv; /* Another popular pager, most, detects when stdout * is not a tty and turns into cat. This makes sense. */ if (!isatty(STDOUT_FILENO)) return bb_cat(argv); if (!num_files) { if (isatty(STDIN_FILENO)) { /* Just "less"? No args and no redirection? */ bb_error_msg("missing filename"); bb_show_usage(); } } else { filename = xstrdup(files[0]); } if (option_mask32 & FLAG_TILDE) empty_line_marker = ""; kbd_fd = open(CURRENT_TTY, O_RDONLY); if (kbd_fd < 0) return bb_cat(argv); ndelay_on(kbd_fd); tcgetattr(kbd_fd, &term_orig); term_less = term_orig; term_less.c_lflag &= ~(ICANON | ECHO); term_less.c_iflag &= ~(IXON | ICRNL); /*term_less.c_oflag &= ~ONLCR;*/ term_less.c_cc[VMIN] = 1; term_less.c_cc[VTIME] = 0; get_terminal_width_height(kbd_fd, &width, &max_displayed_line); /* 20: two tabstops + 4 */ if (width < 20 || max_displayed_line < 3) return bb_cat(argv); max_displayed_line -= 2; /* We want to restore term_orig on exit */ bb_signals(BB_FATAL_SIGS, sig_catcher); #if ENABLE_FEATURE_LESS_WINCH signal(SIGWINCH, sigwinch_handler); #endif buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); reinitialize(); while (1) { #if ENABLE_FEATURE_LESS_WINCH while (WINCH_COUNTER) { again: winch_counter--; get_terminal_width_height(kbd_fd, &width, &max_displayed_line); /* 20: two tabstops + 4 */ if (width < 20) width = 20; if (max_displayed_line < 3) max_displayed_line = 3; max_displayed_line -= 2; free(buffer); buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); /* Avoid re-wrap and/or redraw if we already know * we need to do it again. These ops are expensive */ if (WINCH_COUNTER) goto again; re_wrap(); if (WINCH_COUNTER) goto again; buffer_fill_and_print(); /* This took some time. Loop back and check, * were there another SIGWINCH? */ } #endif keypress = less_getch(-1); /* -1: do not position cursor */ keypress_process(keypress); } }
static void PRS(int argc, char *argv[]) { int i, j; char *arg, *dev, *tmp = 0; char options[128]; int opt = 0; int opts_for_fsck = 0; struct sigaction sa; /* * Set up signal action */ memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = signal_cancel; sigaction(SIGINT, &sa, 0); sigaction(SIGTERM, &sa, 0); num_devices = 0; num_args = 0; instance_list = 0; for (i=1; i < argc; i++) { arg = argv[i]; if (!arg) continue; if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) { if (num_devices >= MAX_DEVICES) { bb_error_msg_and_die("too many devices"); } dev = blkid_get_devname(cache, arg, NULL); if (!dev && strchr(arg, '=')) { /* * Check to see if we failed because * /proc/partitions isn't found. */ if (access("/proc/partitions", R_OK) < 0) { bb_perror_msg_and_die("cannot open /proc/partitions " "(is /proc mounted?)"); } /* * Check to see if this is because * we're not running as root */ if (geteuid()) bb_error_msg_and_die( "must be root to scan for matching filesystems: %s\n", arg); else bb_error_msg_and_die( "cannot find matching filesystem: %s", arg); } devices[num_devices++] = dev ? dev : string_copy(arg); continue; } if (arg[0] != '-' || opts_for_fsck) { if (num_args >= MAX_ARGS) { bb_error_msg_and_die("too many arguments"); } args[num_args++] = string_copy(arg); continue; } for (j=1; arg[j]; j++) { if (opts_for_fsck) { options[++opt] = arg[j]; continue; } switch (arg[j]) { case 'A': doall++; break; case 'C': progress++; if (arg[j+1]) { progress_fd = string_to_int(arg+j+1); if (progress_fd < 0) progress_fd = 0; else goto next_arg; } else if ((i+1) < argc && argv[i+1][0] != '-') { progress_fd = string_to_int(argv[i]); if (progress_fd < 0) progress_fd = 0; else { goto next_arg; i++; } } break; case 'V': verbose++; break; case 'N': noexecute++; break; case 'R': skip_root++; break; case 'T': notitle++; break; case 'M': like_mount++; break; case 'P': parallel_root++; break; case 's': serialize++; break; case 't': tmp = 0; if (fstype) bb_show_usage(); if (arg[j+1]) tmp = arg+j+1; else if ((i+1) < argc) tmp = argv[++i]; else bb_show_usage(); fstype = string_copy(tmp); compile_fs_type(fstype, &fs_type_compiled); goto next_arg; case '-': opts_for_fsck++; break; case '?': bb_show_usage(); break; default: options[++opt] = arg[j]; break; } } next_arg: if (opt) { options[0] = '-'; options[++opt] = '\0'; if (num_args >= MAX_ARGS) { bb_error_msg("too many arguments"); } args[num_args++] = string_copy(options); opt = 0; } } if (getenv("FSCK_FORCE_ALL_PARALLEL")) force_all_parallel++; if ((tmp = getenv("FSCK_MAX_INST"))) max_running = atoi(tmp); }
int nameif_main(int argc, char **argv) { ethtable_t *clist = NULL; FILE *ifh; const char *fname = "/etc/mactab"; char *line; char *line_ptr; int linenum; int ctl_sk; ethtable_t *ch; if (1 & getopt32(argv, "sc:", &fname)) { openlog(applet_name, 0, LOG_LOCAL0); logmode = LOGMODE_SYSLOG; } argc -= optind; argv += optind; if (argc & 1) bb_show_usage(); if (argc) { while (*argv) { char *ifname = xstrdup(*argv++); prepend_new_eth_table(&clist, ifname, *argv++); } } else { ifh = xfopen(fname, "r"); while ((line = xmalloc_fgets(ifh)) != NULL) { char *next; line_ptr = skip_whitespace(line); if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) { free(line); continue; } next = skip_non_whitespace(line_ptr); if (*next) *next++ = '\0'; prepend_new_eth_table(&clist, line_ptr, next); free(line); } fclose(ifh); } ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0); ifh = xfopen("/proc/net/dev", "r"); linenum = 0; while (clist) { struct ifreq ifr; #if ENABLE_FEATURE_NAMEIF_EXTENDED struct ethtool_drvinfo drvinfo; #endif line = xmalloc_fgets(ifh); if (line == NULL) break; /* Seems like we're done */ if (linenum++ < 2 ) goto next_line; /* Skip the first two lines */ /* Find the current interface name and copy it to ifr.ifr_name */ line_ptr = skip_whitespace(line); *skip_non_whitespace(line_ptr) = '\0'; memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, line_ptr, sizeof(ifr.ifr_name)); #if ENABLE_FEATURE_NAMEIF_EXTENDED /* Check for driver etc. */ memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); drvinfo.cmd = ETHTOOL_GDRVINFO; ifr.ifr_data = (caddr_t) &drvinfo; /* Get driver and businfo first, so we have it in drvinfo */ ioctl(ctl_sk, SIOCETHTOOL, &ifr); #endif ioctl(ctl_sk, SIOCGIFHWADDR, &ifr); /* Search the list for a matching device */ for (ch = clist; ch; ch = ch->next) { #if ENABLE_FEATURE_NAMEIF_EXTENDED if (ch->bus_info && strcmp(ch->bus_info, drvinfo.bus_info) != 0) continue; if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) continue; #endif if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) continue; /* if we came here, all selectors have matched */ goto found; } /* Nothing found for current interface */ goto next_line; found: if (strcmp(ifr.ifr_name, ch->ifname) != 0) { strcpy(ifr.ifr_newname, ch->ifname); ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr, "cannot change ifname %s to %s", ifr.ifr_name, ch->ifname); } /* Remove list entry of renamed interface */ if (ch->prev != NULL) ch->prev->next = ch->next; else clist = ch->next; if (ch->next != NULL) ch->next->prev = ch->prev; if (ENABLE_FEATURE_CLEAN_UP) { free(ch->ifname); free(ch->mac); free(ch); } next_line: free(line); } if (ENABLE_FEATURE_CLEAN_UP) { fclose(ifh); }; return 0; }
int cp_main(int argc, char **argv) { struct stat source_stat; struct stat dest_stat; const char *last; const char *dest; int s_flags; int d_flags; int flags; int status = 0; enum { OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1), OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)), OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1), OPT_H = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2), OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), }; // Soft- and hardlinking don't mix // -P and -d are the same (-P is POSIX, -d is GNU) // -r and -R are the same // -a = -pdR opt_complementary = "?:l--s:s--l:Pd:rR:apdR"; flags = getopt32(argc, argv, FILEUTILS_CP_OPTSTR "arPHL"); /* Default behavior of cp is to dereference, so we don't have to do * anything special when we are given -L. * The behavior of -H is *almost* like -L, but not quite, so let's * just ignore it too for fun. if (flags & OPT_L) ... if (flags & OPT_H) ... // deref command-line params only */ #if ENABLE_SELINUX if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) { selinux_or_die(); } #endif flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ if (optind + 2 > argc) { bb_show_usage(); } last = argv[argc - 1]; argv += optind; /* If there are only two arguments and... */ if (optind + 2 == argc) { s_flags = cp_mv_stat2(*argv, &source_stat, (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); if (s_flags < 0) return EXIT_FAILURE; d_flags = cp_mv_stat(last, &dest_stat); if (d_flags < 0) return EXIT_FAILURE; /* ...if neither is a directory or... */ if ( !((s_flags | d_flags) & 2) || /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */ ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) ) { /* ...do a simple copy. */ dest = xstrdup(last); goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ } } do { dest = concat_path_file(last, bb_get_last_path_component(*argv)); DO_COPY: if (copy_file(*argv, dest, flags) < 0) { status = 1; } free((void*)dest); } while (*++argv != last); return status; }
/* Called only from main, once */ static int arp_del(char **args) { char *host; struct arpreq req; struct sockaddr sa; int flags = 0; int err; memset(&req, 0, sizeof(req)); /* Resolve the host name. */ host = *args; if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } /* If a host has more than one address, use the correct one! */ memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr)); if (hw_set) req.arp_ha.sa_family = hw->type; req.arp_flags = ATF_PERM; args++; while (*args != NULL) { switch (index_in_strings(options, *args)) { case 0: /* "pub" */ flags |= 1; args++; break; case 1: /* "priv" */ flags |= 2; args++; break; case 2: /* "temp" */ req.arp_flags &= ~ATF_PERM; args++; break; case 3: /* "trail" */ req.arp_flags |= ATF_USETRAILERS; args++; break; case 4: /* "dontpub" */ #ifdef HAVE_ATF_DONTPUB req.arp_flags |= ATF_DONTPUB; #else bb_error_msg("feature ATF_DONTPUB is not supported"); #endif args++; break; case 5: /* "auto" */ #ifdef HAVE_ATF_MAGIC req.arp_flags |= ATF_MAGIC; #else bb_error_msg("feature ATF_MAGIC is not supported"); #endif args++; break; case 6: /* "dev" */ if (*++args == NULL) bb_show_usage(); device = *args; args++; break; case 7: /* "netmask" */ if (*++args == NULL) bb_show_usage(); if (strcmp(*args, "255.255.255.255") != 0) { host = *args; if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); req.arp_flags |= ATF_NETMASK; } args++; break; default: bb_show_usage(); break; } } if (flags == 0) flags = 3; strncpy(req.arp_dev, device, sizeof(req.arp_dev)); err = -1; /* Call the kernel. */ if (flags & 2) { if (option_mask32 & ARP_OPT_v) bb_error_msg("SIOCDARP(nopub)"); err = ioctl(sockfd, SIOCDARP, &req); if (err < 0) { if (errno == ENXIO) { if (flags & 1) goto nopub; printf("No ARP entry for %s\n", host); return -1; } bb_perror_msg_and_die("SIOCDARP(priv)"); } } if ((flags & 1) && err) { nopub: req.arp_flags |= ATF_PUBL; if (option_mask32 & ARP_OPT_v) bb_error_msg("SIOCDARP(pub)"); if (ioctl(sockfd, SIOCDARP, &req) < 0) { if (errno == ENXIO) { printf("No ARP entry for %s\n", host); return -1; } bb_perror_msg_and_die("SIOCDARP(pub)"); } } return 0; }
static void INET_setroute(int action, char **args) { struct rtentry rt; const char *netmask; int skfd, isnet, xflag; assert((action == RTACTION_ADD) || (action == RTACTION_DEL)); /* Grab the -net or -host options. Remember they were transformed. */ xflag = kw_lookup(tbl_hash_net_host, &args); /* If we did grab -net or -host, make sure we still have an arg left. */ if (*args == NULL) { bb_show_usage(); } /* Clean out the RTREQ structure. */ memset((char *) &rt, 0, sizeof(struct rtentry)); { const char *target = *args++; /* Prefer hostname lookup is -host flag (xflag==1) was given. */ isnet = INET_resolve(target, (struct sockaddr_in *) &rt.rt_dst, (xflag & HOST_FLAG)); if (isnet < 0) { bb_error_msg_and_die("resolving %s", target); } } if (xflag) { /* Reinit isnet if -net or -host was specified. */ isnet = (xflag & NET_FLAG); } /* Fill in the other fields. */ rt.rt_flags = ((isnet) ? RTF_UP : (RTF_UP | RTF_HOST)); netmask = bb_INET_default; while (*args) { int k = kw_lookup(tbl_ipvx, &args); const char *args_m1 = args[-1]; if (k & KW_IPVx_FLAG_ONLY) { rt.rt_flags |= flags_ipvx[k & 3]; continue; } #if HAVE_NEW_ADDRT if (k == KW_IPVx_METRIC) { rt.rt_metric = bb_xgetularg10(args_m1) + 1; continue; } #endif if (k == KW_IPVx_NETMASK) { struct sockaddr mask; if (mask_in_addr(rt)) { bb_show_usage(); } netmask = args_m1; isnet = INET_resolve(netmask, (struct sockaddr_in *) &mask, 0); if (isnet < 0) { bb_error_msg_and_die("resolving %s", netmask); } rt.rt_genmask = full_mask(mask); continue; } if (k == KW_IPVx_GATEWAY) { if (rt.rt_flags & RTF_GATEWAY) { bb_show_usage(); } isnet = INET_resolve(args_m1, (struct sockaddr_in *) &rt.rt_gateway, 1); rt.rt_flags |= RTF_GATEWAY; if (isnet) { if (isnet < 0) { bb_error_msg_and_die("resolving %s", args_m1); } bb_error_msg_and_die("gateway %s is a NETWORK", args_m1); } continue; } if (k == KW_IPVx_MSS) { /* Check valid MSS bounds. */ rt.rt_flags |= RTF_MSS; rt.rt_mss = bb_xgetularg10_bnd(args_m1, 64, 32768); continue; } if (k == KW_IPVx_WINDOW) { /* Check valid window bounds. */ rt.rt_flags |= RTF_WINDOW; rt.rt_window = bb_xgetularg10_bnd(args_m1, 128, INT_MAX); continue; } #ifdef RTF_IRTT if (k == KW_IPVx_IRTT) { rt.rt_flags |= RTF_IRTT; rt.rt_irtt = bb_xgetularg10(args_m1); rt.rt_irtt *= (sysconf(_SC_CLK_TCK) / 100); /* FIXME */ #if 0 /* FIXME: do we need to check anything of this? */ if (rt.rt_irtt < 1 || rt.rt_irtt > (120 * HZ)) { bb_error_msg_and_die("bad irtt"); } #endif continue; } #endif /* Device is special in that it can be the last arg specified * and doesn't requre the dev/device keyword in that case. */ if (!rt.rt_dev && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { /* Don't use args_m1 here since args may have changed! */ rt.rt_dev = args[-1]; continue; } /* Nothing matched. */ bb_show_usage(); } #ifdef RTF_REJECT if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev) { rt.rt_dev = "lo"; } #endif /* sanity checks.. */ if (mask_in_addr(rt)) { unsigned long mask = mask_in_addr(rt); mask = ~ntohl(mask); if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) { bb_error_msg_and_die("netmask %.8x and host route conflict", (unsigned int) mask); } if (mask & (mask + 1)) { bb_error_msg_and_die("bogus netmask %s", netmask); } mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr; if (mask & ~mask_in_addr(rt)) { bb_error_msg_and_die("netmask and route address conflict"); } } /* Fill out netmask if still unset */ if ((action == RTACTION_ADD) && (rt.rt_flags & RTF_HOST)) { mask_in_addr(rt) = 0xffffffff; } /* Create a socket to the INET kernel. */ if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { bb_perror_msg_and_die("socket"); } if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) { bb_perror_msg_and_die("SIOC[ADD|DEL]RT"); } /* Don't bother closing, as we're exiting after we return anyway. */ /* close(skfd); */ }
int telnetd_main(int argc, char **argv) { #if !defined(CONFIG_FEATURE_TELNETD_INETD) || defined(IFX_INETD_ENHANCEMENT) int master_fd; #endif #ifndef CONFIG_FEATURE_TELNETD_INETD struct sockaddr_in sa; #endif /* CONFIG_FEATURE_TELNETD_INETD */ fd_set rdfdset, wrfdset; int selret; #ifndef CONFIG_FEATURE_TELNETD_INETD int on = 1; int portnbr = 23; #endif /* CONFIG_FEATURE_TELNETD_INETD */ int c; static const char options[] = #ifdef CONFIG_FEATURE_TELNETD_INETD #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT "f:l:t:"; #else /*CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT*/ "f:l:"; #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ #else /* CONFIG_EATURE_TELNETD_INETD */ #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT "f:l:p:t:"; #else /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ "f:l:p:"; #endif /*CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT*/ #endif /* CONFIG_FEATURE_TELNETD_INETD */ int maxlen, w, r; #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT struct timeval time_val; int daemon_timeout_val = time(NULL) + 120; #endif #ifndef CONFIG_LOGIN loginpath = DEFAULT_SHELL; #endif for (;;) { c = getopt( argc, argv, options); if (c == EOF) break; switch (c) { case 'f': issuefile = optarg; break; case 'l': loginpath = optarg; break; #ifndef CONFIG_FEATURE_TELNETD_INETD case 'p': portnbr = atoi(optarg); break; #endif /* CONFIG_FEATURE_TELNETD_INETD */ #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT case 't': TIMEOUT = atoi(optarg); break; #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT*/ default: bb_show_usage(); } } if (access(loginpath, X_OK) < 0) { bb_error_msg_and_die ("'%s' unavailable.", loginpath); } argv_init[0] = loginpath; openlog(bb_applet_name, 0, LOG_USER); #ifndef IFX_INETD_ENHANCEMENT #ifdef CONFIG_FEATURE_TELNETD_INETD maxfd = 1; sessions = make_new_session(); #else /* CONFIG_EATURE_TELNETD_INETD */ sessions = 0; /* Grab a TCP socket. */ master_fd = socket(AF_INET, SOCK_STREAM, 0); if (master_fd < 0) { bb_perror_msg_and_die("socket"); } (void)setsockopt(master_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); /* Set it to listen to specified port. */ memset((void *)&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(portnbr); if (bind(master_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { bb_perror_msg_and_die("bind"); } if (listen(master_fd, 1) < 0) { bb_perror_msg_and_die("listen"); } if (daemon(0, 0) < 0) bb_perror_msg_and_die("daemon"); maxfd = master_fd; #endif /* CONFIG_FEATURE_TELNETD_INETD */ #else /* IFX_INETD_ENHANCEMENT */ sessions = 0; master_fd = 0; maxfd = master_fd; #endif /* IFX_INETD_ENHANCEMENT */ do { struct tsession *ts; FD_ZERO(&rdfdset); FD_ZERO(&wrfdset); /* select on the master socket, all telnet sockets and their * ptys if there is room in their respective session buffers. */ #ifndef CONFIG_FEATURE_TELNETD_INETD FD_SET(master_fd, &rdfdset); #endif /* CONFIG_FEATURE_TELNETD_INETD */ ts = sessions; #ifndef CONFIG_FEATURE_TELNETD_INETD while (ts) { #endif /* CONFIG_FEATURE_TELNETD_INETD */ /* buf1 is used from socket to pty * buf2 is used from pty to socket */ if (ts->size1 > 0) { FD_SET(ts->ptyfd, &wrfdset); /* can write to pty */ } if (ts->size1 < BUFSIZE) { #ifdef CONFIG_FEATURE_TELNETD_INETD FD_SET(ts->sockfd_read, &rdfdset); /* can read from socket */ #else /* CONFIG_FEATURE_TELNETD_INETD */ FD_SET(ts->sockfd, &rdfdset); /* can read from socket */ #endif /* CONFIG_FEATURE_TELNETD_INETD */ } if (ts->size2 > 0) { #ifdef CONFIG_FEATURE_TELNETD_INETD FD_SET(ts->sockfd_write, &wrfdset); /* can write to socket */ #else /* CONFIG_FEATURE_TELNETD_INETD */ FD_SET(ts->sockfd, &wrfdset); /* can write to socket */ #endif /* CONFIG_FEATURE_TELNETD_INETD */ } if (ts->size2 < BUFSIZE) { FD_SET(ts->ptyfd, &rdfdset); /* can read from pty */ } #ifndef CONFIG_FEATURE_TELNETD_INETD ts = ts->next; } #endif /* CONFIG_FEATURE_TELNETD_INETD */ #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT time_val.tv_sec = 10; time_val.tv_usec = 0; selret = select(maxfd + 1, &rdfdset, &wrfdset, 0, &time_val); #else selret = select(maxfd + 1, &rdfdset, &wrfdset, 0, 0); #endif if (selret < 0) break; #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT // check if the currtime exceeded timeout time #ifndef CONFIG_FEATURE_TELNETD_INETD ts= sessions; while(ts) { struct tsession *next = ts->next; /* in case we free ts. */ #endif /* CONFIG_FEATURE_TELNETD_INETD */ if(ts->timeout_time < time(NULL)) { printf("Timed out \n"); syslog(LOG_ERR,"Session timed out\n"); #ifdef CONFIG_FEATURE_TELNETD_INETD exit(0); #else /* CONFIG_FEATURE_TELNETD_INETD */ daemon_timeout_val = time(NULL) + 120; free_session(ts); #endif/* CONFIG_FEATURE_TELNETD_INETD */ } #ifndef CONFIG_FEATURE_TELNETD_INETD ts= next; } #endif /* CONFIG_FEATURE_TELNETD_INETD */ if(selret == 0) { if(sessions == NULL && daemon_timeout_val < time(NULL)) { printf("Telnetd Timed out \n"); syslog(LOG_ERR,"Telnetd timed out\n"); exit(0); } else continue; } #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ #ifndef CONFIG_FEATURE_TELNETD_INETD daemon_timeout_val = time(NULL) + 120; /* First check for and accept new sessions. */ if (FD_ISSET(master_fd, &rdfdset)) { int fd, salen; salen = sizeof(sa); if ((fd = accept(master_fd, (struct sockaddr *)&sa, &salen)) < 0) { continue; } else { /* Create a new session and link it into our active list. */ struct tsession *new_ts = make_new_session(fd); if (new_ts) { new_ts->next = sessions; sessions = new_ts; if (fd > maxfd) maxfd = fd; } else { close(fd); } } } /* Then check for data tunneling. */ ts = sessions; while (ts) { /* For all sessions... */ #endif /* CONFIG_FEATURE_TELNETD_INETD */ #ifndef CONFIG_FEATURE_TELNETD_INETD struct tsession *next = ts->next; /* in case we free ts. */ #endif /* CONFIG_FEATURE_TELNETD_INETD */ if (ts->size1 && FD_ISSET(ts->ptyfd, &wrfdset)) { int num_totty; char *ptr; /* Write to pty from buffer 1. */ ptr = remove_iacs(ts, &num_totty); w = write(ts->ptyfd, ptr, num_totty); if (w < 0) { #ifdef CONFIG_FEATURE_TELNETD_INETD exit(0); #else /* CONFIG_FEATURE_TELNETD_INETD */ free_session(ts); ts = next; continue; #endif /* CONFIG_FEATURE_TELNETD_INETD */ } ts->wridx1 += w; ts->size1 -= w; if (ts->wridx1 == BUFSIZE) ts->wridx1 = 0; #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT //some activity in this session reset the timer ts->timeout_time = time(NULL)+ TIMEOUT; #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ } #ifdef CONFIG_FEATURE_TELNETD_INETD if (ts->size2 && FD_ISSET(ts->sockfd_write, &wrfdset)) #else /* CONFIG_FEATURE_TELNETD_INETD */ if (ts->size2 && FD_ISSET(ts->sockfd, &wrfdset)) #endif /* CONFIG_FEATURE_TELNETD_INETD */ { /* Write to socket from buffer 2. */ maxlen = MIN(BUFSIZE - ts->wridx2, ts->size2); #ifdef CONFIG_FEATURE_TELNETD_INETD w = write(ts->sockfd_write, ts->buf2 + ts->wridx2, maxlen); if (w < 0) exit(0); #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT else ts->timeout_time = time(NULL)+TIMEOUT; #endif /*CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT*/ #else /* CONFIG_FEATURE_TELNETD_INETD */ w = write(ts->sockfd, ts->buf2 + ts->wridx2, maxlen); if (w < 0) { free_session(ts); ts = next; continue; } #endif /* CONFIG_FEATURE_TELNETD_INETD */ ts->wridx2 += w; ts->size2 -= w; if (ts->wridx2 == BUFSIZE) ts->wridx2 = 0; #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT //some activity in this session reset the timer ts->timeout_time = time(NULL)+ TIMEOUT; #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ } #ifdef CONFIG_FEATURE_TELNETD_INETD if (ts->size1 < BUFSIZE && FD_ISSET(ts->sockfd_read, &rdfdset)) #else /* CONFIG_FEATURE_TELNETD_INETD */ if (ts->size1 < BUFSIZE && FD_ISSET(ts->sockfd, &rdfdset)) #endif /* CONFIG_FEATURE_TELNETD_INETD */ { /* Read from socket to buffer 1. */ maxlen = MIN(BUFSIZE - ts->rdidx1, BUFSIZE - ts->size1); #ifdef CONFIG_FEATURE_TELNETD_INETD r = read(ts->sockfd_read, ts->buf1 + ts->rdidx1, maxlen); if (!r || (r < 0 && errno != EINTR)) exit(0); #else /* CONFIG_FEATURE_TELNETD_INETD */ r = read(ts->sockfd, ts->buf1 + ts->rdidx1, maxlen); if (!r || (r < 0 && errno != EINTR)) { free_session(ts); ts = next; continue; } #endif /* CONFIG_FEATURE_TELNETD_INETD */ #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT //some activity in this session reset the timer ts->timeout_time = time(NULL)+ TIMEOUT; #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ if(!*(ts->buf1 + ts->rdidx1 + r - 1)) { r--; if(!r) continue; } ts->rdidx1 += r; ts->size1 += r; if (ts->rdidx1 == BUFSIZE) ts->rdidx1 = 0; } if (ts->size2 < BUFSIZE && FD_ISSET(ts->ptyfd, &rdfdset)) { /* Read from pty to buffer 2. */ maxlen = MIN(BUFSIZE - ts->rdidx2, BUFSIZE - ts->size2); r = read(ts->ptyfd, ts->buf2 + ts->rdidx2, maxlen); if (!r || (r < 0 && errno != EINTR)) { #ifdef CONFIG_FEATURE_TELNETD_INETD exit(0); #else /* CONFIG_FEATURE_TELNETD_INETD */ free_session(ts); ts = next; continue; #endif /* CONFIG_FEATURE_TELNETD_INETD */ } ts->rdidx2 += r; ts->size2 += r; if (ts->rdidx2 == BUFSIZE) ts->rdidx2 = 0; #ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT //some activity in this session reset the timer ts->timeout_time = time(NULL)+ TIMEOUT; #endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */ } if (ts->size1 == 0) { ts->rdidx1 = 0; ts->wridx1 = 0; } if (ts->size2 == 0) { ts->rdidx2 = 0; ts->wridx2 = 0; } #ifndef CONFIG_FEATURE_TELNETD_INETD ts = next; } #endif /* CONFIG_FEATURE_TELNETD_INETD */ } while (1); return 0; }
static void INET6_setroute(int action, char **args) { struct sockaddr_in6 sa6; struct in6_rtmsg rt; int prefix_len, skfd; const char *devname; assert((action == RTACTION_ADD) || (action == RTACTION_DEL)); { /* We know args isn't NULL from the check in route_main. */ const char *target = *args++; if (strcmp(target, "default") == 0) { prefix_len = 0; memset(&sa6, 0, sizeof(sa6)); } else { char *cp; if ((cp = strchr(target, '/'))) { /* Yes... const to non is ok. */ *cp = 0; prefix_len = bb_xgetularg10_bnd(cp+1, 0, 128); } else { prefix_len = 128; } if (INET6_resolve(target, (struct sockaddr_in6 *) &sa6) < 0) { bb_error_msg_and_die("resolving %s", target); } } } /* Clean out the RTREQ structure. */ memset((char *) &rt, 0, sizeof(struct in6_rtmsg)); memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr)); /* Fill in the other fields. */ rt.rtmsg_dst_len = prefix_len; rt.rtmsg_flags = ((prefix_len == 128) ? (RTF_UP|RTF_HOST) : RTF_UP); rt.rtmsg_metric = 1; devname = NULL; while (*args) { int k = kw_lookup(tbl_ipvx, &args); const char *args_m1 = args[-1]; if ((k == KW_IPVx_MOD) || (k == KW_IPVx_DYN)) { rt.rtmsg_flags |= flags_ipvx[k & 3]; continue; } if (k == KW_IPVx_METRIC) { rt.rtmsg_metric = bb_xgetularg10(args_m1); continue; } if (k == KW_IPVx_GATEWAY) { if (rt.rtmsg_flags & RTF_GATEWAY) { bb_show_usage(); } if (INET6_resolve(args_m1, (struct sockaddr_in6 *) &sa6) < 0) { bb_error_msg_and_die("resolving %s", args_m1); } memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr)); rt.rtmsg_flags |= RTF_GATEWAY; continue; } /* Device is special in that it can be the last arg specified * and doesn't requre the dev/device keyword in that case. */ if (!devname && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { /* Don't use args_m1 here since args may have changed! */ devname = args[-1]; continue; } /* Nothing matched. */ bb_show_usage(); } /* Create a socket to the INET6 kernel. */ if ((skfd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { bb_perror_msg_and_die("socket"); } rt.rtmsg_ifindex = 0; if (devname) { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, devname); if (ioctl(skfd, SIOGIFINDEX, &ifr) < 0) { bb_perror_msg_and_die("SIOGIFINDEX"); } rt.rtmsg_ifindex = ifr.ifr_ifindex; } /* Tell the kernel to accept this route. */ if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) { bb_perror_msg_and_die("SIOC[ADD|DEL]RT"); } /* Don't bother closing, as we're exiting after we return anyway. */ /* close(skfd); */ }
int brctl_main(int argc UNUSED_PARAM, char **argv) { static const char keywords[] ALIGN1 = "addbr\0" "delbr\0" "addif\0" "delif\0" IF_FEATURE_BRCTL_FANCY( "stp\0" "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" "setpathcost\0" "setportprio\0" "setbridgeprio\0" ) IF_FEATURE_BRCTL_SHOW("show\0"); enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif IF_FEATURE_BRCTL_FANCY(, ARG_stp, ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio ) IF_FEATURE_BRCTL_SHOW(, ARG_show) }; int fd; smallint key; struct ifreq ifr; char *br, *brif; argv++; while (*argv) { #if ENABLE_FEATURE_BRCTL_FANCY int ifidx[MAX_PORTS]; unsigned long args[4]; ifr.ifr_data = (char *) &args; #endif key = index_in_strings(keywords, *argv); if (key == -1) /* no match found in keywords array, bail out. */ bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); argv++; fd = xsocket(AF_INET, SOCK_STREAM, 0); #if ENABLE_FEATURE_BRCTL_SHOW if (key == ARG_show) { /* show */ char brname[IFNAMSIZ]; int bridx[MAX_PORTS]; int i, num; arm_ioctl(args, BRCTL_GET_BRIDGES, (unsigned long) bridx, MAX_PORTS); num = xioctl(fd, SIOCGIFBR, args); puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); for (i = 0; i < num; i++) { char ifname[IFNAMSIZ]; int j, tabs; struct __bridge_info bi; unsigned char *x; if (!if_indextoname(bridx[i], brname)) bb_perror_msg_and_die("can't get bridge name for index %d", i); strncpy_IFNAMSIZ(ifr.ifr_name, brname); arm_ioctl(args, BRCTL_GET_BRIDGE_INFO, (unsigned long) &bi, 0); xioctl(fd, SIOCDEVPRIVATE, &ifr); printf("%s\t\t", brname); /* print bridge id */ x = (unsigned char *) &bi.bridge_id; for (j = 0; j < 8; j++) { printf("%02x", x[j]); if (j == 1) bb_putchar('.'); } printf(bi.stp_enabled ? "\tyes" : "\tno"); /* print interface list */ arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long) ifidx, MAX_PORTS); xioctl(fd, SIOCDEVPRIVATE, &ifr); tabs = 0; for (j = 0; j < MAX_PORTS; j++) { if (!ifidx[j]) continue; if (!if_indextoname(ifidx[j], ifname)) bb_perror_msg_and_die("can't get interface name for index %d", j); if (tabs) printf("\t\t\t\t\t"); else tabs = 1; printf("\t\t%s\n", ifname); } if (!tabs) /* bridge has no interfaces */ bb_putchar('\n'); } goto done; } #endif if (!*argv) /* all but 'show' need at least one argument */ bb_show_usage(); br = *argv++; if (key == ARG_addbr || key == ARG_delbr) { /* addbr or delbr */ ioctl_or_perror_and_die(fd, key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, br, "bridge %s", br); goto done; } if (!*argv) /* all but 'addbr/delbr' need at least two arguments */ bb_show_usage(); strncpy_IFNAMSIZ(ifr.ifr_name, br); if (key == ARG_addif || key == ARG_delif) { /* addif or delif */ brif = *argv; ifr.ifr_ifindex = if_nametoindex(brif); if (!ifr.ifr_ifindex) { bb_perror_msg_and_die("iface %s", brif); } ioctl_or_perror_and_die(fd, key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, &ifr, "bridge %s", br); goto done_next_argv; } #if ENABLE_FEATURE_BRCTL_FANCY if (key == ARG_stp) { /* stp */ static const char no_yes[] ALIGN1 = "0\0" "off\0" "n\0" "no\0" /* 0 .. 3 */ "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */ int onoff = index_in_strings(no_yes, *argv); if (onoff < 0) bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); onoff = (unsigned)onoff / 4; arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, onoff, 0); goto fire; } if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */ static const uint8_t ops[] ALIGN1 = { BRCTL_SET_AGEING_TIME, /* ARG_setageing */ BRCTL_SET_BRIDGE_FORWARD_DELAY, /* ARG_setfd */ BRCTL_SET_BRIDGE_HELLO_TIME, /* ARG_sethello */ BRCTL_SET_BRIDGE_MAX_AGE /* ARG_setmaxage */ }; arm_ioctl(args, ops[key - ARG_setageing], str_to_jiffies(*argv), 0); goto fire; } if (key == ARG_setpathcost || key == ARG_setportprio || key == ARG_setbridgeprio ) { static const uint8_t ops[] ALIGN1 = { BRCTL_SET_PATH_COST, /* ARG_setpathcost */ BRCTL_SET_PORT_PRIORITY, /* ARG_setportprio */ BRCTL_SET_BRIDGE_PRIORITY /* ARG_setbridgeprio */ }; int port = -1; unsigned arg1, arg2; if (key != ARG_setbridgeprio) { /* get portnum */ unsigned i; port = if_nametoindex(*argv++); if (!port) bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, "port"); memset(ifidx, 0, sizeof ifidx); arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, MAX_PORTS); xioctl(fd, SIOCDEVPRIVATE, &ifr); for (i = 0; i < MAX_PORTS; i++) { if (ifidx[i] == port) { port = i; break; } } } arg1 = port; arg2 = xatoi_positive(*argv); if (key == ARG_setbridgeprio) { arg1 = arg2; arg2 = 0; } arm_ioctl(args, ops[key - ARG_setpathcost], arg1, arg2); } fire: /* Execute the previously set command */ xioctl(fd, SIOCDEVPRIVATE, &ifr); #endif done_next_argv: argv++; done: close(fd); } return EXIT_SUCCESS; }
int eooqd_main(int argc, char *argv[]) { int r; char *pid_file_name, *instance_id_str; char *check; struct event *checkQueueEvent, *rePostEvent; struct timeval tv; struct rlimit limit; atlas_id= NULL; instance_id_str= NULL; pid_file_name= NULL; queue_id= ""; (void)getopt32(argv, "A:i:P:q:", &atlas_id, &instance_id_str, &pid_file_name, &queue_id); if (argc != optind+1) { bb_show_usage(); return 1; } instance_id= 0; if (instance_id_str) { instance_id= strtoul(instance_id_str, &check, 0); if (check[0] != '\0') { report("unable to parse instance id '%s'", instance_id_str); return 1; } } if(pid_file_name) { write_pidfile(pid_file_name); } state = xzalloc(sizeof(*state)); state->atlas_id= atlas_id; state->queue_file= argv[optind]; state->max_busy= 10; state->slots= xzalloc(sizeof(*state->slots) * state->max_busy); if (strlen(state->queue_file) + strlen(SUFFIX) + 1 > sizeof(state->curr_qfile)) { report("filename too long ('%s')", state->queue_file); return 1; } strlcpy(state->curr_qfile, state->queue_file, sizeof(state->curr_qfile)); strlcat(state->curr_qfile, SUFFIX, sizeof(state->curr_qfile)); signal(SIGQUIT, SIG_DFL); limit.rlim_cur= RLIM_INFINITY; limit.rlim_max= RLIM_INFINITY; setrlimit(RLIMIT_CORE, &limit); /* Create libevent event base */ EventBase= event_base_new(); if (!EventBase) { crondlog(DIE9 "event_base_new failed"); /* exits */ } DnsBase= evdns_base_new(EventBase, 1 /*initialize*/); if (!DnsBase) { event_base_free(EventBase); crondlog(DIE9 "evdns_base_new failed"); /* exits */ } checkQueueEvent= event_new(EventBase, -1, EV_TIMEOUT|EV_PERSIST, checkQueue, NULL); if (!checkQueueEvent) crondlog(DIE9 "event_new failed"); /* exits */ tv.tv_sec= 1; tv.tv_usec= 0; event_add(checkQueueEvent, &tv); rePostEvent= event_new(EventBase, -1, EV_TIMEOUT|EV_PERSIST, re_post, NULL); if (!rePostEvent) crondlog(DIE9 "event_new failed"); /* exits */ tv.tv_sec= 60; tv.tv_usec= 0; event_add(rePostEvent, &tv); r= event_base_loop(EventBase, 0); if (r != 0) crondlog(LVL9 "event_base_loop failed"); return 0; }
extern int login_main(int argc, char **argv) { char tty[BUFSIZ]; char full_tty[200]; char fromhost[512]; char username[USERNAME_SIZE]; const char *tmp; int amroot; int flag; int failed; int count=0; struct passwd *pw, pw_copy; #ifdef CONFIG_WHEEL_GROUP struct group *grp; #endif int opt_preserve = 0; int opt_fflag = 0; char *opt_host = 0; int alarmstarted = 0; #ifdef CONFIG_SELINUX int flask_enabled = is_flask_enabled(); security_id_t sid = 0, old_tty_sid, new_tty_sid; #endif username[0]=0; amroot = ( getuid ( ) == 0 ); signal ( SIGALRM, alarm_handler ); alarm ( TIMEOUT ); alarmstarted = 1; while (( flag = getopt(argc, argv, "f:h:p")) != EOF ) { switch ( flag ) { case 'p': opt_preserve = 1; break; case 'f': /* * username must be a separate token * (-f root, *NOT* -froot). --marekm */ if ( optarg != argv[optind-1] ) bb_show_usage( ); if ( !amroot ) /* Auth bypass only if real UID is zero */ bb_error_msg_and_die ( "-f permission denied" ); safe_strncpy(username, optarg, USERNAME_SIZE); opt_fflag = 1; break; case 'h': opt_host = optarg; break; default: bb_show_usage( ); } } if (optind < argc) // user from command line (getty) safe_strncpy(username, argv[optind], USERNAME_SIZE); if ( !isatty ( 0 ) || !isatty ( 1 ) || !isatty ( 2 )) return EXIT_FAILURE; /* Must be a terminal */ #ifdef CONFIG_FEATURE_U_W_TMP checkutmp ( !amroot ); #endif tmp = ttyname ( 0 ); if ( tmp && ( strncmp ( tmp, "/dev/", 5 ) == 0 )) safe_strncpy ( tty, tmp + 5, sizeof( tty )); else if ( tmp && *tmp == '/' ) safe_strncpy ( tty, tmp, sizeof( tty )); else safe_strncpy ( tty, "UNKNOWN", sizeof( tty )); #ifdef CONFIG_FEATURE_U_W_TMP if ( amroot ) memset ( utent.ut_host, 0, sizeof utent.ut_host ); #endif if ( opt_host ) { #ifdef CONFIG_FEATURE_U_W_TMP safe_strncpy ( utent.ut_host, opt_host, sizeof( utent. ut_host )); #endif snprintf ( fromhost, sizeof( fromhost ) - 1, " on `%.100s' from `%.200s'", tty, opt_host ); } else snprintf ( fromhost, sizeof( fromhost ) - 1, " on `%.100s'", tty ); setpgrp(); openlog ( "login", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH ); while ( 1 ) { failed = 0; if ( !username[0] ) if(!login_prompt ( username )) return EXIT_FAILURE; if ( !alarmstarted && ( TIMEOUT > 0 )) { alarm ( TIMEOUT ); alarmstarted = 1; } if (!( pw = getpwnam ( username ))) { pw_copy.pw_name = "UNKNOWN"; pw_copy.pw_passwd = "!"; opt_fflag = 0; failed = 1; } else pw_copy = *pw; pw = &pw_copy; if (( pw-> pw_passwd [0] == '!' ) || ( pw-> pw_passwd[0] == '*' )) failed = 1; if ( opt_fflag ) { opt_fflag = 0; goto auth_ok; } if (!failed && ( pw-> pw_uid == 0 ) && ( !check_tty ( tty ))) failed = 1; /* Don't check the password if password entry is empty (!) */ if ( !pw-> pw_passwd[0] ) goto auth_ok; /* authorization takes place here */ if ( correct_password ( pw )) goto auth_ok; failed = 1; auth_ok: if ( !failed) break; { // delay next try time_t start, now; time ( &start ); now = start; while ( difftime ( now, start ) < FAIL_DELAY) { sleep ( FAIL_DELAY ); time ( &now ); } } puts("Login incorrect"); username[0] = 0; if ( ++count == 3 ) { syslog ( LOG_WARNING, "invalid password for `%s'%s\n", pw->pw_name, fromhost); return EXIT_FAILURE; } } alarm ( 0 ); if ( check_nologin ( pw-> pw_uid == 0 )) return EXIT_FAILURE; #ifdef CONFIG_FEATURE_U_W_TMP setutmp ( username, tty ); #endif #ifdef CONFIG_SELINUX if (flask_enabled) { struct stat st; if (get_default_sid(username, 0, &sid)) { fprintf(stderr, "Unable to get SID for %s\n", username); exit(1); } if (stat_secure(tty, &st, &old_tty_sid)) { fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", tty, strerror(errno)); return EXIT_FAILURE; } if (security_change_sid (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0) { fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", tty, strerror(errno)); return EXIT_FAILURE; } if(chsid(tty, new_tty_sid) != 0) { fprintf(stderr, "chsid(%.100s, %d) failed: %.100s\n", tty, new_tty_sid, strerror(errno)); return EXIT_FAILURE; } } else sid = 0; #endif if ( *tty != '/' ) snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty); else safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 ); if ( !is_my_tty ( full_tty )) syslog ( LOG_ERR, "unable to determine TTY name, got %s\n", full_tty ); /* Try these, but don't complain if they fail * (for example when the root fs is read only) */ chown ( full_tty, pw-> pw_uid, pw-> pw_gid ); chmod ( full_tty, 0600 ); change_identity ( pw ); tmp = pw-> pw_shell; if(!tmp || !*tmp) tmp = DEFAULT_SHELL; setup_environment ( tmp, 1, !opt_preserve, pw ); motd ( ); signal ( SIGALRM, SIG_DFL ); /* default alarm signal */ if ( pw-> pw_uid == 0 ) syslog ( LOG_INFO, "root login %s\n", fromhost ); run_shell ( tmp, 1, 0, 0 #ifdef CONFIG_SELINUX , sid #endif ); /* exec the shell finally. */ return EXIT_FAILURE; }
extern int unzip_main(int argc, char **argv) { union { unsigned char raw[26]; struct { unsigned short version; /* 0-1 */ unsigned short flags; /* 2-3 */ unsigned short method; /* 4-5 */ unsigned short modtime; /* 6-7 */ unsigned short moddate; /* 8-9 */ unsigned int crc32 __attribute__ ((packed)); /* 10-13 */ unsigned int cmpsize __attribute__ ((packed));; /* 14-17 */ unsigned int ucmpsize __attribute__ ((packed));; /* 18-21 */ unsigned short filename_len; /* 22-23 */ unsigned short extra_len; /* 24-25 */ } formated __attribute__ ((packed)); } zip_header; archive_handle_t *archive_handle; unsigned int total_size = 0; unsigned int total_entries = 0; char *base_dir = NULL; int opt = 0; /* Initialise */ archive_handle = init_handle(); archive_handle->action_data = NULL; archive_handle->action_header = header_list_unzip; while ((opt = getopt(argc, argv, "lnopqd:")) != -1) { switch (opt) { case 'l': /* list */ archive_handle->action_header = header_verbose_list_unzip; archive_handle->action_data = data_skip; break; case 'n': /* never overwright existing files */ break; case 'o': archive_handle->flags = ARCHIVE_EXTRACT_UNCONDITIONAL; break; case 'p': /* extract files to stdout */ archive_handle->action_data = data_extract_to_stdout; break; case 'q': /* Extract files quietly */ archive_handle->action_header = header_skip; break; case 'd': /* Extract files to specified base directory*/ base_dir = optarg; break; #if 0 case 'x': /* Exclude the specified files */ archive_handle->filter = filter_accept_reject_list; break; #endif default: bb_show_usage(); } } if (argc == optind) { bb_show_usage(); } printf("Archive: %s\n", argv[optind]); if (archive_handle->action_header == header_verbose_list_unzip) { printf(" Length Date Time Name\n"); printf(" -------- ---- ---- ----\n"); } if (*argv[optind] == '-') { archive_handle->src_fd = fileno(stdin); archive_handle->seek = seek_by_char; } else { archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY); } if ((base_dir) && (chdir(base_dir))) { bb_perror_msg_and_die("Couldnt chdir"); } while (optind < argc) { archive_handle->filter = filter_accept_list; archive_handle->accept = llist_add_to(archive_handle->accept, argv[optind]); optind++; } while (1) { unsigned int magic; int dst_fd; /* TODO Endian issues */ archive_xread_all(archive_handle, &magic, 4); archive_handle->offset += 4; if (magic == ZIP_CDS_MAGIC) { break; } else if (magic != ZIP_FILEHEADER_MAGIC) { bb_error_msg_and_die("Invlaide zip magic"); } /* Read the file header */ archive_xread_all(archive_handle, zip_header.raw, 26); archive_handle->offset += 26; archive_handle->file_header->mode = S_IFREG | 0777; if (zip_header.formated.method != 8) { bb_error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method); } /* Read filename */ archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len); archive_handle->offset += zip_header.formated.filename_len; archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; /* Skip extra header bits */ archive_handle->file_header->size = zip_header.formated.extra_len; data_skip(archive_handle); archive_handle->offset += zip_header.formated.extra_len; /* Handle directories */ archive_handle->file_header->mode = S_IFREG | 0777; if (last_char_is(archive_handle->file_header->name, '/')) { archive_handle->file_header->mode ^= S_IFREG; archive_handle->file_header->mode |= S_IFDIR; } /* Data section */ archive_handle->file_header->size = zip_header.formated.cmpsize; if (archive_handle->action_data) { archive_handle->action_data(archive_handle); } else { dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT); inflate(archive_handle->src_fd, dst_fd); close(dst_fd); chmod(archive_handle->file_header->name, archive_handle->file_header->mode); /* Validate decompression - crc */ if (zip_header.formated.crc32 != (gunzip_crc ^ 0xffffffffL)) { bb_error_msg("Invalid compressed data--crc error"); } /* Validate decompression - size */ if (gunzip_bytes_out != zip_header.formated.ucmpsize) { bb_error_msg("Invalid compressed data--length error"); } } /* local file descriptor section */ archive_handle->offset += zip_header.formated.cmpsize; /* This ISNT unix time */ archive_handle->file_header->mtime = zip_header.formated.modtime | (zip_header.formated.moddate << 16); archive_handle->file_header->size = zip_header.formated.ucmpsize; total_size += archive_handle->file_header->size; total_entries++; archive_handle->action_header(archive_handle->file_header); /* Data descriptor section */ if (zip_header.formated.flags & 4) { /* skip over duplicate crc, compressed size and uncompressed size */ unsigned short i; for (i = 0; i != 12; i++) { archive_xread_char(archive_handle); } archive_handle->offset += 12; } } /* Central directory section */ if (archive_handle->action_header == header_verbose_list_unzip) { printf(" -------- -------\n"); printf("%9d %d files\n", total_size, total_entries); } return(EXIT_SUCCESS); }
int fbset_main(int argc, char **argv) #endif { struct fb_var_screeninfo var, varset; int fh, i; char *fbdev = DEFAULTFBDEV; char *modefile = DEFAULTFBMODE; char *thisarg, *mode = NULL; memset(&varset, 0xFF, sizeof(varset)); /* parse cmd args.... why do they have to make things so difficult? */ argv++; argc--; for (; argc > 0 && (thisarg = *argv); argc--, argv++) { for (i = 0; g_cmdoptions[i].name[0]; i++) { if (strcmp(thisarg, g_cmdoptions[i].name)) continue; if (argc-1 < g_cmdoptions[i].param_count) bb_show_usage(); switch (g_cmdoptions[i].code) { case CMD_FB: fbdev = argv[1]; break; case CMD_DB: modefile = argv[1]; break; case CMD_GEOMETRY: varset.xres = xatou32(argv[1]); varset.yres = xatou32(argv[2]); varset.xres_virtual = xatou32(argv[3]); varset.yres_virtual = xatou32(argv[4]); varset.bits_per_pixel = xatou32(argv[5]); break; case CMD_TIMING: varset.pixclock = xatou32(argv[1]); varset.left_margin = xatou32(argv[2]); varset.right_margin = xatou32(argv[3]); varset.upper_margin = xatou32(argv[4]); varset.lower_margin = xatou32(argv[5]); varset.hsync_len = xatou32(argv[6]); varset.vsync_len = xatou32(argv[7]); break; case CMD_ALL: g_options |= OPT_ALL; break; case CMD_CHANGE: g_options |= OPT_CHANGE; break; #ifdef CONFIG_FEATURE_FBSET_FANCY case CMD_XRES: varset.xres = xatou32(argv[1]); break; case CMD_YRES: varset.yres = xatou32(argv[1]); break; case CMD_DEPTH: varset.bits_per_pixel = xatou32(argv[1]); break; #endif } argc -= g_cmdoptions[i].param_count; argv += g_cmdoptions[i].param_count; break; } if (!g_cmdoptions[i].name[0]) { if (argc != 1) bb_show_usage(); mode = *argv; g_options |= OPT_READMODE; } } fh = xopen(fbdev, O_RDONLY); if (ioctl(fh, FBIOGET_VSCREENINFO, &var)) bb_perror_msg_and_die("ioctl(%sT_VSCREENINFO)", "GE"); if (g_options & OPT_READMODE) { if (!readmode(&var, modefile, mode)) { bb_error_msg_and_die("unknown video mode '%s'", mode); } } setmode(&var, &varset); if (g_options & OPT_CHANGE) { if (g_options & OPT_ALL) var.activate = FB_ACTIVATE_ALL; if (ioctl(fh, FBIOPUT_VSCREENINFO, &var)) bb_perror_msg_and_die("ioctl(%sT_VSCREENINFO)", "PU"); } showmode(&var); /* Don't close the file, as exiting will take care of that */ /* close(fh); */ return EXIT_SUCCESS; }
int pgrep_main(int argc UNUSED_PARAM, char **argv) { unsigned pid = getpid(); int signo = SIGTERM; unsigned opt; int scan_mask = PSSCAN_COMM; char *first_arg; int first_arg_idx; int matched_pid; char *cmd_last; procps_status_t *proc; /* These are initialized to 0 */ struct { regex_t re_buffer; regmatch_t re_match[1]; } Z; #define re_buffer (Z.re_buffer) #define re_match (Z.re_match ) memset(&Z, 0, sizeof(Z)); /* We must avoid interpreting -NUM (signal num) as an option */ first_arg_idx = 1; while (1) { first_arg = argv[first_arg_idx]; if (!first_arg) break; /* not "-<small_letter>..."? */ if (first_arg[0] != '-' || first_arg[1] < 'a' || first_arg[1] > 'z') { argv[first_arg_idx] = NULL; /* terminate argv here */ break; } first_arg_idx++; } opt = getopt32(argv, "vlfxon"); argv[first_arg_idx] = first_arg; argv += optind; //argc -= optind; - unused anyway if (OPT_FULL) scan_mask |= PSSCAN_ARGVN; if (pkill) { if (OPT_LIST) { /* -l: print the whole signal list */ print_signames(); return 0; } if (first_arg && first_arg[0] == '-') { signo = get_signum(&first_arg[1]); if (signo < 0) /* || signo > MAX_SIGNUM ? */ bb_error_msg_and_die("bad signal name '%s'", &first_arg[1]); argv++; } } /* One pattern is required */ if (!argv[0] || argv[1]) bb_show_usage(); xregcomp(&re_buffer, argv[0], 0); matched_pid = 0; cmd_last = NULL; proc = NULL; while ((proc = procps_scan(proc, scan_mask)) != NULL) { char *cmd; if (proc->pid == pid) continue; cmd = proc->argv0; if (!cmd) { cmd = proc->comm; } else { int i = proc->argv_len; while (i) { if (!cmd[i]) cmd[i] = ' '; i--; } } /* NB: OPT_INVERT is always 0 or 1 */ if ((regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */ && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == (regoff_t)strlen(cmd)))) ^ OPT_INVERT ) { matched_pid = proc->pid; if (OPT_LAST) { free(cmd_last); cmd_last = xstrdup(cmd); continue; } act(proc->pid, cmd, signo, opt); if (OPT_FIRST) break; } } if (cmd_last) { act(matched_pid, cmd_last, signo, opt); if (ENABLE_FEATURE_CLEAN_UP) free(cmd_last); } return matched_pid == 0; /* return 1 if no processes listed/signaled */ }