cmds.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. /*
  2. * Modifications for uClinux
  3. * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
  4. *
  5. * Original code
  6. * Copyright (c) 1993 by David I. Bell
  7. * Permission is granted to use, distribute, or modify this source,
  8. * provided that this copyright notice remains intact.
  9. *
  10. * Most simple built-in commands are here.
  11. */
  12. #include "sash.h"
  13. #include <sys/types.h>
  14. #include <sys/mount.h>
  15. #include <sys/stat.h>
  16. #include <sys/time.h>
  17. #include <time.h>
  18. #include <unistd.h>
  19. #include <fcntl.h>
  20. #include <signal.h>
  21. #include <pwd.h>
  22. #include <grp.h>
  23. #include <utime.h>
  24. #include <errno.h>
  25. #ifdef EMBED
  26. #include <config/autoconf.h>
  27. #endif
  28. void
  29. do_echo(argc, argv)
  30. int argc;
  31. char **argv;
  32. {
  33. BOOL first;
  34. first = TRUE;
  35. while (argc-- > 1) {
  36. if (!first)
  37. fputc(' ', stdout);
  38. first = FALSE;
  39. fputs(*++argv, stdout);
  40. }
  41. fputc('\n', stdout);
  42. }
  43. void
  44. do_pwd(argc, argv)
  45. int argc;
  46. char **argv;
  47. {
  48. char buf[PATHLEN];
  49. if (getcwd(buf, PATHLEN) == NULL) {
  50. fprintf(stderr, "Cannot get current directory\n");
  51. return;
  52. }
  53. printf("%s\n", buf);
  54. }
  55. void
  56. do_time(argc, argv)
  57. int argc;
  58. char ** argv;
  59. {
  60. struct timeval tv;
  61. gettimeofday(&tv, 0);
  62. printf("Time of day = %d.%6.6d seconds\n", tv.tv_sec, tv.tv_usec);
  63. }
  64. void
  65. do_cd(argc, argv)
  66. int argc;
  67. char **argv;
  68. {
  69. char *path;
  70. if (argc > 1)
  71. path = argv[1];
  72. else {
  73. path = getenv("HOME");
  74. if (path == NULL) {
  75. fprintf(stderr, "No HOME environment variable\n");
  76. return;
  77. }
  78. }
  79. if (chdir(path) < 0)
  80. perror(path);
  81. }
  82. void
  83. do_mkdir(argc, argv)
  84. int argc;
  85. char **argv;
  86. {
  87. int state = 0, mode = -1;
  88. while (argc-- > 1) {
  89. if (state == 0) {
  90. if (strcmp(argv[1], "-m") == 0)
  91. state = 1;
  92. else if (mkdir(argv[1], 0777) < 0)
  93. perror(argv[1]);
  94. else if (mode != -1 && chmod(argv[1], mode) < 0)
  95. perror(argv[1]);
  96. } else if (state == 1) {
  97. mode = strtol(argv[1], NULL, 8);
  98. state = 0;
  99. }
  100. argv++;
  101. }
  102. }
  103. void
  104. do_sleep(argc, argv)
  105. int argc;
  106. char **argv;
  107. {
  108. if (argc > 1)
  109. sleep(atoi(argv[1]));
  110. }
  111. void
  112. do_mknod(argc, argv)
  113. int argc;
  114. char **argv;
  115. {
  116. char *cp;
  117. int mode;
  118. int major;
  119. int minor;
  120. mode = 0666;
  121. if (strcmp(argv[2], "b") == 0)
  122. mode |= S_IFBLK;
  123. else if (strcmp(argv[2], "c") == 0)
  124. mode |= S_IFCHR;
  125. else {
  126. fprintf(stderr, "Bad device type\n");
  127. return;
  128. }
  129. major = 0;
  130. cp = argv[3];
  131. while (isdecimal(*cp))
  132. major = major * 10 + *cp++ - '0';
  133. if (*cp || (major < 0) || (major > 255)) {
  134. fprintf(stderr, "Bad major number\n");
  135. return;
  136. }
  137. minor = 0;
  138. cp = argv[4];
  139. while (isdecimal(*cp))
  140. minor = minor * 10 + *cp++ - '0';
  141. if (*cp || (minor < 0) || (minor > 255)) {
  142. fprintf(stderr, "Bad minor number\n");
  143. return;
  144. }
  145. if (mknod(argv[1], mode, major * 256 + minor) < 0)
  146. perror(argv[1]);
  147. }
  148. void
  149. do_rmdir(argc, argv)
  150. int argc;
  151. char **argv;
  152. {
  153. while (argc-- > 1) {
  154. if (rmdir(argv[1]) < 0)
  155. perror(argv[1]);
  156. argv++;
  157. }
  158. }
  159. void
  160. do_sync(argc, argv)
  161. int argc;
  162. char **argv;
  163. {
  164. #ifdef CONFIG_USER_FLATFSD_FLATFSD
  165. system("exec flatfsd -s");
  166. #endif
  167. sync();
  168. }
  169. void
  170. do_rm(argc, argv)
  171. int argc;
  172. char **argv;
  173. {
  174. while (argc-- > 1) {
  175. if (unlink(argv[1]) < 0)
  176. perror(argv[1]);
  177. argv++;
  178. }
  179. }
  180. void
  181. do_chmod(argc, argv)
  182. int argc;
  183. char **argv;
  184. {
  185. char *cp;
  186. int mode;
  187. mode = 0;
  188. cp = argv[1];
  189. while (isoctal(*cp))
  190. mode = mode * 8 + (*cp++ - '0');
  191. if (*cp) {
  192. fprintf(stderr, "Mode must be octal\n");
  193. return;
  194. }
  195. argc--;
  196. argv++;
  197. while (argc-- > 1) {
  198. if (chmod(argv[1], mode) < 0)
  199. perror(argv[1]);
  200. argv++;
  201. }
  202. }
  203. void
  204. do_chown(argc, argv)
  205. int argc;
  206. char **argv;
  207. {
  208. char *cp;
  209. int uid;
  210. struct passwd *pwd;
  211. struct stat statbuf;
  212. cp = argv[1];
  213. if (isdecimal(*cp)) {
  214. uid = 0;
  215. while (isdecimal(*cp))
  216. uid = uid * 10 + (*cp++ - '0');
  217. if (*cp) {
  218. fprintf(stderr, "Bad uid value\n");
  219. return;
  220. }
  221. } else {
  222. pwd = getpwnam(cp);
  223. if (pwd == NULL) {
  224. fprintf(stderr, "Unknown user name\n");
  225. return;
  226. }
  227. uid = pwd->pw_uid;
  228. }
  229. argc--;
  230. argv++;
  231. while (argc-- > 1) {
  232. argv++;
  233. if ((stat(*argv, &statbuf) < 0) ||
  234. (chown(*argv, uid, statbuf.st_gid) < 0))
  235. perror(*argv);
  236. }
  237. }
  238. void
  239. do_chgrp(argc, argv)
  240. int argc;
  241. char **argv;
  242. {
  243. char *cp;
  244. int gid;
  245. struct group *grp;
  246. struct stat statbuf;
  247. cp = argv[1];
  248. if (isdecimal(*cp)) {
  249. gid = 0;
  250. while (isdecimal(*cp))
  251. gid = gid * 10 + (*cp++ - '0');
  252. if (*cp) {
  253. fprintf(stderr, "Bad gid value\n");
  254. return;
  255. }
  256. } else {
  257. grp = getgrnam(cp);
  258. if (grp == NULL) {
  259. fprintf(stderr, "Unknown group name\n");
  260. return;
  261. }
  262. gid = grp->gr_gid;
  263. }
  264. argc--;
  265. argv++;
  266. while (argc-- > 1) {
  267. argv++;
  268. if ((stat(*argv, &statbuf) < 0) ||
  269. (chown(*argv, statbuf.st_uid, gid) < 0))
  270. perror(*argv);
  271. }
  272. }
  273. void
  274. do_touch(argc, argv)
  275. int argc;
  276. char **argv;
  277. {
  278. char *name;
  279. int fd;
  280. struct utimbuf now;
  281. time(&now.actime);
  282. now.modtime = now.actime;
  283. while (argc-- > 1) {
  284. name = *(++argv);
  285. if (utime(name, &now) <0)
  286. {
  287. fd = open(name, O_CREAT | O_WRONLY | O_EXCL, 0666);
  288. if (fd >= 0)
  289. {
  290. close(fd);
  291. continue;
  292. }
  293. perror(name);
  294. }
  295. }
  296. }
  297. void
  298. do_mv(argc, argv)
  299. int argc;
  300. char **argv;
  301. {
  302. int dirflag;
  303. char *srcname;
  304. char *destname;
  305. char *lastarg;
  306. lastarg = argv[argc - 1];
  307. dirflag = isadir(lastarg);
  308. if ((argc > 3) && !dirflag) {
  309. fprintf(stderr, "%s: not a directory\n", lastarg);
  310. return;
  311. }
  312. while (argc-- > 2) {
  313. srcname = *(++argv);
  314. if (access(srcname, 0) < 0) {
  315. perror(srcname);
  316. continue;
  317. }
  318. destname = lastarg;
  319. if (dirflag)
  320. destname = buildname(destname, srcname);
  321. if (rename(srcname, destname) >= 0)
  322. continue;
  323. if (errno != EXDEV) {
  324. perror(destname);
  325. continue;
  326. }
  327. if (!copyfile(srcname, destname, TRUE))
  328. continue;
  329. if (unlink(srcname) < 0)
  330. perror(srcname);
  331. }
  332. }
  333. void
  334. do_ln(argc, argv)
  335. int argc;
  336. char **argv;
  337. {
  338. int dirflag;
  339. char *srcname;
  340. char *destname;
  341. char *lastarg;
  342. if (argv[1][0] == '-') {
  343. if (strcmp(argv[1], "-s")) {
  344. fprintf(stderr, "Unknown option\n");
  345. return;
  346. }
  347. if (argc != 4) {
  348. fprintf(stderr, "Wrong number of arguments for symbolic link\n");
  349. return;
  350. }
  351. #ifdef S_ISLNK
  352. if (symlink(argv[2], argv[3]) < 0)
  353. perror(argv[3]);
  354. #else
  355. fprintf(stderr, "Symbolic links are not allowed\n");
  356. #endif
  357. return;
  358. }
  359. /*
  360. * Here for normal hard links.
  361. */
  362. lastarg = argv[argc - 1];
  363. dirflag = isadir(lastarg);
  364. if ((argc > 3) && !dirflag) {
  365. fprintf(stderr, "%s: not a directory\n", lastarg);
  366. return;
  367. }
  368. while (argc-- > 2) {
  369. srcname = *(++argv);
  370. if (access(srcname, 0) < 0) {
  371. perror(srcname);
  372. continue;
  373. }
  374. destname = lastarg;
  375. if (dirflag)
  376. destname = buildname(destname, srcname);
  377. if (link(srcname, destname) < 0) {
  378. perror(destname);
  379. continue;
  380. }
  381. }
  382. }
  383. void
  384. do_cp(argc, argv)
  385. int argc;
  386. char **argv;
  387. {
  388. BOOL dirflag;
  389. char *srcname;
  390. char *destname;
  391. char *lastarg;
  392. lastarg = argv[argc - 1];
  393. dirflag = isadir(lastarg);
  394. if ((argc > 3) && !dirflag) {
  395. fprintf(stderr, "%s: not a directory\n", lastarg);
  396. return;
  397. }
  398. while (argc-- > 2) {
  399. destname = lastarg;
  400. srcname = *++argv;
  401. if (dirflag)
  402. destname = buildname(destname, srcname);
  403. (void) copyfile(srcname, destname, FALSE);
  404. }
  405. }
  406. void
  407. do_mount(argc, argv)
  408. int argc;
  409. char **argv;
  410. {
  411. char *str;
  412. char *type;
  413. argc--;
  414. argv++;
  415. type = "minix";
  416. while ((argc > 0) && (**argv == '-')) {
  417. argc--;
  418. str = *argv++ ;
  419. while (*++str) switch (*str) {
  420. case 't':
  421. if ((argc <= 0) || (**argv == '-')) {
  422. fprintf(stderr, "Missing file system type\n");
  423. return;
  424. }
  425. type = *argv++;
  426. argc--;
  427. break;
  428. default:
  429. fprintf(stderr, "Unknown option\n");
  430. return;
  431. }
  432. }
  433. if (argc != 2) {
  434. fprintf(stderr, "Wrong number of arguments for mount\n");
  435. return;
  436. }
  437. if (mount(argv[0], argv[1], type, 0, 0) < 0)
  438. perror("mount failed");
  439. }
  440. void
  441. do_umount(argc, argv)
  442. int argc;
  443. char **argv;
  444. {
  445. if (umount(argv[1]) < 0)
  446. perror(argv[1]);
  447. }
  448. void
  449. do_cmp(argc, argv)
  450. int argc;
  451. char **argv;
  452. {
  453. int fd1;
  454. int fd2;
  455. int cc1;
  456. int cc2;
  457. long pos;
  458. char *srcname;
  459. char *destname;
  460. char *lastarg;
  461. char *bp1;
  462. char *bp2;
  463. char *buf1;
  464. char *buf2;
  465. struct stat statbuf1;
  466. struct stat statbuf2;
  467. if (stat(argv[1], &statbuf1) < 0) {
  468. perror(argv[1]);
  469. return;
  470. }
  471. if (stat(argv[2], &statbuf2) < 0) {
  472. perror(argv[2]);
  473. return;
  474. }
  475. if ((statbuf1.st_dev == statbuf2.st_dev) &&
  476. (statbuf1.st_ino == statbuf2.st_ino))
  477. {
  478. printf("Files are links to each other\n");
  479. return;
  480. }
  481. if (statbuf1.st_size != statbuf2.st_size) {
  482. printf("Files are different sizes\n");
  483. return;
  484. }
  485. fd1 = open(argv[1], 0);
  486. if (fd1 < 0) {
  487. perror(argv[1]);
  488. return;
  489. }
  490. fd2 = open(argv[2], 0);
  491. if (fd2 < 0) {
  492. perror(argv[2]);
  493. close(fd1);
  494. return;
  495. }
  496. buf1 = malloc(8192-16);
  497. buf2 = malloc(8192-16);
  498. pos = 0;
  499. while (TRUE) {
  500. if (intflag)
  501. goto closefiles;
  502. cc1 = read(fd1, buf1, 8192-16);
  503. if (cc1 < 0) {
  504. perror(argv[1]);
  505. goto closefiles;
  506. }
  507. cc2 = read(fd2, buf2, 8192-16);
  508. if (cc2 < 0) {
  509. perror(argv[2]);
  510. goto closefiles;
  511. }
  512. if ((cc1 == 0) && (cc2 == 0)) {
  513. printf("Files are identical\n");
  514. goto closefiles;
  515. }
  516. if (cc1 < cc2) {
  517. printf("First file is shorter than second\n");
  518. goto closefiles;
  519. }
  520. if (cc1 > cc2) {
  521. printf("Second file is shorter than first\n");
  522. goto closefiles;
  523. }
  524. if (memcmp(buf1, buf2, cc1) == 0) {
  525. pos += cc1;
  526. continue;
  527. }
  528. bp1 = buf1;
  529. bp2 = buf2;
  530. while (*bp1++ == *bp2++)
  531. pos++;
  532. printf("Files differ at byte position %ld\n", pos);
  533. goto closefiles;
  534. }
  535. closefiles:
  536. close(fd1);
  537. close(fd2);
  538. free(buf1);
  539. free(buf2);
  540. }
  541. void
  542. do_more(argc, argv)
  543. int argc;
  544. char **argv;
  545. {
  546. FILE *fp;
  547. char *name;
  548. int ch;
  549. int line;
  550. int col;
  551. char buf[80];
  552. while (argc-- > 1) {
  553. name = *(++argv);
  554. fp = fopen(name, "r");
  555. if (fp == NULL) {
  556. perror(name);
  557. return;
  558. }
  559. printf("<< %s >>\n", name);
  560. line = 1;
  561. col = 0;
  562. while (fp && ((ch = fgetc(fp)) != EOF)) {
  563. switch (ch) {
  564. case '\r':
  565. col = 0;
  566. break;
  567. case '\n':
  568. line++;
  569. col = 0;
  570. break;
  571. case '\t':
  572. col = ((col + 1) | 0x07) + 1;
  573. break;
  574. case '\b':
  575. if (col > 0)
  576. col--;
  577. break;
  578. default:
  579. col++;
  580. }
  581. putchar(ch);
  582. if (col >= 80) {
  583. col -= 80;
  584. line++;
  585. }
  586. if (line < 24)
  587. continue;
  588. if (col > 0)
  589. putchar('\n');
  590. printf("--More--");
  591. fflush(stdout);
  592. if (intflag || (read(0, buf, sizeof(buf)) < 0)) {
  593. if (fp)
  594. fclose(fp);
  595. return;
  596. }
  597. ch = buf[0];
  598. if (ch == ':')
  599. ch = buf[1];
  600. switch (ch) {
  601. case 'N':
  602. case 'n':
  603. fclose(fp);
  604. fp = NULL;
  605. break;
  606. case 'Q':
  607. case 'q':
  608. fclose(fp);
  609. return;
  610. }
  611. col = 0;
  612. line = 1;
  613. }
  614. if (fp)
  615. fclose(fp);
  616. }
  617. }
  618. void
  619. do_exit(argc, argv)
  620. int argc;
  621. char **argv;
  622. {
  623. exit(0);
  624. }
  625. void
  626. do_setenv(argc, argv)
  627. int argc;
  628. char **argv;
  629. {
  630. setenv(argv[1], argv[2], 1);
  631. }
  632. void
  633. do_printenv(argc, argv)
  634. int argc;
  635. char **argv;
  636. {
  637. char **env;
  638. extern char **environ;
  639. int len;
  640. env = environ;
  641. if (argc == 1) {
  642. while (*env)
  643. printf("%s\n", *env++);
  644. return;
  645. }
  646. len = strlen(argv[1]);
  647. while (*env) {
  648. if ((strlen(*env) > len) && (env[0][len] == '=') &&
  649. (memcmp(argv[1], *env, len) == 0))
  650. {
  651. printf("%s\n", &env[0][len+1]);
  652. return;
  653. }
  654. env++;
  655. }
  656. }
  657. void
  658. do_umask(argc, argv)
  659. int argc;
  660. char **argv;
  661. {
  662. char *cp;
  663. int mask;
  664. if (argc <= 1) {
  665. mask = umask(0);
  666. umask(mask);
  667. printf("%03o\n", mask);
  668. return;
  669. }
  670. mask = 0;
  671. cp = argv[1];
  672. while (isoctal(*cp))
  673. mask = mask * 8 + *cp++ - '0';
  674. if (*cp || (mask & ~0777)) {
  675. fprintf(stderr, "Bad umask value\n");
  676. return;
  677. }
  678. umask(mask);
  679. }
  680. void
  681. do_kill(argc, argv)
  682. int argc;
  683. char **argv;
  684. {
  685. char *cp;
  686. int sig;
  687. int pid;
  688. sig = SIGTERM;
  689. if (argv[1][0] == '-') {
  690. cp = &argv[1][1];
  691. if (strcmp(cp, "HUP") == 0)
  692. sig = SIGHUP;
  693. else if (strcmp(cp, "INT") == 0)
  694. sig = SIGINT;
  695. else if (strcmp(cp, "QUIT") == 0)
  696. sig = SIGQUIT;
  697. else if (strcmp(cp, "ILL") == 0)
  698. sig = SIGILL;
  699. else if (strcmp(cp, "TRAP") == 0)
  700. sig = SIGTRAP;
  701. else if (strcmp(cp, "ABRT") == 0)
  702. sig = SIGABRT;
  703. else if (strcmp(cp, "IOT") == 0)
  704. sig = SIGIOT;
  705. else if (strcmp(cp, "BUS") == 0)
  706. sig = SIGBUS;
  707. else if (strcmp(cp, "FPE") == 0)
  708. sig = SIGFPE;
  709. else if (strcmp(cp, "KILL") == 0)
  710. sig = SIGKILL;
  711. else if (strcmp(cp, "USR1") == 0)
  712. sig = SIGUSR1;
  713. else if (strcmp(cp, "SEGV") == 0)
  714. sig = SIGSEGV;
  715. else if (strcmp(cp, "USR2") == 0)
  716. sig = SIGUSR2;
  717. else if (strcmp(cp, "PIPE") == 0)
  718. sig = SIGPIPE;
  719. else if (strcmp(cp, "ALRM") == 0)
  720. sig = SIGALRM;
  721. else if (strcmp(cp, "TERM") == 0)
  722. sig = SIGTERM;
  723. #ifdef SIGSTKFLT
  724. else if (strcmp(cp, "STKFLT") == 0)
  725. sig = SIGSTKFLT;
  726. #endif
  727. else if (strcmp(cp, "CHLD") == 0)
  728. sig = SIGCHLD;
  729. else if (strcmp(cp, "CONT") == 0)
  730. sig = SIGCONT;
  731. else if (strcmp(cp, "STOP") == 0)
  732. sig = SIGSTOP;
  733. else if (strcmp(cp, "TSTP") == 0)
  734. sig = SIGTSTP;
  735. else if (strcmp(cp, "TTIN") == 0)
  736. sig = SIGTTIN;
  737. else if (strcmp(cp, "TTOU") == 0)
  738. sig = SIGTTOU;
  739. else if (strcmp(cp, "URG") == 0)
  740. sig = SIGURG;
  741. else if (strcmp(cp, "PWR") == 0)
  742. sig = SIGPWR;
  743. else {
  744. sig = 0;
  745. while (isdecimal(*cp))
  746. sig = sig * 10 + *cp++ - '0';
  747. if (*cp) {
  748. fprintf(stderr, "Unknown signal\n");
  749. exit_code = 1;
  750. return;
  751. }
  752. }
  753. argc--;
  754. argv++;
  755. }
  756. while (argc-- > 1) {
  757. cp = *++argv;
  758. pid = 0;
  759. while (isdecimal(*cp))
  760. pid = pid * 10 + *cp++ - '0';
  761. if (*cp) {
  762. fprintf(stderr, "Non-numeric pid\n");
  763. exit_code = 1;
  764. return;
  765. }
  766. if (kill(pid, sig) < 0) {
  767. perror(*argv);
  768. exit_code = 1;
  769. }
  770. }
  771. }
  772. /* END CODE */