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>
49 #include <netinet/tcp.h>
50 #include <sys/ioctl.h>
51 #include <sys/socket.h>
52 #include <netinet/in.h>
54 #include <arpa/inet.h>
55 #include <sys/socket.h>
57 #include <netinet/in.h>
59 #include <arpa/inet.h>
63 #if !defined(__CYGWIN__)
70 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
71 char **args
, int argc
)
75 command_print(cmd_ctx
, "rm <filename>");
76 return ERROR_INVALID_ARGUMENTS
;
79 if (unlink(args
[0]) != 0)
81 command_print(cmd_ctx
, "failed: %d", errno
);
88 /* loads a file and returns a pointer to it in memory. The file contains
89 * a 0 byte(sentinel) after len bytes - the length of the file. */
90 int loadFile(const char *fileName
, void **data
, size_t *len
)
92 // ensure returned length is always sane
96 pFile
= fopen(fileName
,"rb");
99 LOG_ERROR("Can't open %s\n", fileName
);
102 if (fseek(pFile
, 0, SEEK_END
)!=0)
104 LOG_ERROR("Can't open %s\n", fileName
);
108 long fsize
= ftell(pFile
);
111 LOG_ERROR("Can't open %s\n", fileName
);
117 if (fseek(pFile
, 0, SEEK_SET
)!=0)
119 LOG_ERROR("Can't open %s\n", fileName
);
123 *data
= malloc(*len
+ 1);
126 LOG_ERROR("Can't open %s\n", fileName
);
131 if (fread(*data
, 1, *len
, pFile
)!=*len
)
135 LOG_ERROR("Can't open %s\n", fileName
);
140 // 0-byte after buffer (not included in *len) serves as a sentinel
141 char *buf
= (char *)*data
;
149 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
150 char **args
, int argc
)
154 command_print(cmd_ctx
, "cat <filename>");
155 return ERROR_INVALID_ARGUMENTS
;
158 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
162 int retval
= loadFile(args
[0], &data
, &len
);
163 if (retval
== ERROR_OK
)
165 command_print(cmd_ctx
, "%s", data
);
170 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
175 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
176 char **args
, int argc
)
180 command_print(cmd_ctx
, "trunc <filename>");
181 return ERROR_INVALID_ARGUMENTS
;
184 FILE *config_file
= NULL
;
185 config_file
= fopen(args
[0], "w");
186 if (config_file
!= NULL
)
193 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
196 struct mallinfo info
;
200 command_print(cmd_ctx
, "meminfo");
201 return ERROR_INVALID_ARGUMENTS
;
208 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
210 prev
= info
.fordblks
;
212 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
218 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
219 char **args
, int argc
)
223 command_print(cmd_ctx
,
224 "append <filename> [<string1>, [<string2>, ...]]");
225 return ERROR_INVALID_ARGUMENTS
;
228 FILE *config_file
= NULL
;
229 config_file
= fopen(args
[0], "a");
230 if (config_file
!= NULL
)
233 fseek(config_file
, 0, SEEK_END
);
235 for (i
= 1; i
< argc
; i
++)
237 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
240 fwrite(" ", 1, 1, config_file
);
243 fwrite("\n", 1, 1, config_file
);
252 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
256 return ERROR_INVALID_ARGUMENTS
;
259 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
263 int retval
= loadFile(args
[0], &data
, &len
);
264 if (retval
!= ERROR_OK
)
267 FILE *f
= fopen(args
[1], "wb");
269 retval
= ERROR_INVALID_ARGUMENTS
;
274 size_t chunk
= len
- pos
;
275 static const size_t maxChunk
= 512 * 1024; // ~1/sec
276 if (chunk
> maxChunk
)
281 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
282 retval
= ERROR_INVALID_ARGUMENTS
;
284 if (retval
!= ERROR_OK
)
289 command_print(cmd_ctx
, "%d", len
- pos
);
297 if (retval
== ERROR_OK
)
299 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
302 command_print(cmd_ctx
, "Failed: %d", retval
);
310 if (retval
!= ERROR_OK
)
319 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
322 void copyfile(char *name2
, char *name1
)
330 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
332 SHOW_RESULT( open
, fd1
);
334 fd2
= open(name2
, O_RDONLY
);
336 SHOW_RESULT( open
, fd2
);
340 done
= read(fd2
, buf
, IOSIZE
);
343 SHOW_RESULT( read
, done
);
347 if( done
== 0 ) break;
349 wrote
= write(fd1
, buf
, done
);
350 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
352 if( wrote
!= done
) break;
356 if( err
< 0 ) SHOW_RESULT( close
, err
);
359 if( err
< 0 ) SHOW_RESULT( close
, err
);
363 /* utility fn to copy a directory */
364 void copydir(char *name
, char *destdir
)
369 dirp
= opendir(destdir
);
372 mkdir(destdir
, 0777);
375 err
= closedir(dirp
);
378 dirp
= opendir(name
);
379 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
383 struct dirent
*entry
= readdir(dirp
);
388 if (strcmp(entry
->d_name
, ".") == 0)
390 if (strcmp(entry
->d_name
, "..") == 0)
395 char fullPath
[PATH_MAX
];
396 strncpy(fullPath
, name
, PATH_MAX
);
397 strcat(fullPath
, "/");
398 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
400 if (stat(fullPath
, &buf
) == -1)
402 LOG_ERROR("unable to read status from %s", fullPath
);
405 isDir
= S_ISDIR(buf
.st_mode
) != 0;
410 // diag_printf("<INFO>: entry %14s",entry->d_name);
411 char fullname
[PATH_MAX
];
412 char fullname2
[PATH_MAX
];
414 strcpy(fullname
, name
);
415 strcat(fullname
, "/");
416 strcat(fullname
, entry
->d_name
);
418 strcpy(fullname2
, destdir
);
419 strcat(fullname2
, "/");
420 strcat(fullname2
, entry
->d_name
);
421 // diag_printf("from %s to %s\n", fullname, fullname2);
422 copyfile(fullname
, fullname2
);
424 // diag_printf("\n");
427 err
= closedir(dirp
);
428 if( err
< 0 ) SHOW_RESULT( stat
, err
);
435 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
437 Jim_Obj
* const *argv
)
442 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
447 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
449 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
452 return del
? JIM_OK
: JIM_ERR
;
457 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
459 Jim_Obj
* const *argv
)
463 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
467 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
470 dirp
= opendir(name
);
475 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
479 struct dirent
*entry
= NULL
;
480 entry
= readdir(dirp
);
484 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
487 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
491 Jim_SetResult(interp
, objPtr
);
496 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
500 return ERROR_COMMAND_SYNTAX_ERROR
;
502 unsigned long addr
= strtoul(args
[0], NULL
, 0);
503 volatile unsigned *address
= (volatile unsigned *)addr
;
504 unsigned value
= *address
;
505 command_print(cmd_ctx
, "0x%x : 0x%x", address
, value
);
509 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
513 return ERROR_INVALID_ARGUMENTS
;
515 unsigned long addr
= strtoul(args
[0], NULL
, 0);
516 volatile int *address
= (volatile int *)addr
;
517 int value
=strtoul(args
[1], NULL
, 0);
523 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
525 Jim_Obj
* const *argv
)
529 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
534 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
537 int value
= *((volatile int *) address
);
539 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
545 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
547 Jim_Obj
* const *argv
)
551 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
556 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
559 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
562 *((volatile int *) address
) = value
;
568 /* not so pretty code to fish out ip number*/
569 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
570 Jim_Obj
* const *argv
)
572 #if !defined(__CYGWIN__)
573 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
575 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
577 if (getifaddrs(&ifp
) < 0)
582 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
587 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
588 salen
= sizeof(struct sockaddr_in
);
589 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
590 salen
= sizeof(struct sockaddr_in6
);
594 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
600 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
607 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
608 LOG_ERROR("NOT IMPLEMENTED!!!");
610 Jim_SetResult(interp
, tclOutput
);
615 /* not so pretty code to fish out eth0 mac address */
616 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
617 Jim_Obj
* const *argv
)
621 struct ifreq
*ifr
, *ifend
;
627 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
633 ifc
.ifc_len
= sizeof(ifs
);
635 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
641 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
642 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
644 //if (ifr->ifr_addr.sa_family == AF_INET)
646 if (strcmp("eth0", ifr
->ifr_name
)!=0)
648 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
649 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
658 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
661 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
662 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
663 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
664 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
665 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
666 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
667 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
669 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
671 Jim_SetResult(interp
, tclOutput
);
684 int ioutil_init(struct command_context_s
*cmd_ctx
)
686 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
689 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
690 "display file content");
692 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
693 "truncate a file to 0 size");
695 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
696 COMMAND_ANY
, "copy a file <from> <to>");
698 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
699 COMMAND_ANY
, "append a variable number of strings to a file");
701 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
702 COMMAND_ANY
, "display available ram memory");
704 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
706 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
707 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
708 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
710 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
713 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)