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
56 //#ifdef HAVE_STRINGS_H
57 //#include <strings.h>
61 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
62 char **args
, int argc
)
66 command_print(cmd_ctx
, "rm <filename>");
67 return ERROR_INVALID_ARGUMENTS
;
70 if (unlink(args
[0]) != 0)
72 command_print(cmd_ctx
, "failed: %d", errno
);
79 /* loads a file and returns a pointer to it in memory. The file contains
80 * a 0 byte(sentinel) after len bytes - the length of the file. */
81 int loadFile(const char *fileName
, void **data
, size_t *len
)
83 // ensure returned length is always sane
87 pFile
= fopen(fileName
,"rb");
90 LOG_ERROR("Can't open %s\n", fileName
);
93 if (fseek(pFile
, 0, SEEK_END
)!=0)
95 LOG_ERROR("Can't open %s\n", fileName
);
99 long fsize
= ftell(pFile
);
102 LOG_ERROR("Can't open %s\n", fileName
);
108 if (fseek(pFile
, 0, SEEK_SET
)!=0)
110 LOG_ERROR("Can't open %s\n", fileName
);
114 *data
= malloc(*len
+ 1);
117 LOG_ERROR("Can't open %s\n", fileName
);
122 if (fread(*data
, 1, *len
, pFile
)!=*len
)
126 LOG_ERROR("Can't open %s\n", fileName
);
131 // 0-byte after buffer (not included in *len) serves as a sentinel
132 char *buf
= (char *)*data
;
140 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
141 char **args
, int argc
)
145 command_print(cmd_ctx
, "cat <filename>");
146 return ERROR_INVALID_ARGUMENTS
;
149 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
153 int retval
= loadFile(args
[0], &data
, &len
);
154 if (retval
== ERROR_OK
)
156 command_print(cmd_ctx
, "%s", data
);
161 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
166 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
167 char **args
, int argc
)
171 command_print(cmd_ctx
, "trunc <filename>");
172 return ERROR_INVALID_ARGUMENTS
;
175 FILE *config_file
= NULL
;
176 config_file
= fopen(args
[0], "w");
177 if (config_file
!= NULL
)
184 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
187 struct mallinfo info
;
191 command_print(cmd_ctx
, "meminfo");
192 return ERROR_INVALID_ARGUMENTS
;
199 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
201 prev
= info
.fordblks
;
203 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
209 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
210 char **args
, int argc
)
214 command_print(cmd_ctx
,
215 "append <filename> [<string1>, [<string2>, ...]]");
216 return ERROR_INVALID_ARGUMENTS
;
219 FILE *config_file
= NULL
;
220 config_file
= fopen(args
[0], "a");
221 if (config_file
!= NULL
)
224 fseek(config_file
, 0, SEEK_END
);
226 for (i
= 1; i
< argc
; i
++)
228 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
231 fwrite(" ", 1, 1, config_file
);
234 fwrite("\n", 1, 1, config_file
);
243 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
247 return ERROR_INVALID_ARGUMENTS
;
250 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
254 int retval
= loadFile(args
[0], &data
, &len
);
255 if (retval
!= ERROR_OK
)
258 FILE *f
= fopen(args
[1], "wb");
260 retval
= ERROR_INVALID_ARGUMENTS
;
265 size_t chunk
= len
- pos
;
266 static const size_t maxChunk
= 512 * 1024; // ~1/sec
267 if (chunk
> maxChunk
)
272 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
273 retval
= ERROR_INVALID_ARGUMENTS
;
275 if (retval
!= ERROR_OK
)
280 command_print(cmd_ctx
, "%d", len
- pos
);
288 if (retval
== ERROR_OK
)
290 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
293 command_print(cmd_ctx
, "Failed: %d", retval
);
301 if (retval
!= ERROR_OK
)
310 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
313 void copyfile(char *name2
, char *name1
)
321 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
323 SHOW_RESULT( open
, fd1
);
325 fd2
= open(name2
, O_RDONLY
);
327 SHOW_RESULT( open
, fd2
);
331 done
= read(fd2
, buf
, IOSIZE
);
334 SHOW_RESULT( read
, done
);
338 if( done
== 0 ) break;
340 wrote
= write(fd1
, buf
, done
);
341 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
343 if( wrote
!= done
) break;
347 if( err
< 0 ) SHOW_RESULT( close
, err
);
350 if( err
< 0 ) SHOW_RESULT( close
, err
);
354 /* utility fn to copy a directory */
355 void copydir(char *name
, char *destdir
)
360 dirp
= opendir(destdir
);
363 mkdir(destdir
, 0777);
366 err
= closedir(dirp
);
369 dirp
= opendir(name
);
370 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
374 struct dirent
*entry
= readdir(dirp
);
379 if (strcmp(entry
->d_name
, ".") == 0)
381 if (strcmp(entry
->d_name
, "..") == 0)
386 char fullPath
[PATH_MAX
];
387 strncpy(fullPath
, name
, PATH_MAX
);
388 strcat(fullPath
, "/");
389 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
391 if (stat(fullPath
, &buf
) == -1)
393 LOG_ERROR("unable to read status from %s", fullPath
);
396 isDir
= S_ISDIR(buf
.st_mode
) != 0;
401 // diag_printf("<INFO>: entry %14s",entry->d_name);
402 char fullname
[PATH_MAX
];
403 char fullname2
[PATH_MAX
];
405 strcpy(fullname
, name
);
406 strcat(fullname
, "/");
407 strcat(fullname
, entry
->d_name
);
409 strcpy(fullname2
, destdir
);
410 strcat(fullname2
, "/");
411 strcat(fullname2
, entry
->d_name
);
412 // diag_printf("from %s to %s\n", fullname, fullname2);
413 copyfile(fullname
, fullname2
);
415 // diag_printf("\n");
418 err
= closedir(dirp
);
419 if( err
< 0 ) SHOW_RESULT( stat
, err
);
426 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
428 Jim_Obj
* const *argv
)
433 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
438 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
440 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
443 return del
? JIM_OK
: JIM_ERR
;
448 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
450 Jim_Obj
* const *argv
)
454 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
458 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
461 dirp
= opendir(name
);
466 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
470 struct dirent
*entry
= NULL
;
471 entry
= readdir(dirp
);
475 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
478 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
482 Jim_SetResult(interp
, objPtr
);
487 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
491 return ERROR_COMMAND_SYNTAX_ERROR
;
493 unsigned long addr
= strtoul(args
[0], NULL
, 0);
494 volatile unsigned *address
= (volatile unsigned *)addr
;
495 unsigned value
= *address
;
496 command_print(cmd_ctx
, "0x%x : 0x%x", address
, value
);
500 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
504 return ERROR_INVALID_ARGUMENTS
;
506 unsigned long addr
= strtoul(args
[0], NULL
, 0);
507 volatile int *address
= (volatile int *)addr
;
508 int value
=strtoul(args
[1], NULL
, 0);
514 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
516 Jim_Obj
* const *argv
)
520 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
525 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
528 int value
= *((volatile int *) address
);
530 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
536 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
538 Jim_Obj
* const *argv
)
542 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
547 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
550 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
553 *((volatile int *) address
) = value
;
559 /* not so pretty code to fish out ip number*/
560 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
561 Jim_Obj
* const *argv
)
563 #if !defined(__CYGWIN__)
564 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
566 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
568 if (getifaddrs(&ifp
) < 0)
573 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
578 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
579 salen
= sizeof(struct sockaddr_in
);
580 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
581 salen
= sizeof(struct sockaddr_in6
);
585 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
591 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
598 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
599 LOG_ERROR("NOT IMPLEMENTED!!!");
601 Jim_SetResult(interp
, tclOutput
);
606 /* not so pretty code to fish out eth0 mac address */
607 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
608 Jim_Obj
* const *argv
)
612 struct ifreq
*ifr
, *ifend
;
618 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
624 ifc
.ifc_len
= sizeof(ifs
);
626 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
632 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
633 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
635 //if (ifr->ifr_addr.sa_family == AF_INET)
637 if (strcmp("eth0", ifr
->ifr_name
)!=0)
639 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
640 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
649 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
652 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
653 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
654 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
655 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
656 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
657 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
658 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
660 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
662 Jim_SetResult(interp
, tclOutput
);
675 int ioutil_init(struct command_context_s
*cmd_ctx
)
677 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
680 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
681 "display file content");
683 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
684 "truncate a file to 0 size");
686 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
687 COMMAND_ANY
, "copy a file <from> <to>");
689 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
690 COMMAND_ANY
, "append a variable number of strings to a file");
692 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
693 COMMAND_ANY
, "display available ram memory");
695 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
697 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
698 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
699 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
701 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
704 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)