fix preselection of instructions set
[openadk.git] / package / sash / src / cmds.c
blob149a1a755e66c211ddb5b34b8f215bd8e61fa265
1 /*
2 * Modifications for uClinux
3 * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
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.
10 * Most simple built-in commands are here.
13 #include "sash.h"
15 #include <sys/types.h>
16 #include <sys/mount.h>
17 #include <sys/stat.h>
18 #include <sys/time.h>
19 #include <time.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <signal.h>
23 #include <pwd.h>
24 #include <grp.h>
25 #include <utime.h>
26 #include <errno.h>
28 void
29 do_echo(argc, argv)
30 int argc;
31 char **argv;
33 BOOL first;
35 first = TRUE;
36 while (argc-- > 1) {
37 if (!first)
38 fputc(' ', stdout);
39 first = FALSE;
40 fputs(*++argv, stdout);
42 fputc('\n', stdout);
46 void
47 do_pwd(argc, argv)
48 int argc;
49 char **argv;
51 char buf[PATHLEN];
53 if (getcwd(buf, PATHLEN) == NULL) {
54 fprintf(stderr, "Cannot get current directory\n");
55 return;
58 printf("%s\n", buf);
61 void
62 do_cd(argc, argv)
63 int argc;
64 char **argv;
66 char *path;
68 if (argc > 1)
69 path = argv[1];
70 else {
71 path = getenv("HOME");
72 if (path == NULL) {
73 fprintf(stderr, "No HOME environment variable\n");
74 return;
78 if (chdir(path) < 0)
79 perror(path);
83 void
84 do_mkdir(argc, argv)
85 int argc;
86 char **argv;
88 int state = 0, mode = -1;
90 while (argc-- > 1) {
91 if (state == 0) {
92 if (strcmp(argv[1], "-m") == 0)
93 state = 1;
94 else if (mkdir(argv[1], 0777) < 0)
95 perror(argv[1]);
96 else if (mode != -1 && chmod(argv[1], mode) < 0)
97 perror(argv[1]);
98 } else if (state == 1) {
99 mode = strtol(argv[1], NULL, 8);
100 state = 0;
102 argv++;
106 void
107 do_sleep(argc, argv)
108 int argc;
109 char **argv;
111 if (argc > 1)
112 sleep(atoi(argv[1]));
115 void
116 do_mknod(argc, argv)
117 int argc;
118 char **argv;
120 char *cp;
121 int mode;
122 int major;
123 int minor;
125 mode = 0666;
127 if (strcmp(argv[2], "b") == 0)
128 mode |= S_IFBLK;
129 else if (strcmp(argv[2], "c") == 0)
130 mode |= S_IFCHR;
131 else {
132 fprintf(stderr, "Bad device type\n");
133 return;
136 major = 0;
137 cp = argv[3];
138 while (isdecimal(*cp))
139 major = major * 10 + *cp++ - '0';
141 if (*cp || (major < 0) || (major > 255)) {
142 fprintf(stderr, "Bad major number\n");
143 return;
146 minor = 0;
147 cp = argv[4];
148 while (isdecimal(*cp))
149 minor = minor * 10 + *cp++ - '0';
151 if (*cp || (minor < 0) || (minor > 255)) {
152 fprintf(stderr, "Bad minor number\n");
153 return;
156 if (mknod(argv[1], mode, major * 256 + minor) < 0)
157 perror(argv[1]);
161 void
162 do_rmdir(argc, argv)
163 int argc;
164 char **argv;
166 while (argc-- > 1) {
167 if (rmdir(argv[1]) < 0)
168 perror(argv[1]);
169 argv++;
174 void
175 do_sync(argc, argv)
176 int argc;
177 char **argv;
179 sync();
183 void
184 do_rm(argc, argv)
185 int argc;
186 char **argv;
188 while (argc-- > 1) {
189 if (unlink(argv[1]) < 0)
190 perror(argv[1]);
191 argv++;
196 void
197 do_chmod(argc, argv)
198 int argc;
199 char **argv;
201 char *cp;
202 int mode;
204 mode = 0;
205 cp = argv[1];
206 while (isoctal(*cp))
207 mode = mode * 8 + (*cp++ - '0');
209 if (*cp) {
210 fprintf(stderr, "Mode must be octal\n");
211 return;
213 argc--;
214 argv++;
216 while (argc-- > 1) {
217 if (chmod(argv[1], mode) < 0)
218 perror(argv[1]);
219 argv++;
224 void
225 do_chown(argc, argv)
226 int argc;
227 char **argv;
229 char *cp;
230 int uid;
231 struct passwd *pwd;
232 struct stat statbuf;
234 cp = argv[1];
235 if (isdecimal(*cp)) {
236 uid = 0;
237 while (isdecimal(*cp))
238 uid = uid * 10 + (*cp++ - '0');
240 if (*cp) {
241 fprintf(stderr, "Bad uid value\n");
242 return;
244 } else {
245 pwd = getpwnam(cp);
246 if (pwd == NULL) {
247 fprintf(stderr, "Unknown user name\n");
248 return;
251 uid = pwd->pw_uid;
254 argc--;
255 argv++;
257 while (argc-- > 1) {
258 argv++;
259 if ((stat(*argv, &statbuf) < 0) ||
260 (chown(*argv, uid, statbuf.st_gid) < 0))
261 perror(*argv);
266 void
267 do_chgrp(argc, argv)
268 int argc;
269 char **argv;
271 char *cp;
272 int gid;
273 struct group *grp;
274 struct stat statbuf;
276 cp = argv[1];
277 if (isdecimal(*cp)) {
278 gid = 0;
279 while (isdecimal(*cp))
280 gid = gid * 10 + (*cp++ - '0');
282 if (*cp) {
283 fprintf(stderr, "Bad gid value\n");
284 return;
286 } else {
287 grp = getgrnam(cp);
288 if (grp == NULL) {
289 fprintf(stderr, "Unknown group name\n");
290 return;
293 gid = grp->gr_gid;
296 argc--;
297 argv++;
299 while (argc-- > 1) {
300 argv++;
301 if ((stat(*argv, &statbuf) < 0) ||
302 (chown(*argv, statbuf.st_uid, gid) < 0))
303 perror(*argv);
308 void
309 do_touch(argc, argv)
310 int argc;
311 char **argv;
313 char *name;
314 int fd;
315 struct utimbuf now;
317 time(&now.actime);
318 now.modtime = now.actime;
320 while (argc-- > 1) {
321 name = *(++argv);
323 if (utime(name, &now) <0)
325 fd = open(name, O_CREAT | O_WRONLY | O_EXCL, 0666);
326 if (fd >= 0)
328 close(fd);
329 continue;
331 perror(name);
337 void
338 do_mv(argc, argv)
339 int argc;
340 char **argv;
342 int dirflag;
343 char *srcname;
344 char *destname;
345 char *lastarg;
347 lastarg = argv[argc - 1];
349 dirflag = isadir(lastarg);
351 if ((argc > 3) && !dirflag) {
352 fprintf(stderr, "%s: not a directory\n", lastarg);
353 return;
356 while (argc-- > 2) {
357 srcname = *(++argv);
358 if (access(srcname, 0) < 0) {
359 perror(srcname);
360 continue;
363 destname = lastarg;
364 if (dirflag)
365 destname = buildname(destname, srcname);
367 if (rename(srcname, destname) >= 0)
368 continue;
370 if (errno != EXDEV) {
371 perror(destname);
372 continue;
375 if (!copyfile(srcname, destname, TRUE))
376 continue;
378 if (unlink(srcname) < 0)
379 perror(srcname);
384 void
385 do_ln(argc, argv)
386 int argc;
387 char **argv;
389 int dirflag;
390 char *srcname;
391 char *destname;
392 char *lastarg;
394 if (argv[1][0] == '-') {
395 if (strcmp(argv[1], "-s")) {
396 fprintf(stderr, "Unknown option\n");
397 return;
400 if (argc != 4) {
401 fprintf(stderr, "Wrong number of arguments for symbolic link\n");
402 return;
405 #ifdef S_ISLNK
406 if (symlink(argv[2], argv[3]) < 0)
407 perror(argv[3]);
408 #else
409 fprintf(stderr, "Symbolic links are not allowed\n");
410 #endif
411 return;
415 * Here for normal hard links.
417 lastarg = argv[argc - 1];
418 dirflag = isadir(lastarg);
420 if ((argc > 3) && !dirflag) {
421 fprintf(stderr, "%s: not a directory\n", lastarg);
422 return;
425 while (argc-- > 2) {
426 srcname = *(++argv);
427 if (access(srcname, 0) < 0) {
428 perror(srcname);
429 continue;
432 destname = lastarg;
433 if (dirflag)
434 destname = buildname(destname, srcname);
436 if (link(srcname, destname) < 0) {
437 perror(destname);
438 continue;
444 void
445 do_cp(argc, argv)
446 int argc;
447 char **argv;
449 BOOL dirflag;
450 char *srcname;
451 char *destname;
452 char *lastarg;
454 lastarg = argv[argc - 1];
456 dirflag = isadir(lastarg);
458 if ((argc > 3) && !dirflag) {
459 fprintf(stderr, "%s: not a directory\n", lastarg);
460 return;
463 while (argc-- > 2) {
464 destname = lastarg;
465 srcname = *++argv;
466 if (dirflag)
467 destname = buildname(destname, srcname);
469 (void) copyfile(srcname, destname, FALSE);
474 void
475 do_mount(argc, argv)
476 int argc;
477 char **argv;
479 char *str;
480 char *type;
482 argc--;
483 argv++;
484 type = "minix";
486 while ((argc > 0) && (**argv == '-')) {
487 argc--;
488 str = *argv++ ;
490 while (*++str) switch (*str) {
491 case 't':
492 if ((argc <= 0) || (**argv == '-')) {
493 fprintf(stderr, "Missing file system type\n");
494 return;
497 type = *argv++;
498 argc--;
499 break;
501 default:
502 fprintf(stderr, "Unknown option\n");
503 return;
507 if (argc != 2) {
508 fprintf(stderr, "Wrong number of arguments for mount\n");
509 return;
512 if (mount(argv[0], argv[1], type, 0, 0) < 0)
513 perror("mount failed");
517 void
518 do_umount(argc, argv)
519 int argc;
520 char **argv;
522 if (umount(argv[1]) < 0)
523 perror(argv[1]);
527 void
528 do_cmp(argc, argv)
529 int argc;
530 char **argv;
532 int fd1;
533 int fd2;
534 int cc1;
535 int cc2;
536 long pos;
537 char *srcname;
538 char *destname;
539 char *lastarg;
540 char *bp1;
541 char *bp2;
542 char *buf1;
543 char *buf2;
544 struct stat statbuf1;
545 struct stat statbuf2;
547 if (stat(argv[1], &statbuf1) < 0) {
548 perror(argv[1]);
549 return;
552 if (stat(argv[2], &statbuf2) < 0) {
553 perror(argv[2]);
554 return;
557 if ((statbuf1.st_dev == statbuf2.st_dev) &&
558 (statbuf1.st_ino == statbuf2.st_ino))
560 printf("Files are links to each other\n");
561 return;
564 if (statbuf1.st_size != statbuf2.st_size) {
565 printf("Files are different sizes\n");
566 return;
569 fd1 = open(argv[1], 0);
570 if (fd1 < 0) {
571 perror(argv[1]);
572 return;
575 fd2 = open(argv[2], 0);
576 if (fd2 < 0) {
577 perror(argv[2]);
578 close(fd1);
579 return;
582 buf1 = malloc(8192-16);
583 buf2 = malloc(8192-16);
585 pos = 0;
586 while (TRUE) {
587 if (intflag)
588 goto closefiles;
590 cc1 = read(fd1, buf1, 8192-16);
591 if (cc1 < 0) {
592 perror(argv[1]);
593 goto closefiles;
596 cc2 = read(fd2, buf2, 8192-16);
597 if (cc2 < 0) {
598 perror(argv[2]);
599 goto closefiles;
602 if ((cc1 == 0) && (cc2 == 0)) {
603 printf("Files are identical\n");
604 goto closefiles;
607 if (cc1 < cc2) {
608 printf("First file is shorter than second\n");
609 goto closefiles;
612 if (cc1 > cc2) {
613 printf("Second file is shorter than first\n");
614 goto closefiles;
617 if (memcmp(buf1, buf2, cc1) == 0) {
618 pos += cc1;
619 continue;
622 bp1 = buf1;
623 bp2 = buf2;
624 while (*bp1++ == *bp2++)
625 pos++;
627 printf("Files differ at byte position %ld\n", pos);
628 goto closefiles;
631 closefiles:
632 close(fd1);
633 close(fd2);
634 free(buf1);
635 free(buf2);
639 void
640 do_more(argc, argv)
641 int argc;
642 char **argv;
644 FILE *fp;
645 char *name;
646 int ch;
647 int line;
648 int col;
649 char buf[80];
651 while (argc-- > 1) {
652 name = *(++argv);
654 fp = fopen(name, "r");
655 if (fp == NULL) {
656 perror(name);
657 return;
660 printf("<< %s >>\n", name);
661 line = 1;
662 col = 0;
664 while (fp && ((ch = fgetc(fp)) != EOF)) {
665 switch (ch) {
666 case '\r':
667 col = 0;
668 break;
670 case '\n':
671 line++;
672 col = 0;
673 break;
675 case '\t':
676 col = ((col + 1) | 0x07) + 1;
677 break;
679 case '\b':
680 if (col > 0)
681 col--;
682 break;
684 default:
685 col++;
688 putchar(ch);
689 if (col >= 80) {
690 col -= 80;
691 line++;
694 if (line < 24)
695 continue;
697 if (col > 0)
698 putchar('\n');
700 printf("--More--");
701 fflush(stdout);
703 if (intflag || (read(0, buf, sizeof(buf)) < 0)) {
704 if (fp)
705 fclose(fp);
706 return;
709 ch = buf[0];
710 if (ch == ':')
711 ch = buf[1];
713 switch (ch) {
714 case 'N':
715 case 'n':
716 fclose(fp);
717 fp = NULL;
718 break;
720 case 'Q':
721 case 'q':
722 fclose(fp);
723 return;
726 col = 0;
727 line = 1;
729 if (fp)
730 fclose(fp);
735 void
736 do_exit(argc, argv)
737 int argc;
738 char **argv;
740 exit(0);
744 void
745 do_setenv(argc, argv)
746 int argc;
747 char **argv;
749 setenv(argv[1], argv[2], 1);
753 void
754 do_printenv(argc, argv)
755 int argc;
756 char **argv;
758 char **env;
759 extern char **environ;
760 int len;
762 env = environ;
764 if (argc == 1) {
765 while (*env)
766 printf("%s\n", *env++);
767 return;
770 len = strlen(argv[1]);
771 while (*env) {
772 if ((strlen(*env) > len) && (env[0][len] == '=') &&
773 (memcmp(argv[1], *env, len) == 0))
775 printf("%s\n", &env[0][len+1]);
776 return;
778 env++;
783 void
784 do_umask(argc, argv)
785 int argc;
786 char **argv;
788 char *cp;
789 int mask;
791 if (argc <= 1) {
792 mask = umask(0);
793 umask(mask);
794 printf("%03o\n", mask);
795 return;
798 mask = 0;
799 cp = argv[1];
800 while (isoctal(*cp))
801 mask = mask * 8 + *cp++ - '0';
803 if (*cp || (mask & ~0777)) {
804 fprintf(stderr, "Bad umask value\n");
805 return;
808 umask(mask);
812 void
813 do_kill(argc, argv)
814 int argc;
815 char **argv;
817 char *cp;
818 int sig;
819 int pid;
821 sig = SIGTERM;
823 if (argv[1][0] == '-') {
824 cp = &argv[1][1];
825 if (strcmp(cp, "HUP") == 0)
826 sig = SIGHUP;
827 else if (strcmp(cp, "INT") == 0)
828 sig = SIGINT;
829 else if (strcmp(cp, "QUIT") == 0)
830 sig = SIGQUIT;
831 else if (strcmp(cp, "ILL") == 0)
832 sig = SIGILL;
833 else if (strcmp(cp, "TRAP") == 0)
834 sig = SIGTRAP;
835 else if (strcmp(cp, "ABRT") == 0)
836 sig = SIGABRT;
837 else if (strcmp(cp, "IOT") == 0)
838 sig = SIGIOT;
839 else if (strcmp(cp, "BUS") == 0)
840 sig = SIGBUS;
841 else if (strcmp(cp, "FPE") == 0)
842 sig = SIGFPE;
843 else if (strcmp(cp, "KILL") == 0)
844 sig = SIGKILL;
845 else if (strcmp(cp, "USR1") == 0)
846 sig = SIGUSR1;
847 else if (strcmp(cp, "SEGV") == 0)
848 sig = SIGSEGV;
849 else if (strcmp(cp, "USR2") == 0)
850 sig = SIGUSR2;
851 else if (strcmp(cp, "PIPE") == 0)
852 sig = SIGPIPE;
853 else if (strcmp(cp, "ALRM") == 0)
854 sig = SIGALRM;
855 else if (strcmp(cp, "TERM") == 0)
856 sig = SIGTERM;
857 #ifdef SIGSTKFLT
858 else if (strcmp(cp, "STKFLT") == 0)
859 sig = SIGSTKFLT;
860 #endif
861 else if (strcmp(cp, "CHLD") == 0)
862 sig = SIGCHLD;
863 else if (strcmp(cp, "CONT") == 0)
864 sig = SIGCONT;
865 else if (strcmp(cp, "STOP") == 0)
866 sig = SIGSTOP;
867 else if (strcmp(cp, "TSTP") == 0)
868 sig = SIGTSTP;
869 else if (strcmp(cp, "TTIN") == 0)
870 sig = SIGTTIN;
871 else if (strcmp(cp, "TTOU") == 0)
872 sig = SIGTTOU;
873 else if (strcmp(cp, "URG") == 0)
874 sig = SIGURG;
875 else if (strcmp(cp, "PWR") == 0)
876 sig = SIGPWR;
877 else {
878 sig = 0;
879 while (isdecimal(*cp))
880 sig = sig * 10 + *cp++ - '0';
882 if (*cp) {
883 fprintf(stderr, "Unknown signal\n");
884 exit_code = 1;
885 return;
888 argc--;
889 argv++;
892 while (argc-- > 1) {
893 cp = *++argv;
894 pid = 0;
895 while (isdecimal(*cp))
896 pid = pid * 10 + *cp++ - '0';
898 if (*cp) {
899 fprintf(stderr, "Non-numeric pid\n");
900 exit_code = 1;
901 return;
904 if (kill(pid, sig) < 0) {
905 perror(*argv);
906 exit_code = 1;
911 /* END CODE */