1 /***************************************************************************
2 * Copyright (C) 2007-2010 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_SYS_IOCTL_H
42 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_STAT_H
57 /* loads a file and returns a pointer to it in memory. The file contains
58 * a 0 byte(sentinel) after len bytes - the length of the file. */
59 int loadFile(const char *fileName
, void **data
, size_t *len
)
61 // ensure returned length is always sane
65 pFile
= fopen(fileName
,"rb");
68 LOG_ERROR("Can't open %s", fileName
);
71 if (fseek(pFile
, 0, SEEK_END
) != 0)
73 LOG_ERROR("Can't open %s", fileName
);
77 long fsize
= ftell(pFile
);
80 LOG_ERROR("Can't open %s", fileName
);
86 if (fseek(pFile
, 0, SEEK_SET
) != 0)
88 LOG_ERROR("Can't open %s", fileName
);
92 *data
= malloc(*len
+ 1);
95 LOG_ERROR("Can't open %s", fileName
);
100 if (fread(*data
, 1, *len
, pFile
)!=*len
)
104 LOG_ERROR("Can't open %s", fileName
);
109 // 0-byte after buffer (not included in *len) serves as a sentinel
110 char *buf
= (char *)*data
;
116 COMMAND_HANDLER(handle_cat_command
)
120 return ERROR_COMMAND_SYNTAX_ERROR
;
123 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
127 int retval
= loadFile(CMD_ARGV
[0], &data
, &len
);
128 if (retval
== ERROR_OK
)
130 command_print(CMD_CTX
, "%s", (char *)data
);
135 command_print(CMD_CTX
, "%s not found", CMD_ARGV
[0]);
141 COMMAND_HANDLER(handle_trunc_command
)
145 return ERROR_COMMAND_SYNTAX_ERROR
;
148 FILE *config_file
= NULL
;
149 config_file
= fopen(CMD_ARGV
[0], "w");
150 if (config_file
!= NULL
)
156 COMMAND_HANDLER(handle_meminfo_command
)
159 struct mallinfo info
;
163 return ERROR_COMMAND_SYNTAX_ERROR
;
170 command_print(CMD_CTX
, "Diff: %d", prev
- info
.fordblks
);
172 prev
= info
.fordblks
;
174 command_print(CMD_CTX
, "Available ram: %d", info
.fordblks
);
180 COMMAND_HANDLER(handle_append_command
)
184 return ERROR_COMMAND_SYNTAX_ERROR
;
187 int retval
= ERROR_FAIL
;
188 FILE *config_file
= NULL
;
190 config_file
= fopen(CMD_ARGV
[0], "a");
191 if (config_file
!= NULL
)
193 fseek(config_file
, 0, SEEK_END
);
196 for (i
= 1; i
< CMD_ARGC
; i
++)
198 if (fwrite(CMD_ARGV
[i
], 1, strlen(CMD_ARGV
[i
]),
199 config_file
) != strlen(CMD_ARGV
[i
]))
201 if (i
!= CMD_ARGC
- 1)
203 if (fwrite(" ", 1, 1, config_file
) != 1)
207 if ((i
== CMD_ARGC
) && (fwrite("\n", 1, 1, config_file
) == 1))
218 COMMAND_HANDLER(handle_cp_command
)
222 return ERROR_COMMAND_SYNTAX_ERROR
;
225 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
229 int retval
= loadFile(CMD_ARGV
[0], &data
, &len
);
230 if (retval
!= ERROR_OK
)
233 FILE *f
= fopen(CMD_ARGV
[1], "wb");
235 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
240 size_t chunk
= len
- pos
;
241 static const size_t maxChunk
= 512 * 1024; // ~1/sec
242 if (chunk
> maxChunk
)
247 if ((retval
== ERROR_OK
) && (fwrite(((char *)data
) + pos
, 1, chunk
, f
) != chunk
))
248 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
250 if (retval
!= ERROR_OK
)
255 command_print(CMD_CTX
, "%zu", len
- pos
);
263 if (retval
== ERROR_OK
)
265 command_print(CMD_CTX
, "Copied %s to %s", CMD_ARGV
[0], CMD_ARGV
[1]);
268 command_print(CMD_CTX
, "copy failed");
276 if (retval
!= ERROR_OK
)
285 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
288 void copyfile(char *name2
, char *name1
)
296 fd1
= open(name1
, O_WRONLY
| O_CREAT
, 0664);
298 SHOW_RESULT(open
, fd1
);
300 fd2
= open(name2
, O_RDONLY
);
302 SHOW_RESULT(open
, fd2
);
306 done
= read(fd2
, buf
, IOSIZE
);
309 SHOW_RESULT(read
, done
);
313 if (done
== 0) break;
315 wrote
= write(fd1
, buf
, done
);
316 if (wrote
!= done
) SHOW_RESULT(write
, wrote
);
318 if (wrote
!= done
) break;
322 if (err
< 0) SHOW_RESULT(close
, err
);
325 if (err
< 0) SHOW_RESULT(close
, err
);
329 /* utility fn to copy a directory */
330 void copydir(char *name
, char *destdir
)
335 dirp
= opendir(destdir
);
338 mkdir(destdir
, 0777);
341 err
= closedir(dirp
);
344 dirp
= opendir(name
);
345 if (dirp
== NULL
) SHOW_RESULT(opendir
, -1);
349 struct dirent
*entry
= readdir(dirp
);
354 if (strcmp(entry
->d_name
, ".") == 0)
356 if (strcmp(entry
->d_name
, "..") == 0)
361 char fullPath
[PATH_MAX
];
362 strncpy(fullPath
, name
, PATH_MAX
);
363 strcat(fullPath
, "/");
364 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
366 if (stat(fullPath
, &buf
) == -1)
368 LOG_ERROR("unable to read status from %s", fullPath
);
371 isDir
= S_ISDIR(buf
.st_mode
) != 0;
376 // diag_printf("<INFO>: entry %14s",entry->d_name);
377 char fullname
[PATH_MAX
];
378 char fullname2
[PATH_MAX
];
380 strcpy(fullname
, name
);
381 strcat(fullname
, "/");
382 strcat(fullname
, entry
->d_name
);
384 strcpy(fullname2
, destdir
);
385 strcat(fullname2
, "/");
386 strcat(fullname2
, entry
->d_name
);
387 // diag_printf("from %s to %s\n", fullname, fullname2);
388 copyfile(fullname
, fullname2
);
390 // diag_printf("\n");
393 err
= closedir(dirp
);
394 if (err
< 0) SHOW_RESULT(stat
, err
);
400 COMMAND_HANDLER(handle_rm_command
)
403 return ERROR_COMMAND_SYNTAX_ERROR
;
406 if (rmdir(CMD_ARGV
[0]) == 0)
408 else if (unlink(CMD_ARGV
[0]) == 0)
411 return del
? ERROR_OK
: ERROR_FAIL
;
416 ioutil_Jim_Command_ls(Jim_Interp
*interp
,
418 Jim_Obj
* const *argv
)
422 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
426 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
429 dirp
= opendir(name
);
434 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
438 struct dirent
*entry
= NULL
;
439 entry
= readdir(dirp
);
443 if ((strcmp(".", entry
->d_name
) == 0)||(strcmp("..", entry
->d_name
) == 0))
446 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
450 Jim_SetResult(interp
, objPtr
);
456 ioutil_Jim_Command_peek(Jim_Interp
*interp
,
458 Jim_Obj
* const *argv
)
462 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
467 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
470 int value
= *((volatile int *) address
);
472 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
478 ioutil_Jim_Command_poke(Jim_Interp
*interp
,
480 Jim_Obj
* const *argv
)
484 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
489 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
492 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
495 *((volatile int *) address
) = value
;
501 /* not so pretty code to fish out ip number*/
502 static int ioutil_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
503 Jim_Obj
* const *argv
)
505 #if !defined(__CYGWIN__)
506 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
508 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
510 if (getifaddrs(&ifp
) < 0)
515 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
520 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
521 salen
= sizeof(struct sockaddr_in
);
522 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
523 salen
= sizeof(struct sockaddr_in6
);
527 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
533 Jim_AppendString(interp
, tclOutput
, ip
, strlen(ip
));
540 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "fixme!!!", 0);
541 LOG_ERROR("NOT IMPLEMENTED!!!");
543 Jim_SetResult(interp
, tclOutput
);
548 /* not so pretty code to fish out eth0 mac address */
549 static int ioutil_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
550 Jim_Obj
* const *argv
)
554 struct ifreq
*ifr
, *ifend
;
560 SockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
566 ifc
.ifc_len
= sizeof(ifs
);
568 if (ioctl(SockFD
, SIOCGIFCONF
, &ifc
) < 0)
574 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
575 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
577 //if (ifr->ifr_addr.sa_family == AF_INET)
579 if (strcmp("eth0", ifr
->ifr_name
) != 0)
581 strncpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
582 if (ioctl(SockFD
, SIOCGIFHWADDR
, &ifreq
) < 0)
591 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
594 sprintf(buffer
, "%02x-%02x-%02x-%02x-%02x-%02x",
595 ifreq
.ifr_hwaddr
.sa_data
[0]&0xff,
596 ifreq
.ifr_hwaddr
.sa_data
[1]&0xff,
597 ifreq
.ifr_hwaddr
.sa_data
[2]&0xff,
598 ifreq
.ifr_hwaddr
.sa_data
[3]&0xff,
599 ifreq
.ifr_hwaddr
.sa_data
[4]&0xff,
600 ifreq
.ifr_hwaddr
.sa_data
[5]&0xff);
602 Jim_AppendString(interp
, tclOutput
, buffer
, strlen(buffer
));
604 Jim_SetResult(interp
, tclOutput
);
615 static const struct command_registration ioutil_command_handlers
[] = {
618 .handler
= handle_cat_command
,
620 .help
= "display text file content",
625 .handler
= handle_trunc_command
,
627 .help
= "truncate a file to zero length",
632 .handler
= handle_cp_command
,
634 .help
= "copy a file",
635 .usage
= "src_file_name dst_file_name",
638 .name
= "append_file",
639 .handler
= handle_append_command
,
641 .help
= "append a variable number of strings to a file",
642 .usage
= "file_name [<string1>, [<string2>, ...]]",
646 .handler
= handle_meminfo_command
,
648 .help
= "display free heap space",
653 .handler
= handle_rm_command
,
654 .help
= "remove a directory or file",
655 .usage
= "file_name",
659 * Peek and poke are security holes -- they manipulate
660 * server-internal addresses.
667 .jim_handler
= ioutil_Jim_Command_peek
,
668 .help
= "peek at a memory address",
674 .jim_handler
= ioutil_Jim_Command_poke
,
675 .help
= "poke at a memory address",
676 .usage
= "address value",
681 .jim_handler
= ioutil_Jim_Command_ls
,
682 .help
= "show a listing of files",
688 .jim_handler
= ioutil_Jim_Command_mac
,
689 .help
= "show MAC address",
693 .jim_handler
= ioutil_Jim_Command_ip
,
695 .help
= "show IP address",
697 COMMAND_REGISTRATION_DONE
700 int ioutil_init(struct command_context
*cmd_ctx
)
702 return register_commands(cmd_ctx
, NULL
, ioutil_command_handlers
);
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)