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
, size_t *len
)
94 // ensure returned length is always sane
98 pFile
= fopen(fileName
,"rb");
101 LOG_ERROR("Can't open %s\n", fileName
);
104 if (fseek(pFile
, 0, SEEK_END
)!=0)
106 LOG_ERROR("Can't open %s\n", fileName
);
110 long fsize
= ftell(pFile
);
113 LOG_ERROR("Can't open %s\n", fileName
);
119 if (fseek(pFile
, 0, SEEK_SET
)!=0)
121 LOG_ERROR("Can't open %s\n", fileName
);
125 *data
= malloc(*len
+ 1);
128 LOG_ERROR("Can't open %s\n", fileName
);
133 if (fread(*data
, 1, *len
, pFile
)!=*len
)
137 LOG_ERROR("Can't open %s\n", fileName
);
142 // 0-byte after buffer (not included in *len) serves as a sentinel
143 char *buf
= (char *)*data
;
151 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
152 char **args
, int argc
)
156 command_print(cmd_ctx
, "cat <filename>");
157 return ERROR_INVALID_ARGUMENTS
;
160 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
164 int retval
= loadFile(args
[0], &data
, &len
);
165 if (retval
== ERROR_OK
)
167 command_print(cmd_ctx
, "%s", data
);
172 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
177 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
178 char **args
, int argc
)
182 command_print(cmd_ctx
, "trunc <filename>");
183 return ERROR_INVALID_ARGUMENTS
;
186 FILE *config_file
= NULL
;
187 config_file
= fopen(args
[0], "w");
188 if (config_file
!= NULL
)
195 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
198 struct mallinfo info
;
202 command_print(cmd_ctx
, "meminfo");
203 return ERROR_INVALID_ARGUMENTS
;
210 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
212 prev
= info
.fordblks
;
214 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
220 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
221 char **args
, int argc
)
225 command_print(cmd_ctx
,
226 "append <filename> [<string1>, [<string2>, ...]]");
227 return ERROR_INVALID_ARGUMENTS
;
230 FILE *config_file
= NULL
;
231 config_file
= fopen(args
[0], "a");
232 if (config_file
!= NULL
)
235 fseek(config_file
, 0, SEEK_END
);
237 for (i
= 1; i
< argc
; i
++)
239 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
242 fwrite(" ", 1, 1, config_file
);
245 fwrite("\n", 1, 1, config_file
);
254 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
258 return ERROR_INVALID_ARGUMENTS
;
261 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
265 int retval
= loadFile(args
[0], &data
, &len
);
266 if (retval
!= ERROR_OK
)
269 FILE *f
= fopen(args
[1], "wb");
271 retval
= ERROR_INVALID_ARGUMENTS
;
276 size_t chunk
= len
- pos
;
277 static const size_t maxChunk
= 512 * 1024; // ~1/sec
278 if (chunk
> maxChunk
)
283 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
284 retval
= ERROR_INVALID_ARGUMENTS
;
286 if (retval
!= ERROR_OK
)
291 command_print(cmd_ctx
, "%d", len
- pos
);
299 if (retval
== ERROR_OK
)
301 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
304 command_print(cmd_ctx
, "Failed: %d", retval
);
312 if (retval
!= ERROR_OK
)
321 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
324 void copyfile(char *name2
, char *name1
)
332 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
334 SHOW_RESULT( open
, fd1
);
336 fd2
= open(name2
, O_RDONLY
);
338 SHOW_RESULT( open
, fd2
);
342 done
= read(fd2
, buf
, IOSIZE
);
345 SHOW_RESULT( read
, done
);
349 if( done
== 0 ) break;
351 wrote
= write(fd1
, buf
, done
);
352 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
354 if( wrote
!= done
) break;
358 if( err
< 0 ) SHOW_RESULT( close
, err
);
361 if( err
< 0 ) SHOW_RESULT( close
, err
);
365 /* utility fn to copy a directory */
366 void copydir(char *name
, char *destdir
)
371 dirp
= opendir(destdir
);
374 mkdir(destdir
, 0777);
377 err
= closedir(dirp
);
380 dirp
= opendir(name
);
381 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
385 struct dirent
*entry
= readdir(dirp
);
390 if (strcmp(entry
->d_name
, ".") == 0)
392 if (strcmp(entry
->d_name
, "..") == 0)
397 char fullPath
[PATH_MAX
];
398 strncpy(fullPath
, name
, PATH_MAX
);
399 strcat(fullPath
, "/");
400 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
402 if (stat(fullPath
, &buf
) == -1)
404 LOG_ERROR("unable to read status from %s", fullPath
);
407 isDir
= S_ISDIR(buf
.st_mode
) != 0;
412 // diag_printf("<INFO>: entry %14s",entry->d_name);
413 char fullname
[PATH_MAX
];
414 char fullname2
[PATH_MAX
];
416 strcpy(fullname
, name
);
417 strcat(fullname
, "/");
418 strcat(fullname
, entry
->d_name
);
420 strcpy(fullname2
, destdir
);
421 strcat(fullname2
, "/");
422 strcat(fullname2
, entry
->d_name
);
423 // diag_printf("from %s to %s\n", fullname, fullname2);
424 copyfile(fullname
, fullname2
);
426 // diag_printf("\n");
429 err
= closedir(dirp
);
430 if( err
< 0 ) SHOW_RESULT( stat
, err
);
437 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
439 Jim_Obj
* const *argv
)
444 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
449 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
451 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
454 return del
? JIM_OK
: JIM_ERR
;
459 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
461 Jim_Obj
* const *argv
)
465 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
469 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
472 dirp
= opendir(name
);
477 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
481 struct dirent
*entry
= NULL
;
482 entry
= readdir(dirp
);
486 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
489 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
493 Jim_SetResult(interp
, objPtr
);
498 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
502 return ERROR_COMMAND_SYNTAX_ERROR
;
504 unsigned long addr
= strtoul(args
[0], NULL
, 0);
505 volatile unsigned *address
= (volatile unsigned *)addr
;
506 unsigned value
= *address
;
507 command_print(cmd_ctx
, "0x%x : 0x%x", address
, value
);
511 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
515 return ERROR_INVALID_ARGUMENTS
;
517 unsigned long addr
= strtoul(args
[0], NULL
, 0);
518 volatile int *address
= (volatile int *)addr
;
519 int value
=strtoul(args
[1], NULL
, 0);
525 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
527 Jim_Obj
* const *argv
)
531 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
536 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
539 int value
= *((volatile int *) address
);
541 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
547 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
549 Jim_Obj
* const *argv
)
553 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
558 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
561 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
564 *((volatile int *) address
) = value
;
570 /* not so pretty code to fish out ip number*/
571 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
572 Jim_Obj
* const *argv
)
574 #if !defined(__CYGWIN__)
575 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
577 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
579 if (getifaddrs(&ifp
) < 0)
584 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
589 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
590 salen
= sizeof(struct sockaddr_in
);
591 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
592 salen
= sizeof(struct sockaddr_in6
);
596 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
602 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
609 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
610 LOG_ERROR("NOT IMPLEMENTED!!!");
612 Jim_SetResult(interp
, tclOutput
);
617 /* not so pretty code to fish out eth0 mac address */
618 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
619 Jim_Obj
* const *argv
)
623 struct ifreq
*ifr
, *ifend
;
629 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
635 ifc
.ifc_len
= sizeof(ifs
);
637 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
643 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
644 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
646 //if (ifr->ifr_addr.sa_family == AF_INET)
648 if (strcmp("eth0", ifr
->ifr_name
)!=0)
650 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
651 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
660 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
663 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
664 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
665 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
666 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
667 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
668 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
669 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
671 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
673 Jim_SetResult(interp
, tclOutput
);
686 int ioutil_init(struct command_context_s
*cmd_ctx
)
688 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
691 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
692 "display file content");
694 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
695 "truncate a file to 0 size");
697 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
698 COMMAND_ANY
, "copy a file <from> <to>");
700 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
701 COMMAND_ANY
, "append a variable number of strings to a file");
703 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
704 COMMAND_ANY
, "display available ram memory");
706 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
708 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
709 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
710 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
712 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
715 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)