1 /***************************************************************************
2 * Copyright (C) 2007-2008 by Øyvind Harboe *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
20 /* this file contains various functionality useful to standalone systems */
28 #include "configuration.h"
33 #include <time_support.h>
35 #include <sys/types.h>
50 #include <netinet/tcp.h>
51 #include <sys/ioctl.h>
52 #include <sys/socket.h>
53 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 #include <sys/types.h>
57 #include <sys/socket.h>
59 #include <netinet/in.h>
61 #include <arpa/inet.h>
65 #if !defined(__CYGWIN__)
72 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
73 char **args
, int argc
)
77 command_print(cmd_ctx
, "rm <filename>");
78 return ERROR_INVALID_ARGUMENTS
;
81 if (unlink(args
[0]) != 0)
83 command_print(cmd_ctx
, "failed: %d", errno
);
90 /* loads a file and returns a pointer to it in memory. The file contains
91 * a 0 byte(sentinel) after len bytes - the length of the file. */
92 int loadFile(const char *fileName
, void **data
, int *len
)
95 pFile
= fopen(fileName
,"rb");
98 LOG_ERROR("Can't open %s\n", fileName
);
101 if (fseek(pFile
, 0, SEEK_END
)!=0)
103 LOG_ERROR("Can't open %s\n", fileName
);
110 LOG_ERROR("Can't open %s\n", fileName
);
115 if (fseek(pFile
, 0, SEEK_SET
)!=0)
117 LOG_ERROR("Can't open %s\n", fileName
);
121 *data
=malloc(*len
+1);
124 LOG_ERROR("Can't open %s\n", fileName
);
129 if (fread(*data
, 1, *len
, pFile
)!=*len
)
133 LOG_ERROR("Can't open %s\n", fileName
);
137 *(((char *)(*data
))+*len
)=0; /* sentinel */
147 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
148 char **args
, int argc
)
152 command_print(cmd_ctx
, "cat <filename>");
153 return ERROR_INVALID_ARGUMENTS
;
156 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
160 int retval
= loadFile(args
[0], &data
, &len
);
161 if (retval
== ERROR_OK
)
163 command_print(cmd_ctx
, "%s", data
);
168 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
173 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
174 char **args
, int argc
)
178 command_print(cmd_ctx
, "trunc <filename>");
179 return ERROR_INVALID_ARGUMENTS
;
182 FILE *config_file
= NULL
;
183 config_file
= fopen(args
[0], "w");
184 if (config_file
!= NULL
)
191 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
194 struct mallinfo info
;
198 command_print(cmd_ctx
, "meminfo");
199 return ERROR_INVALID_ARGUMENTS
;
206 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
208 prev
= info
.fordblks
;
210 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
216 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
217 char **args
, int argc
)
221 command_print(cmd_ctx
,
222 "append <filename> [<string1>, [<string2>, ...]]");
223 return ERROR_INVALID_ARGUMENTS
;
226 FILE *config_file
= NULL
;
227 config_file
= fopen(args
[0], "a");
228 if (config_file
!= NULL
)
231 fseek(config_file
, 0, SEEK_END
);
233 for (i
= 1; i
< argc
; i
++)
235 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
238 fwrite(" ", 1, 1, config_file
);
241 fwrite("\n", 1, 1, config_file
);
250 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
254 return ERROR_INVALID_ARGUMENTS
;
257 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
261 int retval
= loadFile(args
[0], &data
, &len
);
262 if (retval
!= ERROR_OK
)
265 FILE *f
= fopen(args
[1], "wb");
267 retval
= ERROR_INVALID_ARGUMENTS
;
272 int chunk
= len
- pos
;
273 static const int maxChunk
= 512 * 1024; // ~1/sec
274 if (chunk
> maxChunk
)
279 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
280 retval
= ERROR_INVALID_ARGUMENTS
;
282 if (retval
!= ERROR_OK
)
287 command_print(cmd_ctx
, "%d", len
- pos
);
295 if (retval
== ERROR_OK
)
297 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
300 command_print(cmd_ctx
, "Failed: %d", retval
);
308 if (retval
!= ERROR_OK
)
317 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
320 void copyfile(char *name2
, char *name1
)
328 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
330 SHOW_RESULT( open
, fd1
);
332 fd2
= open(name2
, O_RDONLY
);
334 SHOW_RESULT( open
, fd2
);
338 done
= read(fd2
, buf
, IOSIZE
);
341 SHOW_RESULT( read
, done
);
345 if( done
== 0 ) break;
347 wrote
= write(fd1
, buf
, done
);
348 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
350 if( wrote
!= done
) break;
354 if( err
< 0 ) SHOW_RESULT( close
, err
);
357 if( err
< 0 ) SHOW_RESULT( close
, err
);
361 /* utility fn to copy a directory */
362 void copydir(char *name
, char *destdir
)
367 dirp
= opendir(destdir
);
370 mkdir(destdir
, 0777);
373 err
= closedir(dirp
);
376 dirp
= opendir(name
);
377 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
381 struct dirent
*entry
= readdir(dirp
);
386 if (strcmp(entry
->d_name
, ".") == 0)
388 if (strcmp(entry
->d_name
, "..") == 0)
393 char fullPath
[PATH_MAX
];
394 strncpy(fullPath
, name
, PATH_MAX
);
395 strcat(fullPath
, "/");
396 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
398 if (stat(fullPath
, &buf
) == -1)
400 LOG_ERROR("unable to read status from %s", fullPath
);
403 isDir
= S_ISDIR(buf
.st_mode
) != 0;
408 // diag_printf("<INFO>: entry %14s",entry->d_name);
409 char fullname
[PATH_MAX
];
410 char fullname2
[PATH_MAX
];
412 strcpy(fullname
, name
);
413 strcat(fullname
, "/");
414 strcat(fullname
, entry
->d_name
);
416 strcpy(fullname2
, destdir
);
417 strcat(fullname2
, "/");
418 strcat(fullname2
, entry
->d_name
);
419 // diag_printf("from %s to %s\n", fullname, fullname2);
420 copyfile(fullname
, fullname2
);
422 // diag_printf("\n");
425 err
= closedir(dirp
);
426 if( err
< 0 ) SHOW_RESULT( stat
, err
);
433 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
435 Jim_Obj
* const *argv
)
440 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
445 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
447 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
450 return del
? JIM_OK
: JIM_ERR
;
455 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
457 Jim_Obj
* const *argv
)
461 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
465 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
468 dirp
= opendir(name
);
473 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
477 struct dirent
*entry
= NULL
;
478 entry
= readdir(dirp
);
482 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
485 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
489 Jim_SetResult(interp
, objPtr
);
494 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
498 return ERROR_COMMAND_SYNTAX_ERROR
;
500 volatile int *address
=(volatile int *)strtoul(args
[0], NULL
, 0);
502 command_print(cmd_ctx
, "0x%x : 0x%x", address
, value
);
506 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
510 return ERROR_INVALID_ARGUMENTS
;
512 volatile int *address
=(volatile int *)strtoul(args
[0], NULL
, 0);
513 int value
=strtoul(args
[1], NULL
, 0);
519 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
521 Jim_Obj
* const *argv
)
525 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
530 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
533 int value
= *((volatile int *) address
);
535 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
541 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
543 Jim_Obj
* const *argv
)
547 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
552 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
555 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
558 *((volatile int *) address
) = value
;
564 /* not so pretty code to fish out ip number*/
565 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
566 Jim_Obj
* const *argv
)
568 #if !defined(__CYGWIN__)
569 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
571 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
573 if (getifaddrs(&ifp
) < 0)
578 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
583 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
584 salen
= sizeof(struct sockaddr_in
);
585 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
586 salen
= sizeof(struct sockaddr_in6
);
590 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
596 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
603 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
604 LOG_ERROR("NOT IMPLEMENTED!!!");
606 Jim_SetResult(interp
, tclOutput
);
611 /* not so pretty code to fish out eth0 mac address */
612 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
613 Jim_Obj
* const *argv
)
617 struct ifreq
*ifr
, *ifend
;
623 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
629 ifc
.ifc_len
= sizeof(ifs
);
631 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
637 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
638 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
640 //if (ifr->ifr_addr.sa_family == AF_INET)
642 if (strcmp("eth0", ifr
->ifr_name
)!=0)
644 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
645 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
654 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
657 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
658 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
659 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
660 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
661 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
662 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
663 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
665 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
667 Jim_SetResult(interp
, tclOutput
);
680 int ioutil_init(struct command_context_s
*cmd_ctx
)
682 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
685 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
686 "display file content");
688 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
689 "truncate a file to 0 size");
691 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
692 COMMAND_ANY
, "copy a file <from> <to>");
694 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
695 COMMAND_ANY
, "append a variable number of strings to a file");
697 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
698 COMMAND_ANY
, "display available ram memory");
700 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
702 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
703 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
704 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
706 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
709 Jim_CreateCommand(interp
, "ip", zylinjtag_Jim_Command_ip
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)