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 */
27 #include "time_support.h"
29 #ifdef HAVE_ARPA_INET_H
30 #include <arpa/inet.h>
41 //#ifdef HAVE_NETINET_TCP_H
42 //#include <netinet/tcp.h>
44 #ifdef HAVE_SYS_IOCTL_H
45 #include <sys/ioctl.h>
47 #ifdef HAVE_SYS_STAT_H
58 //#ifdef HAVE_STRINGS_H
59 //#include <strings.h>
63 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
64 char **args
, int argc
)
68 command_print(cmd_ctx
, "rm <filename>");
69 return ERROR_INVALID_ARGUMENTS
;
72 if (unlink(args
[0]) != 0)
74 command_print(cmd_ctx
, "failed: %d", errno
);
81 /* loads a file and returns a pointer to it in memory. The file contains
82 * a 0 byte(sentinel) after len bytes - the length of the file. */
83 int loadFile(const char *fileName
, void **data
, size_t *len
)
85 // ensure returned length is always sane
89 pFile
= fopen(fileName
,"rb");
92 LOG_ERROR("Can't open %s\n", fileName
);
95 if (fseek(pFile
, 0, SEEK_END
)!=0)
97 LOG_ERROR("Can't open %s\n", fileName
);
101 long fsize
= ftell(pFile
);
104 LOG_ERROR("Can't open %s\n", fileName
);
110 if (fseek(pFile
, 0, SEEK_SET
)!=0)
112 LOG_ERROR("Can't open %s\n", fileName
);
116 *data
= malloc(*len
+ 1);
119 LOG_ERROR("Can't open %s\n", fileName
);
124 if (fread(*data
, 1, *len
, pFile
)!=*len
)
128 LOG_ERROR("Can't open %s\n", fileName
);
133 // 0-byte after buffer (not included in *len) serves as a sentinel
134 char *buf
= (char *)*data
;
142 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
143 char **args
, int argc
)
147 command_print(cmd_ctx
, "cat <filename>");
148 return ERROR_INVALID_ARGUMENTS
;
151 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
155 int retval
= loadFile(args
[0], &data
, &len
);
156 if (retval
== ERROR_OK
)
158 command_print(cmd_ctx
, "%s", data
);
163 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
168 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
169 char **args
, int argc
)
173 command_print(cmd_ctx
, "trunc <filename>");
174 return ERROR_INVALID_ARGUMENTS
;
177 FILE *config_file
= NULL
;
178 config_file
= fopen(args
[0], "w");
179 if (config_file
!= NULL
)
186 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
189 struct mallinfo info
;
193 command_print(cmd_ctx
, "meminfo");
194 return ERROR_INVALID_ARGUMENTS
;
201 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
203 prev
= info
.fordblks
;
205 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
211 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
212 char **args
, int argc
)
216 command_print(cmd_ctx
,
217 "append <filename> [<string1>, [<string2>, ...]]");
218 return ERROR_INVALID_ARGUMENTS
;
221 FILE *config_file
= NULL
;
222 config_file
= fopen(args
[0], "a");
223 if (config_file
!= NULL
)
226 fseek(config_file
, 0, SEEK_END
);
228 for (i
= 1; i
< argc
; i
++)
230 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
233 fwrite(" ", 1, 1, config_file
);
236 fwrite("\n", 1, 1, config_file
);
245 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
249 return ERROR_INVALID_ARGUMENTS
;
252 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
256 int retval
= loadFile(args
[0], &data
, &len
);
257 if (retval
!= ERROR_OK
)
260 FILE *f
= fopen(args
[1], "wb");
262 retval
= ERROR_INVALID_ARGUMENTS
;
267 size_t chunk
= len
- pos
;
268 static const size_t maxChunk
= 512 * 1024; // ~1/sec
269 if (chunk
> maxChunk
)
274 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
275 retval
= ERROR_INVALID_ARGUMENTS
;
277 if (retval
!= ERROR_OK
)
282 command_print(cmd_ctx
, "%d", len
- pos
);
290 if (retval
== ERROR_OK
)
292 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
295 command_print(cmd_ctx
, "Failed: %d", retval
);
303 if (retval
!= ERROR_OK
)
312 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
315 void copyfile(char *name2
, char *name1
)
323 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
325 SHOW_RESULT( open
, fd1
);
327 fd2
= open(name2
, O_RDONLY
);
329 SHOW_RESULT( open
, fd2
);
333 done
= read(fd2
, buf
, IOSIZE
);
336 SHOW_RESULT( read
, done
);
340 if( done
== 0 ) break;
342 wrote
= write(fd1
, buf
, done
);
343 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
345 if( wrote
!= done
) break;
349 if( err
< 0 ) SHOW_RESULT( close
, err
);
352 if( err
< 0 ) SHOW_RESULT( close
, err
);
356 /* utility fn to copy a directory */
357 void copydir(char *name
, char *destdir
)
362 dirp
= opendir(destdir
);
365 mkdir(destdir
, 0777);
368 err
= closedir(dirp
);
371 dirp
= opendir(name
);
372 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
376 struct dirent
*entry
= readdir(dirp
);
381 if (strcmp(entry
->d_name
, ".") == 0)
383 if (strcmp(entry
->d_name
, "..") == 0)
388 char fullPath
[PATH_MAX
];
389 strncpy(fullPath
, name
, PATH_MAX
);
390 strcat(fullPath
, "/");
391 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
393 if (stat(fullPath
, &buf
) == -1)
395 LOG_ERROR("unable to read status from %s", fullPath
);
398 isDir
= S_ISDIR(buf
.st_mode
) != 0;
403 // diag_printf("<INFO>: entry %14s",entry->d_name);
404 char fullname
[PATH_MAX
];
405 char fullname2
[PATH_MAX
];
407 strcpy(fullname
, name
);
408 strcat(fullname
, "/");
409 strcat(fullname
, entry
->d_name
);
411 strcpy(fullname2
, destdir
);
412 strcat(fullname2
, "/");
413 strcat(fullname2
, entry
->d_name
);
414 // diag_printf("from %s to %s\n", fullname, fullname2);
415 copyfile(fullname
, fullname2
);
417 // diag_printf("\n");
420 err
= closedir(dirp
);
421 if( err
< 0 ) SHOW_RESULT( stat
, err
);
428 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
430 Jim_Obj
* const *argv
)
435 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
440 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
442 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
445 return del
? JIM_OK
: JIM_ERR
;
450 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
452 Jim_Obj
* const *argv
)
456 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
460 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
463 dirp
= opendir(name
);
468 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
472 struct dirent
*entry
= NULL
;
473 entry
= readdir(dirp
);
477 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
480 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
484 Jim_SetResult(interp
, objPtr
);
489 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
493 return ERROR_COMMAND_SYNTAX_ERROR
;
495 unsigned long addr
= strtoul(args
[0], NULL
, 0);
496 volatile unsigned *address
= (volatile unsigned *)addr
;
497 unsigned value
= *address
;
498 command_print(cmd_ctx
, "0x%x : 0x%x", address
, value
);
502 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
506 return ERROR_INVALID_ARGUMENTS
;
508 unsigned long addr
= strtoul(args
[0], NULL
, 0);
509 volatile int *address
= (volatile int *)addr
;
510 int value
=strtoul(args
[1], NULL
, 0);
516 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
518 Jim_Obj
* const *argv
)
522 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
527 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
530 int value
= *((volatile int *) address
);
532 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
538 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
540 Jim_Obj
* const *argv
)
544 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
549 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
552 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
555 *((volatile int *) address
) = value
;
561 /* not so pretty code to fish out ip number*/
562 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
563 Jim_Obj
* const *argv
)
565 #if !defined(__CYGWIN__)
566 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
568 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
570 if (getifaddrs(&ifp
) < 0)
575 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
580 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
581 salen
= sizeof(struct sockaddr_in
);
582 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
583 salen
= sizeof(struct sockaddr_in6
);
587 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
593 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
600 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
601 LOG_ERROR("NOT IMPLEMENTED!!!");
603 Jim_SetResult(interp
, tclOutput
);
608 /* not so pretty code to fish out eth0 mac address */
609 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
610 Jim_Obj
* const *argv
)
614 struct ifreq
*ifr
, *ifend
;
620 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
626 ifc
.ifc_len
= sizeof(ifs
);
628 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
634 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
635 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
637 //if (ifr->ifr_addr.sa_family == AF_INET)
639 if (strcmp("eth0", ifr
->ifr_name
)!=0)
641 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
642 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
651 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
654 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
655 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
656 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
657 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
658 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
659 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
660 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
662 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
664 Jim_SetResult(interp
, tclOutput
);
677 int ioutil_init(struct command_context_s
*cmd_ctx
)
679 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
682 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
683 "display file content");
685 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
686 "truncate a file to 0 size");
688 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
689 COMMAND_ANY
, "copy a file <from> <to>");
691 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
692 COMMAND_ANY
, "append a variable number of strings to a file");
694 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
695 COMMAND_ANY
, "display available ram memory");
697 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
699 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
700 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
701 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
703 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
706 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)