Kernel 0.6.3; ZNFS filesystem is able to create file, directories, change directory...
[ZeXOS.git] / kernel / core / commands.c
blobbd536a3f62fa7c340716b828b8bac349b2e9d611
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <build.h>
23 #include <system.h>
24 #include <arch/io.h>
25 #include <string.h>
26 #include <partition.h>
27 #include <env.h>
28 #include <dev.h>
29 #include <vfs.h>
30 #include <fs.h>
31 #include <tty.h>
32 #include <proc.h>
33 #include <stdlib.h>
34 #include <net/socket.h>
35 #include <module.h>
36 #include <commands.h>
37 #include <signal.h>
38 #include <smp.h>
39 #include <build.h>
40 #include <config.h>
41 #include <net/if.h>
42 #include <net/net.h>
43 #include <net/ip.h>
44 #include <net/ndp.h>
45 #include <net/tun.h>
46 #include <net/icmp.h>
48 command_t command_list;
49 extern partition_t partition_list;
51 unsigned char test[80];
53 typedef void (*void_fn_void_t)(void);
55 extern task_t task_list;
56 extern vfs_t vfs_list;
57 extern int cstrcmp (char *one, char *two);
58 extern unsigned long file_cache_id;
59 extern task_t *_curr_task;
60 extern module_t *module_load (char *modname);
61 extern unsigned long timer_ticks;
62 extern unsigned vgagui;
64 char *argparse (char *cmd)
66 unsigned cmd_len = strlen (cmd);
67 unsigned p = 1;
69 while (p < cmd_len) {
70 if (cmd[p] == ' ')
71 return cmd + p + 1;
73 p ++;
76 return "";
79 /*************************************************************\
80 | OMMANDs |
81 \*************************************************************/
84 unsigned command_help (char *command, unsigned len)
86 command_t *ctx;
88 unsigned i = 0;
90 tty_t *tty = currtty;
92 for (ctx = command_list.next; ctx != &command_list; ctx = ctx->next) {
93 i ++;
95 printf ("\n%s : %s", ctx->name, ctx->desc);
97 if (i >= 24 && vgagui != 2) {
98 settextcolor (0, 15);
99 printf ("\nPress enter to continue");
101 settextcolor (15, 0);
102 printf (" ");
104 /* wait, until enter key is pressed */
105 while (1)
106 if (tty == currtty) {
107 if (getkey () != '\n')
108 schedule ();
109 else
110 break;
111 } else
112 schedule ();
114 tty_cls (tty);
115 i = 0;
119 printf ("\n");
121 return 1;
124 unsigned command_hdd (char *command, unsigned len)
126 #ifdef ARCH_i386
127 int t;
128 int m;
129 int c;
130 int c2;
131 int h;
132 int s;
134 outb (0x70, 0x12);
135 t = inb (0x71);
137 if (t >> 4 == 0)
139 printf ("/dev/hda not installed\n");
141 else
143 outb (0x70, 0x1b);
144 c = inb (0x71);
145 outb (0x70, 0x1c);
146 c2 = inb (0x71);
147 outb (0x70, 0x1d);
148 h = inb (0x71);
149 outb (0x70, 0x23);
150 s = inb (0x71);
151 printf ("/dev/hda installed - CHS=%d-%d:%d:%d\n", c, c2, h, s);
154 if (t & 0xF == 0)
156 printf ("/dev/hdb not installed\n");
158 else
160 outb (0x70, 0x24);
161 c = inb (0x71);
162 outb (0x70, 0x25);
163 c2 = inb (0x71);
164 outb (0x70, 0x26);
165 h = inb (0x71);
166 outb (0x70, 0x2c);
167 s = inb (0x71);
168 printf ("/dev/hdb installed - CHS=%d-%d:%d:%d\n", c, c2, h, s);
170 #endif
172 return 1;
175 unsigned command_reboot (char *command, unsigned len)
177 arch_cpu_reset ();
179 while (1);
181 return 1;
184 unsigned command_halt (char *command, unsigned len)
186 arch_cpu_shutdown ();
188 puts ("\nSystem halted\nPlease press power button ..");
190 int_disable ();
192 while(1);
194 return 1;
197 unsigned command_tasks (char *command, unsigned len)
199 puts ("id\tname\tpriority\n");
201 task_t *task;
202 for (task = task_list.next; task != &task_list; task = task->next)
203 printf ("%d\t%s\t%u\n", task->id, task->name, task->priority);
205 return 1;
208 unsigned command_ps (char *command, unsigned len)
210 proc_display ();
212 return 1;
215 unsigned command_uptime (char *command, unsigned len)
217 uptime ();
219 return 1;
222 unsigned command_version (char *command, unsigned len)
224 osinfo ();
226 return 1;
229 unsigned command_debug (char *command, unsigned len)
231 if (!debug) {
232 debug = 1;
233 DPRINT ("developer mode was enabled.");
235 return 1;
238 DPRINT ("developer mode was disabled.");
239 debug = 0;
241 return 1;
244 unsigned command_mount (char *command, unsigned len)
246 strcpy (test, argparse (command));
247 char devname[20];
248 char mountpoint[32];
250 unsigned l = strlen (test);
251 unsigned x = 0;
252 while (x < l) {
253 if (test[x] == ' ')
254 break;
255 x ++;
258 memcpy (devname, test, x);
259 devname[x] = '\0';
260 strcpy (mountpoint, argparse (test));
261 unsigned y = strlen (mountpoint);
263 if (mountpoint[y-1] != '/') {
264 mountpoint[y] = '/';
265 mountpoint[y+1] = '\0';
268 if (x && y) {
269 partition_t *p = partition_find (devname);
271 if (p)
272 mount (p, "", mountpoint);
273 else
274 printf ("ERROR -> partition %s does not exists\n", devname);
275 } else
276 mount_display ();
278 return 1;
281 unsigned command_umount (char *command, unsigned len)
283 char mountpoint[32];
284 strcpy (mountpoint, argparse (command));
286 unsigned y = strlen (mountpoint);
287 unsigned x = 0;
289 if (mountpoint[y-1] != '/') {
290 mountpoint[y] = '/';
291 mountpoint[y+1] = '\0';
294 if (y) {
295 partition_t *partition;
296 for (partition = partition_list.next; partition != &partition_list; partition = partition->next) {
297 if (umount (partition, mountpoint))
298 x ++;
301 if (!x)
302 printf ("ERROR -> directory %s is not mounted\n", mountpoint);
304 if (x > 1)
305 printf ("WARNING -> multiple (%d) umount of %s\n", x, mountpoint);
306 } else
307 return 0;
309 return 1;
312 unsigned command_env (char *command, unsigned len)
314 env_display ();
316 return 1;
319 unsigned command_cd (char *command, unsigned len)
321 strcpy (test, argparse (command));
323 cd (test);
325 return 1;
328 unsigned command_ls (char *command, unsigned len)
330 strcpy (test, argparse (command));
332 ls (test);
334 return 1;
337 unsigned command_cat (char *command, unsigned len)
339 strcpy (test, argparse (command));
341 cat (test);
343 return 1;
346 unsigned command_rm (char *command, unsigned len)
348 strcpy (test, argparse (command));
350 rm (test);
352 return 1;
355 unsigned command_mkdir (char *command, unsigned len)
357 strcpy (test, argparse (command));
359 mkdir (test);
361 return 1;
364 unsigned command_touch (char *command, unsigned len)
366 strcpy (test, argparse (command));
368 touch (test);
370 return 1;
373 unsigned command_exec (char *command, unsigned len)
375 if (!strncmp ("./", command, 2))
376 strcpy (test, command+2);
377 else
378 strcpy (test, argparse (command));
380 unsigned arg_len = strlen (argparse (test));
381 char arg[arg_len+1];
382 strcpy (arg, argparse (test));
383 arg[arg_len] = '\0';
385 unsigned test_len = strlen (test);
387 /* lock current tty keyboard */
388 tty_lock (currtty);
390 /* if there is argument after name, rewrite space character to zero */
391 if (test [test_len-(arg_len+1)] == ' ')
392 test [test_len-(arg_len+1)] = '\0';
393 else
394 test [test_len-arg_len] = '\0';
396 /* read file data from filesystem */
397 int ret = vfs_read (test, strlen (test));
399 if (ret < 0) {
400 printf ("%s: command not found\n", test);
401 DPRINT ("ERROR -> vfs_read () - '%s'\n", test);
402 tty_unlock (currtty);
403 return 0;
406 unsigned bin_len = file_cache_id;
408 unsigned char *bin = (unsigned char *) swmalloc (bin_len);
410 if (!bin) {
411 printf ("ERROR -> out of memory\n");
412 return 0;
415 /* copy image to page aligned memory */
416 memcpy (bin, file_cache, bin_len);
418 bin[file_cache_id] = '\0';
420 unsigned entry, code, data, data_off, bss;
421 int err = exec_elf (bin, &entry, &data, &data_off, &bss);
423 if (err != NULL) {
424 printf ("ERROR -> invalid ELF exec\n");
425 tty_unlock (currtty);
426 return 0;
429 /* create process */
430 proc_t *proc = proc_create (currtty, test, entry);
432 /* check for & character as app parameter */
433 unsigned d = 0;
434 while (d < arg_len) {
435 if (arg[d] == '&') {
436 if (proc_flag_set (proc, PROC_FLAG_DAEMON))
437 printf ("%s: started as daemon\n", test);
439 arg[d] = '\0';
441 if (arg_len > 2 && arg[d-1] == ' ') {
442 arg[d-1] = '\0';
443 arg_len --;
446 arg_len --;
448 break;
450 d ++;
453 if (!proc) {
454 printf ("ERROR -> Invalid process: %s\n", test);
456 tty_unlock (currtty);
458 /* free image of elf-bss section */
459 //flush_elf (bss);
461 /* free program image */
462 //pfree (bin);
463 return 0;
466 /* save process information to structure for later use */
467 proc->start = (unsigned) bin;
468 proc->code = entry;
469 proc->data = data;
470 proc->data_off = data_off;
471 proc->bss = bss;
472 proc->end = (unsigned) (bin + bin_len);
474 file_cache_id = 0;
476 /* well, set argument for out app */
477 proc_arg_set (proc, arg, arg_len);
479 proc_vmem_map (proc);
481 /* Is this process started as daemon ? */
482 /* wait here, until pid != 0*/
483 if (!(proc->flags & PROC_FLAG_DAEMON))
484 while (proc->pid)
485 schedule ();
487 /* enable interrupts */
488 int_enable ();
490 /* unlock tty console - user can write in */
491 tty_unlock (currtty);
493 _curr_task = proc->tty->task; // this is pretty needed for correct return to our tty task
495 if (!(proc->flags & PROC_FLAG_DAEMON)) {
496 if (!proc_done (proc))
497 while (1) // NOTE: heh, this is good stuff :P
498 schedule ();
500 /* free image of elf-bss section */
501 //flush_elf (bss);
503 /* free program image */
504 swfree (bin, bin_len);
507 /* switch to next task */
508 schedule ();
510 return 1;
513 unsigned command_lsdev (char *command, unsigned len)
515 dev_display ();
517 return 1;
520 unsigned command_login (char *command, unsigned len)
522 currtty->user = NULL;
523 currtty->logged = false;
525 settextcolor (7, 0);
526 puts ("login: ");
528 return 1;
531 unsigned command_serialw (char *command, unsigned len)
533 dev_t *dev = dev_find ("/dev/com0");
535 if (dev) {
536 unsigned len = strlen (argparse (command));
537 char data[len+1];
538 memcpy (data, argparse (command), len);
539 data[len] = '\0';
541 dev->handler (DEV_ACT_WRITE, data, len);
543 printf ("serialw: %s\n", data);
546 return 1;
549 unsigned command_serialr (char *command, unsigned len)
551 dev_t *dev = dev_find ("/dev/com0");
553 if (dev) {
554 char data[11];
556 dev->handler (DEV_ACT_READ, data, 1);
558 printf ("serialr: %s\n", data);
561 return 1;
564 unsigned command_fdisk (char *command, unsigned len)
566 fdisk ();
568 return 1;
571 unsigned command_hdcat (char *command, unsigned len)
573 tty_lock (currtty);
575 partition_t *p = partition_find (argparse (command));
577 if (p) {
578 dev_t *dev = (dev_t *) dev_findbypartition (p);
579 int c, d = 0;
580 unsigned char block[512];
582 printf ("dev: %s\n", dev->devname);
584 while (!key_pressed (1)) {
585 if (key_pressed (72) == 1) {
586 printf ("##block: %d\n", d);
587 dev->handler (DEV_ACT_READ, p, block, "", d);
589 for (c = 0; c < 512; c ++)
590 putch ((unsigned)block[c]);
591 d ++;
594 usleep (5);
596 } else
597 printf ("Please specify partition, example: hdcat /dev/hda0\n");
599 tty_unlock (currtty);
601 return 1;
604 unsigned command_free (char *command, unsigned len)
606 util_cmdfree ();
608 return 1;
611 unsigned command_date (char *command, unsigned len)
613 rtc_getcurrtime ();
615 printf ("%02u:%02u:%02u, %u.%u.%u\n", realtime->tm_hour, realtime->tm_min, realtime->tm_sec,
616 realtime->tm_mday, realtime->tm_mon, realtime->tm_year);
618 return 1;
622 Tone Frequency (Hz)
623 C 130.8
624 D 146.8
625 E 164.8
626 F 174.6
627 G 196.0
628 A 220.0
629 H 246.9
631 C 261.6
632 D 293.7
633 E 329.6
634 F 349.2
635 G 392.0
636 A 440.0
637 H 493.9
639 C 523.3
640 D 587.3
641 E 659.3
642 F 698.5
643 G 784.0
644 A 880.0
645 H 987.8
647 C 1046.5
648 D 1174.7
649 E 1318.5
650 F 1396.9
651 G 1568.0
652 A 1760.0
653 H 1975.5
656 void play_tone (dev_t *dev, char tone, char type, char time)
658 unsigned t = 2;
660 switch (type) {
661 case '1':
662 t = 1;
663 break;
664 case '2':
665 t = 2;
666 break;
667 case '3':
668 t = 3;
669 break;
670 case '4':
671 t = 4;
672 break;
676 unsigned tt = 1;
678 printf ("play_tone (.., %c, %d, %d);\n", tone, t, tt);
680 switch (tone) {
681 case 'c':
682 dev->handler (DEV_ACT_PLAY, 131*t);
683 break;
684 case 'd':
685 dev->handler (DEV_ACT_PLAY, 147*t);
686 break;
687 case 'e':
688 dev->handler (DEV_ACT_PLAY, 165*t);
689 break;
690 case 'f':
691 dev->handler (DEV_ACT_PLAY, 175*t);
692 break;
693 case 'g':
694 dev->handler (DEV_ACT_PLAY, 196*t);
695 break;
696 case 'a':
697 dev->handler (DEV_ACT_PLAY, 220*t);
698 break;
699 case 'h':
700 dev->handler (DEV_ACT_PLAY, 247*t);
701 break;
702 case 'C':
703 dev->handler (DEV_ACT_PLAY, 136*t);
704 break;
705 case 'F':
706 dev->handler (DEV_ACT_PLAY, 188*t);
707 break;
710 switch (time) {
711 case '0':
712 timer_wait (2500);
713 break;
714 case '1':
715 timer_wait (1250);
716 break;
717 case '2':
718 timer_wait (625);
719 break;
724 printf ("end: play_tone ();\n");
726 dev->handler (DEV_ACT_PLAY, 0);
729 void play_song (dev_t *dev, char *data)
731 printf ("play_song ();\n");
732 unsigned i = 0, l = strlen (data);
733 unsigned time = 1;
734 while (i != l) {
735 switch (data[i]) {
736 printf ("switch ()\n");
737 case 'p':
739 switch (data[i+1]) {
740 case '0':
741 timer_wait (2500);
742 break;
743 case '1':
744 timer_wait (1250);
745 break;
746 case '2':
747 timer_wait (625);
748 break;
752 i ++;
753 break;
754 case ' ':
755 break;
756 default:
757 play_tone (dev, data[i], data[i+1], data[i+2]);
758 i += 2;
759 break;
762 i ++;
767 unsigned command_spk (char *command, unsigned len)
769 unsigned int freq = 20;
771 dev_t *dev = dev_find ("/dev/pcspk");
773 if (dev) {
775 We wish you a merry christmas v1.0
777 D2(1/8) G2(1/8) G2(1/16) A2(1/16) G2(1/16) Fis2(1/16) E2(1/8) C2(1/8) E2(1/8) A2(1/8) A2(1/16) H2(1/16) A2(1/16) G2(1/16) Fis2(1/8) D2(1/4) H2(1/8) H2(1/16) C3(1/16) H2(1/16) A2(1/16) G2(1/8) E2(1/8) D2(1/16) D2(1/16) E2(1/8) A2(1/8) Fis2(1/8) G2(1/8)
780 play_song (dev, "d21 g21 g22 a22 g22 F22 e21 c21 e21 a21 a22 h22 a22 g22 F21 d20 h21 h22 c32 h22 a22 g21 e21 d22 d22 e21 a21 F21 g21");
782 timer_wait (2000);
785 We wish you a merry christmas v3.0
787 G2(1/8) C3(1/8) C3(1/16) D3(1/16) C3(1/16) H2(1/16) A2(1/4) D3(1/8) D3(1/16) E3(1/16) D3(1/16) C3(1/16) H2(1/4) G2(1/8) E3(1/8) E3(1/16) F3(1/16) E3(1/16) D3(1/16) C3(1/8) A2(1/8) G2(1/8) A2(1/8) D3(1/8) H2(1/8) C3(1/8)
790 play_song (dev, "g21 c31 c32 d32 c32 h22 a20 d31 d32 e32 d32 c32 h20 g21 e31 e32 f32 e32 d32 c31 a21 g21 a21 d31 h21 c31");
792 timer_wait (2000);
795 Dallas v2.0
796 G2(1/8) C3(1/8) P(1/16) G2(1/16) G3(1/8) C3(1/16) E3(1/8) D3(1/16) E3(1/16) C3(1/8) G2(1/8) C3(1/8) A3(1/8) G3(1/8) E3(1/16) F3(1/16) G3(1/8) G3(1/16) P(1/16) G2(1/8) C3(1/8) A3(1/8) G3(1/8) E3(1/16) F3(1/16) G3(1/8) D3(1/16) E3(1/16) C3(1/8) G2(1/8) C3(1/8) E3(1/16) F3(1/16) D3(1/8) G3(1/8) G3(1/8)
798 /* play_song (dev, "g21 c31 p2 g22 g31 c32 e31 d32 e32 c31 g21 c31 a31 g31 e32 f32 g31 g32 p2 g21 c31 a31 g31 e32 f32 g31 d32 e32 c31 g21 c31 e32 f32 d31 g31 g31");*/
800 //timer_wait (2000);
803 return 1;
806 extern bool bus_pci_acthandler (unsigned act, char *block, unsigned block_len);
807 extern netif_t netif_list;
808 extern void ext2_dump ();
809 void thread_test ()
811 while (1) {
813 kprintf ("hu\n");
815 unsigned long timer_start = timer_ticks + ((unsigned) 1 * 1000);
817 while (timer_start > timer_ticks)
818 schedule ();
822 extern unsigned start;
823 extern unsigned end;
824 extern bool ide_acthandler (unsigned act, partition_t *p, char *block, char *more, int n);
825 unsigned command_test (char *command, unsigned len)
827 //vfs_dirent ();
829 /*partition_t *p = partition_find ("/dev/hda0");
831 if (p)
832 mount (p, "", "/mnt/hdd/");
833 else
834 printf ("WARNING -> partition /dev/hda0 does not exists\n");
836 //char *t = (char *) 0x400000+0x1;
837 //*t = 0x1;
839 //printf ("ddd: 0x%x, 0x%x\n", start, end);
841 /* paging_disable ();
843 task_t *task = task_find (0);
845 if (!task)
846 return 0;
847 char *t = (char *) 0x400000;
848 *t = 0x12;
850 t = (char *) 0x0;
852 *t = 0x3;
854 printf ("Start2: 0x%x\n", *t);
855 unsigned r = page_mmap (task->page_cover, (void *) 0x0, (void *) 0x1000, 1, 0);
857 if (!r) {
858 printf ("Oj Oj\n");
859 paging_enable ();
860 return 0;
863 paging_enable ();*/
867 t = (char *) 0x0;
869 printf ("Start3: 0x%x\n", *t);
871 *t = 0x2;
873 paging_disable ();
875 t = (char *) 0x400000;
877 printf ("Start4: 0x%x\n", *t);
879 paging_enable ();*/
881 /*init_adm ();
883 cd ((char *) "/mnt/floppy");
885 unsigned i = 0;
887 while (++ i < 100) {
888 command_exec ("exec sh", 7);
889 schedule ();
892 cd ("..");
893 cd ("..");*/
895 /* Create virtual block device */
896 #ifdef ARCH_i386
897 dev_t *dev = (dev_t *) dev_register ("vbd", "Virtual Block Device", DEV_ATTR_BLOCK, (dev_handler_t *) &ide_acthandler);
899 partition_t *p = partition_add (dev, fs_supported ("znfs"));
901 znfs_init (partition_add (dev, fs_supported ("znfs")), "192.168.1.2"); // small HACK
903 if (p)
904 mount (p, "", "/mnt/hdd/");
905 else
906 printf ("WARNING -> partition /dev/hda0 does not exists\n");
908 cd ((char *) "/mnt/hdd");
909 #endif
910 //printf ("Je to na 0x%x\n", vesafb);
911 return 1;
914 unsigned command_test2 (char *command, unsigned len)
917 return 1;
920 unsigned command_test3 (char *command, unsigned len)
923 return 1;
926 unsigned command_test4 (char *command, unsigned len)
930 return 1;
934 extern void ps2mouse_get_status (int *x, int *y, int *state);
935 extern unsigned ps2mouse_install ();
936 unsigned command_mouse (char *command, unsigned len)
938 printf ("PS/2 Mouse test\n");
940 ps2mouse_install ();
942 int x, y, state;
943 int x2, y2, state2;
945 while (1) {
947 ps2mouse_get_status (&x, &y, &state);
949 if (x != x2 && y != y2)
950 printf ("mys: %d %d %d\n", x, y, state);
952 x2 = x;
953 y2 = y;
954 state2 = state;
956 schedule ();
959 return 1;
962 unsigned command_vesa (char *command, unsigned len)
964 if (!init_video_vesa ())
965 printf ("vesa -> failed\n");
967 return 1;
970 unsigned command_kill (char *command, unsigned len)
972 strcpy (test, argparse (currtty->shell));
974 pid_t pid = (pid_t) atoi (test);
976 proc_t *proc = proc_findbypid (pid);
978 if (!proc) {
979 printf ("kill: (%s) - No such process\n", test);
980 return 0;
983 /* send SIGTERM to selected process */
984 if (!proc_signal (proc, SIGTERM))
985 return 0;
987 /* check for daemon */
988 if (proc->flags & PROC_FLAG_DAEMON)
989 if (!proc_done (proc))
990 return 0;
992 return 1;
995 unsigned command_modprobe (char *command, unsigned len)
997 unsigned arg_len = strlen (argparse (currtty->shell));
998 char arg[arg_len+1];
999 strcpy (arg, argparse (currtty->shell));
1000 arg[arg_len] = '\0';
1002 module_load (arg);
1004 return 1;
1007 unsigned command_lsmod (char *command, unsigned len)
1009 module_display ();
1011 return 1;
1014 #ifdef CONFIG_DRV_PCI
1015 unsigned command_lspci (char *command, unsigned len)
1017 #ifdef ARCH_i386
1018 pcidev_display ();
1019 #endif
1020 return 1;
1022 #endif
1024 unsigned command_iflist (char *command, unsigned len)
1026 iflist_display ();
1028 return 1;
1031 unsigned command_ifconfig (char *command, unsigned len)
1033 strcpy (test, argparse (command));
1034 char ifid[20];
1035 char ip[32];
1037 unsigned l = strlen (test);
1038 unsigned x = 0;
1039 while (x < l) {
1040 if (test[x] == ' ')
1041 break;
1042 x ++;
1045 memcpy (ifid, test, x);
1046 ifid[x] = '\0';
1048 strcpy (ip, argparse (test));
1049 unsigned y = strlen (ip);
1051 netif_t *netif = netif_findbyname (ifid);
1053 if (!netif) {
1054 printf ("ifconfig -> bad network interface name, example: eth0\n");
1055 return 0;
1058 net_ipv4 ipv4;
1059 net_ipv6 ipv6;
1060 if (ipv4 = net_proto_ip_convert (ip)) {
1061 netif_ip_addr (netif, ipv4);
1063 printf ("%s: IPv4 ", ifid);
1064 net_proto_ip_print (ipv4);
1065 printf (" - OK\n");
1066 } else if (net_proto_ipv6_convert (ipv6, ip)) {
1067 netif_ipv6_addr (netif, ipv6);
1069 printf ("%s: IPv6 ", ifid);
1070 net_proto_ipv6_print (ipv6);
1071 printf (" - OK\n");
1072 } else {
1073 printf ("ifconfig -> bad ip address format, example:\n\t\t192.168.1.1 for IPv4\n\t\tfc00:0:0:0:0:0:0:10 for IPv6\n");
1074 return 0;
1077 return 1;
1080 unsigned command_ifroute (char *command, unsigned len)
1082 strcpy (test, argparse (command));
1083 char ifid[20];
1084 char ip[32];
1086 unsigned l = strlen (test);
1087 unsigned x = 0;
1088 while (x < l) {
1089 if (test[x] == ' ')
1090 break;
1091 x ++;
1094 memcpy (ifid, test, x);
1095 ifid[x] = '\0';
1097 strcpy (ip, argparse (test));
1098 unsigned y = strlen (ip);
1100 netif_t *netif = netif_findbyname (ifid);
1102 if (!netif) {
1103 printf ("ifroute -> bad network interface name, example: eth0\n");
1104 return 0;
1107 unsigned char a;
1108 unsigned char b;
1109 unsigned char c;
1110 unsigned char d;
1112 unsigned g = 0;
1113 unsigned i = 0;
1115 unsigned h[4];
1117 while (i < y) {
1118 if (ip[i] == '.') {
1119 ip[i] = '\0';
1120 h[g] = i+1;
1121 g ++;
1124 i ++;
1127 if (g != 3) {
1128 printf ("ifroute -> bad ip address format, example: 192.168.1.254\n");
1129 return 0;
1132 a = atoi (ip);
1133 b = atoi (ip+h[0]);
1134 c = atoi (ip+h[1]);
1135 d = atoi (ip+h[2]);
1137 printf ("%s->gw: %d.%d.%d.%d - OK\n", ifid, a, b, c, d);
1139 return netif_gw_addr (netif, NET_IPV4_TO_ADDR (a, b, c, d));
1142 unsigned command_dnsconfig (char *command, unsigned len)
1144 strcpy (test, argparse (currtty->shell));
1146 if (!test)
1147 return 0;
1149 unsigned l = strlen (test);
1151 if (!l) {
1152 printf ("dnsconfig -> your domain name server is: ");
1153 net_proto_ip_print (dns_addr_get ());
1154 printf ("\n");
1156 return 0;
1159 printf ("dnsconfig: %s - OK\n", test);
1161 net_ipv4 dns = net_proto_ip_convert (test);
1163 if (!dns)
1164 return 0;
1166 dns_addr (dns);
1168 return 1;
1171 unsigned command_tunconfig (char *command, unsigned len)
1173 strcpy (test, argparse (currtty->shell));
1175 if (!test)
1176 return 0;
1178 unsigned l = strlen (test);
1180 if (!l) {
1181 printf ("tunconfig -> wrong syntax !\ntunconfig <ipv4tunnel> for enable or tunconfig 0 for disable\n");
1183 return 0;
1186 /* you can disable this service over character '0' as parameter */
1187 if (l == 1 && test[0] == '0') {
1188 tun6_addr (0);
1190 printf ("tunconfig: disabled - OK\n");
1192 return 1;
1195 /* classical ipv4 address from tunnel server */
1196 net_ipv4 tunnel = net_proto_ip_convert (test);
1198 if (!tunnel) {
1199 printf ("tunconfig -> wrong syntax !\nExample: tunconfig 216.66.80.30\n");
1201 return 0;
1204 tun6_addr (tunnel);
1206 printf ("tunconfig: ::%s - OK\n", test);
1208 return 1;
1211 unsigned command_kbdmap (char *command, unsigned len)
1213 strcpy (test, argparse (currtty->shell));
1215 if (!test)
1216 return 0;
1218 unsigned ret = keyboard_setlayout (test);
1220 if (ret)
1221 printf ("Keyboard layout was changed to '%s'\n", test);
1223 return ret;
1226 unsigned command_mkzexfs (char *command, unsigned len)
1228 #ifdef ARCH_i386
1229 strcpy (test, argparse (currtty->shell));
1231 if (!test)
1232 return 0;
1234 partition_t *p = partition_find ("/dev/hda0");
1236 mkzexfs (p);
1237 #endif
1238 return 1;
1241 unsigned command_mkext2 (char *command, unsigned len)
1243 #ifdef ARCH_i386
1244 strcpy (test, argparse (currtty->shell));
1246 if (!test)
1247 return 0;
1249 partition_t *p = partition_find ("/dev/hda0");
1251 mkext2 (p);
1252 #endif
1253 return 1;
1256 unsigned command_ping (char *command, unsigned len)
1258 strcpy (test, argparse (currtty->shell));
1260 if (!test)
1261 return 0;
1263 netif_t *netif = netif_findbyname ("eth0");
1265 if (!netif) {
1266 printf ("ping -> network interface does not exists\n");
1267 return 0;
1270 unsigned char a;
1271 unsigned char b;
1272 unsigned char c;
1273 unsigned char d;
1275 unsigned g = 0;
1276 unsigned i = 0;
1277 unsigned y = strlen (test);
1279 if (!y) {
1280 printf ("ping -> wrong syntax, please specify address\n");
1281 return 0;
1284 unsigned h[4];
1286 while (i < y) {
1287 if (test[i] == '.') {
1288 test[i] = '\0';
1289 h[g] = i+1;
1290 g ++;
1293 i ++;
1296 net_ipv4 target = 0;
1298 if (g != 3) {
1299 strcpy (test, argparse (currtty->shell));
1300 target = dns_cache_get (test);
1302 if (!target)
1303 target = dns_send_request (test);
1305 if (!target) {
1306 printf ("ping -> bad hostname or ip address format, example: 192.168.1.1\n");
1307 return 0;
1309 } else {
1310 a = atoi (test);
1311 b = atoi (test+h[0]);
1312 c = atoi (test+h[1]);
1313 d = atoi (test+h[2]);
1315 target = NET_IPV4_TO_ADDR (a, b, c, d);
1317 strcpy (test, argparse (currtty->shell));
1320 char address[20];
1321 net_proto_ip_convert2 (target, address);
1323 i = 0;
1325 while (i < 8) {
1326 unsigned long time_a = timer_ticks;
1327 unsigned ret = net_proto_icmp_ping (netif, target);
1328 if (ret) {
1329 printf ("ping -> %s (%s) - %ums\n", test, address, (timer_ticks - time_a));
1330 } else {
1331 printf ("ping -> Host %s is unreachable\n", test);
1332 break;
1335 i ++;
1338 return 1;
1341 unsigned command_ping6 (char *command, unsigned len)
1343 strcpy (test, argparse (currtty->shell));
1345 if (!test)
1346 return 0;
1348 netif_t *netif = netif_findbyname ("eth0");
1350 if (!netif) {
1351 printf ("ping -> network interface does not exists\n");
1352 return 0;
1355 unsigned short a;
1356 unsigned short b;
1357 unsigned short c;
1358 unsigned short d;
1359 unsigned short e;
1360 unsigned short f;
1361 unsigned short g;
1362 unsigned short h;
1364 unsigned j = 0;
1365 unsigned i = 0;
1366 unsigned y = strlen (test);
1368 if (!y) {
1369 printf ("ping -> wrong syntax, please specify ipv6 address\n");
1370 return 0;
1373 unsigned k[8];
1375 while (i < y) {
1376 if (test[i] == ':') {
1377 test[i] = '\0';
1378 k[j] = i+1;
1379 j ++;
1382 i ++;
1385 net_ipv6 target;
1387 if (j != 7) {
1388 /*strcpy (test, argparse (currtty->shell));
1389 target = dns_cache_get (test);
1391 if (!target)
1392 target = dns_send_request (test);
1394 if (!target) {*/
1395 // printf ("ping -> bad hostname or ip address format, example: 192.168.1.1\n");
1396 // return 0;
1398 printf ("ping -> wrong syntax, please specify ipv6 address\n");
1399 return 0;
1400 } else {
1401 char *endptr;
1403 a = strtol (test, &endptr, 16);
1404 b = strtol (test+k[0], &endptr, 16);
1405 c = strtol (test+k[1], &endptr, 16);
1406 d = strtol (test+k[2], &endptr, 16);
1407 e = strtol (test+k[3], &endptr, 16);
1408 f = strtol (test+k[4], &endptr, 16);
1409 g = strtol (test+k[5], &endptr, 16);
1410 h = strtol (test+k[6], &endptr, 16);
1412 NET_IPV6_TO_ADDR (target, a, b, c, d, e, f, g, h);
1414 //printf ("ipv6: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", a, b, c, d, e, f, g, h);
1416 strcpy (test, argparse (currtty->shell));
1419 char address[40];
1420 //net_proto_ipv6_convert2 (target, address);
1422 i = 0;
1424 while (i < 8) {
1425 unsigned long time_a = timer_ticks;
1426 unsigned ret = net_proto_icmp6_ping (netif, target);
1427 if (ret) {
1428 printf ("ping6 -> %s (%s) - %ums\n", test, test, (timer_ticks - time_a));
1429 } else {
1430 printf ("ping6 -> Host %s is unreachable\n", test);
1431 break;
1434 i ++;
1437 return 1;
1440 unsigned command_netexec (char *command, unsigned len)
1442 strcpy (test, argparse (command));
1444 if (!test)
1445 return 0;
1447 if (!strlen (test)) {
1448 printf ("Syntax:\nnetexec <ip_of_tftp> <filename> [parameters]\n");
1449 return 0;
1452 unsigned arg_len = strlen (argparse (test));
1453 char arg[arg_len+1];
1454 strcpy (arg, argparse (test));
1455 arg[arg_len] = '\0';
1457 unsigned test_len = strlen (test);
1458 test [test_len-arg_len] = '\0';
1460 if (test[test_len-arg_len-1] == ' ') {
1461 test[test_len-arg_len-1] = '\0';
1462 test_len --;
1465 char file[arg_len+1];
1466 unsigned file_len = 0;
1467 memcpy (file, arg, arg_len);
1468 while (file_len < arg_len) {
1469 if (file[file_len] == ' ') {
1470 file[file_len] = '\0';
1471 break;
1473 file_len ++;
1476 if (file[arg_len] != '\0')
1477 file[arg_len] = '\0';
1479 unsigned l = file_len;
1481 unsigned ret = tftp_client_connect (test, 69, file, &l);
1483 if (!ret) {
1484 printf ("tftp -> something go wrong !\n");
1485 return 0;
1488 printf ("tftp -> file length: %ubytes\t\t[OK]\n", l);
1490 char *bin = (unsigned char *) pmalloc (sizeof (char) * (l+1));
1492 if (!bin)
1493 return 0;
1495 int ret2 = tftp_client_read (ret, bin, l);
1497 if (!ret2) {
1498 printf ("tftp -> tftp_client_read () error\n");
1499 free (bin);
1500 return 0;
1503 memcpy (file_cache, bin, l);
1505 unsigned entry, code, data, data_off, bss;
1506 int err = exec_elf (bin, &entry, &data, &data_off, &bss);
1508 if (err != NULL) {
1509 printf ("ERROR -> invalid ELF exec\n");
1510 return 0;
1513 tty_lock (currtty);
1514 timer_wait (1);
1515 /* create process */
1516 proc_t *proc = proc_create (currtty, "netexec", entry);
1517 timer_wait (1);
1520 /* check for & character as app parameter */
1521 /* unsigned d = 0;
1522 while (d < arg_len) {
1523 if (arg[d] == '&') {
1524 if (proc_flag_set (proc, PROC_FLAG_DAEMON))
1525 printf ("%s: started as daemon\n", test);
1527 arg[d] = '\0';
1529 if (arg_len > 2 && arg[d-1] == ' ') {
1530 arg[d-1] = '\0';
1531 arg_len --;
1534 arg_len --;
1536 break;
1538 d ++;
1541 if (!proc) {
1542 printf ("ERROR -> Invalid process: %s\n", test);
1543 return 0;
1546 timer_wait (1);
1548 /* save process information to structure for later use */
1549 proc->start = (unsigned) bin;
1550 proc->code = entry;
1551 proc->data = data;
1552 proc->data_off = data_off;
1553 proc->bss = bss;
1554 proc->end = (unsigned) (bin + l);
1556 timer_wait (1);
1558 /* well, set argument for out app */
1559 proc_arg_set (proc, arg+file_len+1, arg_len-file_len-1);
1561 timer_wait (1);
1563 /* Is this process started as daemon ? */
1564 /* wait here, until pid != 0*/
1565 if (!(proc->flags & PROC_FLAG_DAEMON))
1566 while (proc->pid)
1567 schedule ();
1569 timer_wait (1);
1571 /* enable interrupts */
1572 int_enable ();
1574 /* unlock tty console - user can write in */
1575 tty_unlock (proc->tty);
1577 _curr_task = proc->tty->task; // this is pretty needed for correct return to our tty task
1579 if (!(proc->flags & PROC_FLAG_DAEMON)) {
1580 if (!proc_done (proc))
1581 while (1) // NOTE: heh, this is good stuff :P
1582 schedule ();
1584 /* free image of app */
1585 //flush_elf ();
1586 //kfree (bin);
1589 /* switch to next task */
1590 schedule ();
1592 sclose (ret);
1594 return 1;
1597 unsigned command_netcp (char *command, unsigned len)
1599 strcpy (test, argparse (command));
1601 if (!test)
1602 return 0;
1604 if (!strlen (test)) {
1605 printf ("Syntax:\nnetcp <ip_of_tftp> <tftp_file> <output_file>\n");
1606 return 0;
1609 unsigned arg_len = strlen (argparse (test));
1610 char arg[arg_len+1];
1611 strcpy (arg, argparse (test));
1612 arg[arg_len] = '\0';
1614 unsigned test_len = strlen (test);
1615 test [test_len-arg_len] = '\0';
1617 if (test[test_len-arg_len-1] == ' ') {
1618 test[test_len-arg_len-1] = '\0';
1619 test_len --;
1622 char file[arg_len+1];
1623 unsigned file_len = 0;
1624 memcpy (file, arg, arg_len);
1625 while (file_len < arg_len) {
1626 if (file[file_len] == ' ') {
1627 file[file_len] = '\0';
1628 break;
1630 file_len ++;
1633 if (file[arg_len] != '\0')
1634 file[arg_len] = '\0';
1636 unsigned l = file_len;
1638 unsigned ret = tftp_client_connect (test, 69, file, &l);
1640 if (!ret) {
1641 printf ("tftp -> something go wrong !\n");
1642 return 0;
1645 printf ("tftp -> file length: %ubytes\t\t[OK]\n", l);
1646 printf ("DDDDDDDD: '%s' :: '%s' :: '%s'\n", test, file, arg);
1647 char *bin = (unsigned char *) malloc (sizeof (char) * (l+1));
1649 if (!bin)
1650 return 0;
1652 int ret2 = tftp_client_read (ret, bin, l);
1654 if (!ret2) {
1655 printf ("tftp -> tftp_client_read () error\n");
1656 free (bin);
1657 return 0;
1660 sclose (ret);
1662 file_cache_id = 0;
1663 file_cache = bin;
1665 char *output = argparse (arg);
1667 if (!output) {
1668 free (bin);
1669 printf ("ERROR -> output file name is empty\n");
1670 return 0;
1673 int fd = open (output, O_WRONLY | O_CREAT);
1675 if (!fd) {
1676 free (bin);
1677 printf ("ERROR -> something go wrong with %s\n", output);
1678 return 0;
1681 ret = write (fd, bin, l);
1683 if (!ret) {
1684 free (bin);
1685 printf ("ERROR -> File '%s' could'nt be writed\n", output);
1688 file_cache = (unsigned char *) 0x350000;
1690 return 1;
1693 void task_savemode ()
1695 while (1) {
1696 /* disable cpu for cycle */
1697 arch_cpu_hlt ();
1698 schedule ();
1702 unsigned command_savemode (char *command, unsigned len)
1704 task_t *task = (task_t *) task_create ("savemode", (unsigned) &task_savemode, 16);
1706 if (!task) {
1707 printf ("ERROR -> Save mode thread was'nt created\n");
1708 return 0;
1711 printf ("Save mode was succefully started\n");
1713 return 1;
1716 unsigned command_cpuinfo (char *command, unsigned len)
1718 printf ("Processor info:\n");
1720 cat ("/proc/cpuinfo");
1722 return 1;
1725 unsigned command_adm (char *command, unsigned len)
1727 printf ("Automatic Device Mounter - init ()\n");
1729 init_adm ();
1731 return 1;
1734 /*************************************************************\
1735 | COMMAND's UTILS |
1736 \*************************************************************/
1738 unsigned command_parser (char *command, unsigned len)
1740 /* find first non-space in command */
1741 int i = 0;
1742 for (i = 0; i < len; i ++) {
1743 if (command[i] != ' ')
1744 break;
1746 command_t *ctx;
1748 /* try to find the command */
1749 for (ctx = command_list.next; ctx != &command_list; ctx = ctx->next) {
1750 if (!cstrcmp (ctx->name, command+i)) {
1751 ctx->handler (command+i, len-i);
1752 return 1;
1756 printf ("%s: command not found\n", command);
1758 return 0;
1761 void commands (int i)
1763 // currtty->shell_len has been set to zero already
1764 command_parser (currtty->shell, strlen(currtty->shell));
1767 unsigned command_register (char *name, char *desc, command_handler_t *handler, unsigned flags)
1769 command_t *c;
1770 /* we dont want commands with same name */
1771 for (c = command_list.next; c != &command_list; c = c->next)
1772 if (!strcmp(c->name, name))
1773 return 0;
1775 command_t *ctx;
1777 // alloc and init context
1778 ctx = (command_t *) kmalloc (sizeof (command_t));
1780 if (!ctx)
1781 return 0;
1783 unsigned name_len = strlen (name);
1784 ctx->name = (char *) kmalloc (sizeof (char) * name_len +1);
1786 if (!ctx->name)
1787 return 0;
1789 memcpy (ctx->name, name, name_len);
1790 ctx->name[name_len] = '\0';
1792 unsigned desc_len = strlen (desc);
1793 ctx->desc = (char *) kmalloc (sizeof (char) * desc_len +1);
1795 if (!ctx->desc)
1796 return 0;
1798 memcpy (ctx->desc, desc, desc_len);
1799 ctx->desc[desc_len] = '\0';
1801 ctx->handler = handler;
1802 ctx->flags = flags;
1804 ctx->next = &command_list;
1805 ctx->prev = command_list.prev;
1806 ctx->prev->next = ctx;
1807 ctx->next->prev = ctx;
1809 return 1;
1812 unsigned command_unregister (char *name)
1814 command_t *ctx;
1816 for (ctx = command_list.next; ctx != &command_list; ctx = ctx->next) {
1817 if (!strcmp(ctx->name, name)) {
1818 ctx->next->prev = ctx->prev;
1819 ctx->prev->next = ctx->next;
1821 return 1;
1825 return 0;
1828 /*************************************************************\
1829 | INITIALIZATION OF COMMANDS |
1830 \*************************************************************/
1832 unsigned int init_commands ()
1834 command_list.next = &command_list;
1835 command_list.prev = &command_list;
1837 // reg commands
1838 command_register ("help", "Displays list of available commands", &command_help, 0);
1839 command_register ("hdd", "Detect HDD", &command_hdd, 0);
1840 command_register ("reboot", "Reboot computer", &command_reboot, 0);
1841 command_register ("halt", "Shutdown computer", &command_halt, 0);
1842 command_register ("tasks", "Print all tasks", &command_tasks, 0);
1843 command_register ("ps", "Print all process", &command_ps, 0);
1844 command_register ("uptime", "Print uptime in seconds", &command_uptime, 0);
1845 command_register ("version", "Displays a version of system", &command_version, 0);
1846 command_register ("debug", "Change to developer mode", &command_debug, 0);
1847 command_register ("mount", "Mount device to selected directory", &command_mount, 0);
1848 command_register ("umount", "Unmount mounted directory", &command_umount, 0);
1849 command_register ("env", "Displays all env variables", &command_env, 0);
1850 command_register ("cd", "Change directory", &command_cd, 0);
1851 command_register ("ls", " Displays files in current directory", &command_ls, 0);
1852 command_register ("cat", "Displays text in selected file", &command_cat, 0);
1853 command_register ("rm", "Remove a file", &command_rm, 0);
1854 command_register ("mkdir", "Create a directory", &command_mkdir, 0);
1855 command_register ("touch", "Create a file", &command_touch, 0);
1856 command_register ("exec", "Execute a selected program", &command_exec, 0);
1857 command_register ("lsdev", "Displays found devices", &command_lsdev, 0);
1858 command_register ("login", "Login as another user", &command_login, 0);
1859 command_register ("fdisk", "Partition table manipulator", &command_fdisk, 0);
1860 command_register ("hdcat", "Read selected block of data from drive", &command_hdcat, 0);
1861 command_register ("free", "Display amount of free and used memory", &command_free, 0);
1862 command_register ("date", "Show current date and time", &command_date, 0);
1863 //command_register ("xmastime", "play noel on pc-speaker", &command_spk, 0);
1864 command_register ("test", "Some test", &command_test, 0);
1865 //command_register ("testb", "Some test", &command_test2, 0);
1866 //command_register ("testc", "Some test", &command_test3, 0);
1867 //command_register ("testd", "Some test", &command_test4, 0);
1868 //command_register ("vesa", "Some test", &command_vesa, 0);
1869 command_register ("kill", "Send a signal to process", &command_kill, 0);
1870 command_register ("modprobe", "program to add modules from the kernel", &command_modprobe, 0);
1871 command_register ("lsmod", "program to show the status of modules", &command_lsmod, 0);
1872 #ifdef CONFIG_DRV_PCI
1873 command_register ("lspci", "list all pci devices", &command_lspci, 0);
1874 #endif
1875 //command_register ("mouse", "ps2 mouse test", &command_mouse, 0);
1876 command_register ("iflist", "Show network interface", &command_iflist, 0);
1877 command_register ("ifconfig", "Configure network interface", &command_ifconfig, 0);
1878 command_register ("ifroute", "Configure gateway address", &command_ifroute, 0);
1879 command_register ("dnsconfig", "Configure domain name server address", &command_dnsconfig, 0);
1880 #ifdef CONFIG_PROTO_TUN6
1881 command_register ("tunconfig", "Configure IPv6 tunnel server address", &command_tunconfig, 0);
1882 #endif
1883 command_register ("kbdmap", "Change keyboard layout", &command_kbdmap, 0);
1884 #ifdef CONFIG_DRV_ZEXFS
1885 command_register ("mkzexfs", "Create zexfs filesystem on hdd", &command_mkzexfs, 0);
1886 #endif
1887 #ifdef CONFIG_DRV_EXT2
1888 command_register ("mkext2", "Create ext2 filesystem on hdd", &command_mkext2, 0);
1889 #endif
1890 #ifdef CONFIG_PROTO_IPV4
1891 command_register ("ping", "Send ICMP echo request", &command_ping, 0);
1892 #endif
1893 #ifdef CONFIG_PROTO_IPV6
1894 command_register ("ping6", "Send ICMPv6 echo request", &command_ping6, 0);
1895 #endif
1896 command_register ("netexec", "Execute file from network", &command_netexec, 0);
1897 command_register ("netcp", "Copy file from network to filesystem", &command_netcp, 0);
1898 command_register ("savemode", "Make less cpu load", &command_savemode, 0);
1899 command_register ("cpuinfo", "Show CPU info", &command_cpuinfo, 0);
1901 command_register ("adm", "Automatic Device Mounter", &command_adm, 0);
1903 return 1;