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
)
95 pFile
= fopen(fileName
,"rb");
98 LOG_ERROR("Can't open %s\n", fileName
);
101 if (fseek(pFile
, 0, SEEK_END
)!=0)
103 LOG_ERROR("Can't open %s\n", fileName
);
107 long fsize
= ftell(pFile
);
110 LOG_ERROR("Can't open %s\n", fileName
);
115 if (fseek(pFile
, 0, SEEK_SET
)!=0)
117 LOG_ERROR("Can't open %s\n", fileName
);
121 *data
= malloc(fsize
+ 1);
124 LOG_ERROR("Can't open %s\n", fileName
);
129 if (fread(*data
, 1, *len
, pFile
)!=*len
)
133 LOG_ERROR("Can't open %s\n", fileName
);
137 *(((char *)(*data
))+*len
)=0; /* sentinel */
147 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
148 char **args
, int argc
)
152 command_print(cmd_ctx
, "cat <filename>");
153 return ERROR_INVALID_ARGUMENTS
;
156 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
160 int retval
= loadFile(args
[0], &data
, &len
);
161 if (retval
== ERROR_OK
)
163 command_print(cmd_ctx
, "%s", data
);
168 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
173 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
174 char **args
, int argc
)
178 command_print(cmd_ctx
, "trunc <filename>");
179 return ERROR_INVALID_ARGUMENTS
;
182 FILE *config_file
= NULL
;
183 config_file
= fopen(args
[0], "w");
184 if (config_file
!= NULL
)
191 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
194 struct mallinfo info
;
198 command_print(cmd_ctx
, "meminfo");
199 return ERROR_INVALID_ARGUMENTS
;
206 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
208 prev
= info
.fordblks
;
210 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
216 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
217 char **args
, int argc
)
221 command_print(cmd_ctx
,
222 "append <filename> [<string1>, [<string2>, ...]]");
223 return ERROR_INVALID_ARGUMENTS
;
226 FILE *config_file
= NULL
;
227 config_file
= fopen(args
[0], "a");
228 if (config_file
!= NULL
)
231 fseek(config_file
, 0, SEEK_END
);
233 for (i
= 1; i
< argc
; i
++)
235 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
238 fwrite(" ", 1, 1, config_file
);
241 fwrite("\n", 1, 1, config_file
);
250 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
254 return ERROR_INVALID_ARGUMENTS
;
257 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
261 int retval
= loadFile(args
[0], &data
, &len
);
262 if (retval
!= ERROR_OK
)
265 FILE *f
= fopen(args
[1], "wb");
267 retval
= ERROR_INVALID_ARGUMENTS
;
272 size_t chunk
= len
- pos
;
273 static const size_t maxChunk
= 512 * 1024; // ~1/sec
274 if (chunk
> maxChunk
)
279 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
280 retval
= ERROR_INVALID_ARGUMENTS
;
282 if (retval
!= ERROR_OK
)
287 command_print(cmd_ctx
, "%d", len
- pos
);
295 if (retval
== ERROR_OK
)
297 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
300 command_print(cmd_ctx
, "Failed: %d", retval
);
308 if (retval
!= ERROR_OK
)
317 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
320 void copyfile(char *name2
, char *name1
)
328 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
330 SHOW_RESULT( open
, fd1
);
332 fd2
= open(name2
, O_RDONLY
);
334 SHOW_RESULT( open
, fd2
);
338 done
= read(fd2
, buf
, IOSIZE
);
341 SHOW_RESULT( read
, done
);
345 if( done
== 0 ) break;
347 wrote
= write(fd1
, buf
, done
);
348 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
350 if( wrote
!= done
) break;
354 if( err
< 0 ) SHOW_RESULT( close
, err
);
357 if( err
< 0 ) SHOW_RESULT( close
, err
);
361 /* utility fn to copy a directory */
362 void copydir(char *name
, char *destdir
)
367 dirp
= opendir(destdir
);
370 mkdir(destdir
, 0777);
373 err
= closedir(dirp
);
376 dirp
= opendir(name
);
377 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
381 struct dirent
*entry
= readdir(dirp
);
386 if (strcmp(entry
->d_name
, ".") == 0)
388 if (strcmp(entry
->d_name
, "..") == 0)
393 char fullPath
[PATH_MAX
];
394 strncpy(fullPath
, name
, PATH_MAX
);
395 strcat(fullPath
, "/");
396 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
398 if (stat(fullPath
, &buf
) == -1)
400 LOG_ERROR("unable to read status from %s", fullPath
);
403 isDir
= S_ISDIR(buf
.st_mode
) != 0;
408 // diag_printf("<INFO>: entry %14s",entry->d_name);
409 char fullname
[PATH_MAX
];
410 char fullname2
[PATH_MAX
];
412 strcpy(fullname
, name
);
413 strcat(fullname
, "/");
414 strcat(fullname
, entry
->d_name
);
416 strcpy(fullname2
, destdir
);
417 strcat(fullname2
, "/");
418 strcat(fullname2
, entry
->d_name
);
419 // diag_printf("from %s to %s\n", fullname, fullname2);
420 copyfile(fullname
, fullname2
);
422 // diag_printf("\n");
425 err
= closedir(dirp
);
426 if( err
< 0 ) SHOW_RESULT( stat
, err
);
433 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
435 Jim_Obj
* const *argv
)
440 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
445 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
447 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
450 return del
? JIM_OK
: JIM_ERR
;
455 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
457 Jim_Obj
* const *argv
)
461 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
465 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
468 dirp
= opendir(name
);
473 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
477 struct dirent
*entry
= NULL
;
478 entry
= readdir(dirp
);
482 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
485 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
489 Jim_SetResult(interp
, objPtr
);
494 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
498 return ERROR_COMMAND_SYNTAX_ERROR
;
500 unsigned long addr
= strtoul(args
[0], NULL
, 0);
501 volatile unsigned *address
= (volatile unsigned *)addr
;
502 unsigned value
= *address
;
503 command_print(cmd_ctx
, "0x%x : 0x%x", address
, value
);
507 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
511 return ERROR_INVALID_ARGUMENTS
;
513 unsigned long addr
= strtoul(args
[0], NULL
, 0);
514 volatile int *address
= (volatile int *)addr
;
515 int value
=strtoul(args
[1], NULL
, 0);
521 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
523 Jim_Obj
* const *argv
)
527 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
532 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
535 int value
= *((volatile int *) address
);
537 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
543 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
545 Jim_Obj
* const *argv
)
549 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
554 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
557 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
560 *((volatile int *) address
) = value
;
566 /* not so pretty code to fish out ip number*/
567 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
568 Jim_Obj
* const *argv
)
570 #if !defined(__CYGWIN__)
571 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
573 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
575 if (getifaddrs(&ifp
) < 0)
580 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
585 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
586 salen
= sizeof(struct sockaddr_in
);
587 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
588 salen
= sizeof(struct sockaddr_in6
);
592 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
598 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
605 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
606 LOG_ERROR("NOT IMPLEMENTED!!!");
608 Jim_SetResult(interp
, tclOutput
);
613 /* not so pretty code to fish out eth0 mac address */
614 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
615 Jim_Obj
* const *argv
)
619 struct ifreq
*ifr
, *ifend
;
625 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
631 ifc
.ifc_len
= sizeof(ifs
);
633 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
639 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
640 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
642 //if (ifr->ifr_addr.sa_family == AF_INET)
644 if (strcmp("eth0", ifr
->ifr_name
)!=0)
646 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
647 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
656 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
659 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
660 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
661 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
662 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
663 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
664 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
665 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
667 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
669 Jim_SetResult(interp
, tclOutput
);
682 int ioutil_init(struct command_context_s
*cmd_ctx
)
684 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
687 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
688 "display file content");
690 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
691 "truncate a file to 0 size");
693 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
694 COMMAND_ANY
, "copy a file <from> <to>");
696 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
697 COMMAND_ANY
, "append a variable number of strings to a file");
699 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
700 COMMAND_ANY
, "display available ram memory");
702 Jim_CreateCommand(interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
704 Jim_CreateCommand(interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
705 Jim_CreateCommand(interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
706 Jim_CreateCommand(interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
708 Jim_CreateCommand(interp
, "mac", zylinjtag_Jim_Command_mac
,
711 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)