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
60 COMMAND_HANDLER(handle_rm_command
)
64 command_print(cmd_ctx
, "rm <filename>");
65 return ERROR_INVALID_ARGUMENTS
;
68 if (unlink(args
[0]) != 0)
70 command_print(cmd_ctx
, "failed: %d", errno
);
77 /* loads a file and returns a pointer to it in memory. The file contains
78 * a 0 byte(sentinel) after len bytes - the length of the file. */
79 int loadFile(const char *fileName
, void **data
, size_t *len
)
81 // ensure returned length is always sane
85 pFile
= fopen(fileName
,"rb");
88 LOG_ERROR("Can't open %s\n", fileName
);
91 if (fseek(pFile
, 0, SEEK_END
) != 0)
93 LOG_ERROR("Can't open %s\n", fileName
);
97 long fsize
= ftell(pFile
);
100 LOG_ERROR("Can't open %s\n", fileName
);
106 if (fseek(pFile
, 0, SEEK_SET
) != 0)
108 LOG_ERROR("Can't open %s\n", fileName
);
112 *data
= malloc(*len
+ 1);
115 LOG_ERROR("Can't open %s\n", fileName
);
120 if (fread(*data
, 1, *len
, pFile
)!=*len
)
124 LOG_ERROR("Can't open %s\n", fileName
);
129 // 0-byte after buffer (not included in *len) serves as a sentinel
130 char *buf
= (char *)*data
;
136 COMMAND_HANDLER(handle_cat_command
)
140 command_print(cmd_ctx
, "cat <filename>");
141 return ERROR_INVALID_ARGUMENTS
;
144 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
148 int retval
= loadFile(args
[0], &data
, &len
);
149 if (retval
== ERROR_OK
)
151 command_print(cmd_ctx
, "%s", (char *)data
);
156 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
162 COMMAND_HANDLER(handle_trunc_command
)
166 command_print(cmd_ctx
, "trunc <filename>");
167 return ERROR_INVALID_ARGUMENTS
;
170 FILE *config_file
= NULL
;
171 config_file
= fopen(args
[0], "w");
172 if (config_file
!= NULL
)
178 COMMAND_HANDLER(handle_meminfo_command
)
181 struct mallinfo info
;
185 command_print(cmd_ctx
, "meminfo");
186 return ERROR_INVALID_ARGUMENTS
;
193 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
195 prev
= info
.fordblks
;
197 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
203 COMMAND_HANDLER(handle_append_command
)
207 command_print(cmd_ctx
,
208 "append <filename> [<string1>, [<string2>, ...]]");
209 return ERROR_INVALID_ARGUMENTS
;
212 int retval
= ERROR_FAIL
;
213 FILE *config_file
= NULL
;
214 config_file
= fopen(args
[0], "a");
215 if (config_file
!= NULL
)
217 fseek(config_file
, 0, SEEK_END
);
220 for (i
= 1; i
< argc
; i
++)
222 if (fwrite(args
[i
], 1, strlen(args
[i
]), config_file
) != strlen(args
[i
]))
226 if (fwrite(" ", 1, 1, config_file
) != 1)
230 if ((i
== argc
) && (fwrite("\n", 1, 1, config_file
) == 1))
242 COMMAND_HANDLER(handle_cp_command
)
246 return ERROR_INVALID_ARGUMENTS
;
249 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
253 int retval
= loadFile(args
[0], &data
, &len
);
254 if (retval
!= ERROR_OK
)
257 FILE *f
= fopen(args
[1], "wb");
259 retval
= ERROR_INVALID_ARGUMENTS
;
264 size_t chunk
= len
- pos
;
265 static const size_t maxChunk
= 512 * 1024; // ~1/sec
266 if (chunk
> maxChunk
)
271 if ((retval
== ERROR_OK
) && (fwrite(((char *)data
) + pos
, 1, chunk
, f
) != chunk
))
272 retval
= ERROR_INVALID_ARGUMENTS
;
274 if (retval
!= ERROR_OK
)
279 command_print(cmd_ctx
, "%zu", len
- pos
);
287 if (retval
== ERROR_OK
)
289 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
292 command_print(cmd_ctx
, "Failed: %d", retval
);
300 if (retval
!= ERROR_OK
)
309 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
312 void copyfile(char *name2
, char *name1
)
320 fd1
= open(name1
, O_WRONLY
| O_CREAT
, 0664);
322 SHOW_RESULT(open
, fd1
);
324 fd2
= open(name2
, O_RDONLY
);
326 SHOW_RESULT(open
, fd2
);
330 done
= read(fd2
, buf
, IOSIZE
);
333 SHOW_RESULT(read
, done
);
337 if (done
== 0) break;
339 wrote
= write(fd1
, buf
, done
);
340 if (wrote
!= done
) SHOW_RESULT(write
, wrote
);
342 if (wrote
!= done
) break;
346 if (err
< 0) SHOW_RESULT(close
, err
);
349 if (err
< 0) SHOW_RESULT(close
, err
);
353 /* utility fn to copy a directory */
354 void copydir(char *name
, char *destdir
)
359 dirp
= opendir(destdir
);
362 mkdir(destdir
, 0777);
365 err
= closedir(dirp
);
368 dirp
= opendir(name
);
369 if (dirp
== NULL
) SHOW_RESULT(opendir
, -1);
373 struct dirent
*entry
= readdir(dirp
);
378 if (strcmp(entry
->d_name
, ".") == 0)
380 if (strcmp(entry
->d_name
, "..") == 0)
385 char fullPath
[PATH_MAX
];
386 strncpy(fullPath
, name
, PATH_MAX
);
387 strcat(fullPath
, "/");
388 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
390 if (stat(fullPath
, &buf
) == -1)
392 LOG_ERROR("unable to read status from %s", fullPath
);
395 isDir
= S_ISDIR(buf
.st_mode
) != 0;
400 // diag_printf("<INFO>: entry %14s",entry->d_name);
401 char fullname
[PATH_MAX
];
402 char fullname2
[PATH_MAX
];
404 strcpy(fullname
, name
);
405 strcat(fullname
, "/");
406 strcat(fullname
, entry
->d_name
);
408 strcpy(fullname2
, destdir
);
409 strcat(fullname2
, "/");
410 strcat(fullname2
, entry
->d_name
);
411 // diag_printf("from %s to %s\n", fullname, fullname2);
412 copyfile(fullname
, fullname2
);
414 // diag_printf("\n");
417 err
= closedir(dirp
);
418 if (err
< 0) SHOW_RESULT(stat
, err
);
425 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
427 Jim_Obj
* const *argv
)
432 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
437 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
439 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
442 return del
? JIM_OK
: JIM_ERR
;
447 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
449 Jim_Obj
* const *argv
)
453 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
457 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
460 dirp
= opendir(name
);
465 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
469 struct dirent
*entry
= NULL
;
470 entry
= readdir(dirp
);
474 if ((strcmp(".", entry
->d_name
) == 0)||(strcmp("..", entry
->d_name
) == 0))
477 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
481 Jim_SetResult(interp
, objPtr
);
487 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
489 Jim_Obj
* const *argv
)
493 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
498 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
501 int value
= *((volatile int *) address
);
503 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
509 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
511 Jim_Obj
* const *argv
)
515 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
520 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
523 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
526 *((volatile int *) address
) = value
;
532 /* not so pretty code to fish out ip number*/
533 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
534 Jim_Obj
* const *argv
)
536 #if !defined(__CYGWIN__)
537 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
539 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
541 if (getifaddrs(&ifp
) < 0)
546 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
551 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
552 salen
= sizeof(struct sockaddr_in
);
553 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
554 salen
= sizeof(struct sockaddr_in6
);
558 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
564 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
571 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
572 LOG_ERROR("NOT IMPLEMENTED!!!");
574 Jim_SetResult(interp
, tclOutput
);
579 /* not so pretty code to fish out eth0 mac address */
580 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
581 Jim_Obj
* const *argv
)
585 struct ifreq
*ifr
, *ifend
;
591 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
597 ifc
.ifc_len
= sizeof(ifs
);
599 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
605 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
606 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
608 //if (ifr->ifr_addr.sa_family == AF_INET)
610 if (strcmp("eth0", ifr
->ifr_name
) != 0)
612 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
613 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
622 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
625 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
626 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
627 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
628 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
629 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
630 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
631 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
633 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
635 Jim_SetResult(interp
, tclOutput
);
648 int ioutil_init(struct command_context_s
*cmd_ctx
)
650 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
653 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
654 "display file content");
656 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
657 "truncate a file to 0 size");
659 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
660 COMMAND_ANY
, "copy a file <from> <to>");
662 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
663 COMMAND_ANY
, "append a variable number of strings to a file");
665 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
666 COMMAND_ANY
, "display available ram memory");
668 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
670 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
671 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
672 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
674 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
677 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)