delete unused code
[openocd.git] / src / helper / ioutil.c
1 /***************************************************************************
2 * Copyright (C) 2007-2008 by Øyvind Harboe *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
19
20 /* this file contains various functionality useful to standalone systems */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "log.h"
27 #include "time_support.h"
28
29 #ifdef HAVE_ARPA_INET_H
30 #include <arpa/inet.h>
31 #endif
32 #ifdef HAVE_DIRENT_H
33 #include <dirent.h>
34 #endif
35 #ifdef HAVE_NETDB_H
36 #include <netdb.h>
37 #endif
38 #ifdef HAVE_NET_IF_H
39 #include <net/if.h>
40 #endif
41 //#ifdef HAVE_NETINET_TCP_H
42 //#include <netinet/tcp.h>
43 //#endif
44 #ifdef HAVE_SYS_IOCTL_H
45 #include <sys/ioctl.h>
46 #endif
47 #ifdef HAVE_SYS_STAT_H
48 #include <sys/stat.h>
49 #endif
50 #ifdef HAVE_IFADDRS_H
51 #include <ifaddrs.h>
52 #endif
53 #ifdef HAVE_MALLOC_H
54 #if !BUILD_ECOSBOARD
55 #include <malloc.h>
56 #endif
57 #endif
58 //#ifdef HAVE_STRINGS_H
59 //#include <strings.h>
60 //#endif
61
62
63 int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
64 char **args, int argc)
65 {
66 if (argc != 1)
67 {
68 command_print(cmd_ctx, "rm <filename>");
69 return ERROR_INVALID_ARGUMENTS;
70 }
71
72 if (unlink(args[0]) != 0)
73 {
74 command_print(cmd_ctx, "failed: %d", errno);
75 }
76
77 return ERROR_OK;
78 }
79
80
81 /* loads a file and returns a pointer to it in memory. The file contains
82 * a 0 byte(sentinel) after len bytes - the length of the file. */
83 int loadFile(const char *fileName, void **data, size_t *len)
84 {
85 // ensure returned length is always sane
86 *len = 0;
87
88 FILE * pFile;
89 pFile = fopen(fileName,"rb");
90 if (pFile==NULL)
91 {
92 LOG_ERROR("Can't open %s\n", fileName);
93 return ERROR_FAIL;
94 }
95 if (fseek(pFile, 0, SEEK_END)!=0)
96 {
97 LOG_ERROR("Can't open %s\n", fileName);
98 fclose(pFile);
99 return ERROR_FAIL;
100 }
101 long fsize = ftell(pFile);
102 if (fsize == -1)
103 {
104 LOG_ERROR("Can't open %s\n", fileName);
105 fclose(pFile);
106 return ERROR_FAIL;
107 }
108 *len = fsize;
109
110 if (fseek(pFile, 0, SEEK_SET)!=0)
111 {
112 LOG_ERROR("Can't open %s\n", fileName);
113 fclose(pFile);
114 return ERROR_FAIL;
115 }
116 *data = malloc(*len + 1);
117 if (*data==NULL)
118 {
119 LOG_ERROR("Can't open %s\n", fileName);
120 fclose(pFile);
121 return ERROR_FAIL;
122 }
123
124 if (fread(*data, 1, *len, pFile)!=*len)
125 {
126 fclose(pFile);
127 free(*data);
128 LOG_ERROR("Can't open %s\n", fileName);
129 return ERROR_FAIL;
130 }
131 fclose(pFile);
132
133 // 0-byte after buffer (not included in *len) serves as a sentinel
134 char *buf = (char *)*data;
135 buf[*len] = 0;
136
137 return ERROR_OK;
138 }
139
140
141
142 int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
143 char **args, int argc)
144 {
145 if (argc != 1)
146 {
147 command_print(cmd_ctx, "cat <filename>");
148 return ERROR_INVALID_ARGUMENTS;
149 }
150
151 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
152 void *data;
153 size_t len;
154
155 int retval = loadFile(args[0], &data, &len);
156 if (retval == ERROR_OK)
157 {
158 command_print(cmd_ctx, "%s", (char *)data);
159 free(data);
160 }
161 else
162 {
163 command_print(cmd_ctx, "%s not found %d", args[0], retval);
164 }
165
166 return ERROR_OK;
167 }
168 int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
169 char **args, int argc)
170 {
171 if (argc != 1)
172 {
173 command_print(cmd_ctx, "trunc <filename>");
174 return ERROR_INVALID_ARGUMENTS;
175 }
176
177 FILE *config_file = NULL;
178 config_file = fopen(args[0], "w");
179 if (config_file != NULL)
180 fclose(config_file);
181
182 return ERROR_OK;
183 }
184
185
186 int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
187 {
188 static int prev = 0;
189 struct mallinfo info;
190
191 if (argc != 0)
192 {
193 command_print(cmd_ctx, "meminfo");
194 return ERROR_INVALID_ARGUMENTS;
195 }
196
197 info = mallinfo();
198
199 if (prev > 0)
200 {
201 command_print(cmd_ctx, "Diff: %d", prev - info.fordblks);
202 }
203 prev = info.fordblks;
204
205 command_print(cmd_ctx, "Available ram: %d", info.fordblks );
206
207 return ERROR_OK;
208 }
209
210
211 int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
212 char **args, int argc)
213 {
214 if (argc < 1)
215 {
216 command_print(cmd_ctx,
217 "append <filename> [<string1>, [<string2>, ...]]");
218 return ERROR_INVALID_ARGUMENTS;
219 }
220
221 int retval=ERROR_FAIL;
222 FILE *config_file = NULL;
223 config_file = fopen(args[0], "a");
224 if (config_file != NULL)
225 {
226 int i;
227 fseek(config_file, 0, SEEK_END);
228
229 for (i = 1; i < argc; i++)
230 {
231 if (fwrite(args[i], strlen(args[i]), 1, config_file)!=strlen(args[i]))
232 break;
233 if (i != argc - 1)
234 {
235 if (fwrite(" ", 1, 1, config_file)!=1)
236 break;
237 }
238 }
239 if ((i==argc)&&(fwrite("\n", 1, 1, config_file)==1))
240 {
241 retval=ERROR_OK;
242 }
243 fclose(config_file);
244 }
245
246 return retval;
247 }
248
249
250
251 int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
252 {
253 if (argc != 2)
254 {
255 return ERROR_INVALID_ARGUMENTS;
256 }
257
258 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
259 void *data;
260 size_t len;
261
262 int retval = loadFile(args[0], &data, &len);
263 if (retval != ERROR_OK)
264 return retval;
265
266 FILE *f = fopen(args[1], "wb");
267 if (f == NULL)
268 retval = ERROR_INVALID_ARGUMENTS;
269
270 size_t pos = 0;
271 for (;;)
272 {
273 size_t chunk = len - pos;
274 static const size_t maxChunk = 512 * 1024; // ~1/sec
275 if (chunk > maxChunk)
276 {
277 chunk = maxChunk;
278 }
279
280 if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
281 retval = ERROR_INVALID_ARGUMENTS;
282
283 if (retval != ERROR_OK)
284 {
285 break;
286 }
287
288 command_print(cmd_ctx, "%d", len - pos);
289
290 pos += chunk;
291
292 if (pos == len)
293 break;
294 }
295
296 if (retval == ERROR_OK)
297 {
298 command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
299 } else
300 {
301 command_print(cmd_ctx, "Failed: %d", retval);
302 }
303
304 if (data != NULL)
305 free(data);
306 if (f != NULL)
307 fclose(f);
308
309 if (retval != ERROR_OK)
310 unlink(args[1]);
311
312 return retval;
313 }
314
315
316
317
318 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
319
320 #define IOSIZE 512
321 void copyfile(char *name2, char *name1)
322 {
323
324 int err;
325 char buf[IOSIZE];
326 int fd1, fd2;
327 ssize_t done, wrote;
328
329 fd1 = open(name1, O_WRONLY | O_CREAT);
330 if (fd1 < 0)
331 SHOW_RESULT( open, fd1 );
332
333 fd2 = open(name2, O_RDONLY);
334 if (fd2 < 0)
335 SHOW_RESULT( open, fd2 );
336
337 for (;;)
338 {
339 done = read(fd2, buf, IOSIZE );
340 if (done < 0)
341 {
342 SHOW_RESULT( read, done );
343 break;
344 }
345
346 if( done == 0 ) break;
347
348 wrote = write(fd1, buf, done);
349 if( wrote != done ) SHOW_RESULT( write, wrote );
350
351 if( wrote != done ) break;
352 }
353
354 err = close(fd1);
355 if( err < 0 ) SHOW_RESULT( close, err );
356
357 err = close(fd2);
358 if( err < 0 ) SHOW_RESULT( close, err );
359
360 }
361
362 /* utility fn to copy a directory */
363 void copydir(char *name, char *destdir)
364 {
365 int err;
366 DIR *dirp;
367
368 dirp = opendir(destdir);
369 if (dirp==NULL)
370 {
371 mkdir(destdir, 0777);
372 } else
373 {
374 err = closedir(dirp);
375 }
376
377 dirp = opendir(name);
378 if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
379
380 for (;;)
381 {
382 struct dirent *entry = readdir(dirp);
383
384 if (entry == NULL)
385 break;
386
387 if (strcmp(entry->d_name, ".") == 0)
388 continue;
389 if (strcmp(entry->d_name, "..") == 0)
390 continue;
391
392 int isDir = 0;
393 struct stat buf;
394 char fullPath[PATH_MAX];
395 strncpy(fullPath, name, PATH_MAX);
396 strcat(fullPath, "/");
397 strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
398
399 if (stat(fullPath, &buf) == -1)
400 {
401 LOG_ERROR("unable to read status from %s", fullPath);
402 break;
403 }
404 isDir = S_ISDIR(buf.st_mode) != 0;
405
406 if (isDir)
407 continue;
408
409 // diag_printf("<INFO>: entry %14s",entry->d_name);
410 char fullname[PATH_MAX];
411 char fullname2[PATH_MAX];
412
413 strcpy(fullname, name);
414 strcat(fullname, "/");
415 strcat(fullname, entry->d_name);
416
417 strcpy(fullname2, destdir);
418 strcat(fullname2, "/");
419 strcat(fullname2, entry->d_name);
420 // diag_printf("from %s to %s\n", fullname, fullname2);
421 copyfile(fullname, fullname2);
422
423 // diag_printf("\n");
424 }
425
426 err = closedir(dirp);
427 if( err < 0 ) SHOW_RESULT( stat, err );
428 }
429
430
431
432
433 static int
434 zylinjtag_Jim_Command_rm(Jim_Interp *interp,
435 int argc,
436 Jim_Obj * const *argv)
437 {
438 int del;
439 if (argc != 2)
440 {
441 Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
442 return JIM_ERR;
443 }
444
445 del = 0;
446 if (unlink(Jim_GetString(argv[1], NULL)) == 0)
447 del = 1;
448 if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
449 del = 1;
450
451 return del ? JIM_OK : JIM_ERR;
452 }
453
454
455 static int
456 zylinjtag_Jim_Command_ls(Jim_Interp *interp,
457 int argc,
458 Jim_Obj * const *argv)
459 {
460 if (argc != 2)
461 {
462 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
463 return JIM_ERR;
464 }
465
466 char *name = (char*) Jim_GetString(argv[1], NULL);
467
468 DIR *dirp = NULL;
469 dirp = opendir(name);
470 if (dirp == NULL)
471 {
472 return JIM_ERR;
473 }
474 Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
475
476 for (;;)
477 {
478 struct dirent *entry = NULL;
479 entry = readdir(dirp);
480 if (entry == NULL)
481 break;
482
483 if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
484 continue;
485
486 Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
487 }
488 closedir(dirp);
489
490 Jim_SetResult(interp, objPtr);
491
492 return JIM_OK;
493 }
494
495 static int
496 zylinjtag_Jim_Command_peek(Jim_Interp *interp,
497 int argc,
498 Jim_Obj * const *argv)
499 {
500 if (argc != 2)
501 {
502 Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
503 return JIM_ERR;
504 }
505
506 long address;
507 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
508 return JIM_ERR;
509
510 int value = *((volatile int *) address);
511
512 Jim_SetResult(interp, Jim_NewIntObj(interp, value));
513
514 return JIM_OK;
515 }
516
517 static int
518 zylinjtag_Jim_Command_poke(Jim_Interp *interp,
519 int argc,
520 Jim_Obj * const *argv)
521 {
522 if (argc != 3)
523 {
524 Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
525 return JIM_ERR;
526 }
527
528 long address;
529 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
530 return JIM_ERR;
531 long value;
532 if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
533 return JIM_ERR;
534
535 *((volatile int *) address) = value;
536
537 return JIM_OK;
538 }
539
540
541 /* not so pretty code to fish out ip number*/
542 static int zylinjtag_Jim_Command_ip(Jim_Interp *interp, int argc,
543 Jim_Obj * const *argv)
544 {
545 #if !defined(__CYGWIN__)
546 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
547
548 struct ifaddrs *ifa = NULL, *ifp = NULL;
549
550 if (getifaddrs(&ifp) < 0)
551 {
552 return JIM_ERR;
553 }
554
555 for (ifa = ifp; ifa; ifa = ifa->ifa_next)
556 {
557 char ip[200];
558 socklen_t salen;
559
560 if (ifa->ifa_addr->sa_family == AF_INET)
561 salen = sizeof(struct sockaddr_in);
562 else if (ifa->ifa_addr->sa_family == AF_INET6)
563 salen = sizeof(struct sockaddr_in6);
564 else
565 continue;
566
567 if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
568 NI_NUMERICHOST) < 0)
569 {
570 continue;
571 }
572
573 Jim_AppendString(interp, tclOutput, ip, strlen(ip));
574 break;
575
576 }
577
578 freeifaddrs(ifp);
579 #else
580 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "fixme!!!", 0);
581 LOG_ERROR("NOT IMPLEMENTED!!!");
582 #endif
583 Jim_SetResult(interp, tclOutput);
584
585 return JIM_OK;
586 }
587
588 /* not so pretty code to fish out eth0 mac address */
589 static int zylinjtag_Jim_Command_mac(Jim_Interp *interp, int argc,
590 Jim_Obj * const *argv)
591 {
592
593
594 struct ifreq *ifr, *ifend;
595 struct ifreq ifreq;
596 struct ifconf ifc;
597 struct ifreq ifs[5];
598 int SockFD;
599
600 SockFD = socket(AF_INET, SOCK_DGRAM, 0);
601 if (SockFD < 0)
602 {
603 return JIM_ERR;
604 }
605
606 ifc.ifc_len = sizeof(ifs);
607 ifc.ifc_req = ifs;
608 if (ioctl(SockFD, SIOCGIFCONF, &ifc) < 0)
609 {
610 close(SockFD);
611 return JIM_ERR;
612 }
613
614 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
615 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
616 {
617 //if (ifr->ifr_addr.sa_family == AF_INET)
618 {
619 if (strcmp("eth0", ifr->ifr_name)!=0)
620 continue;
621 strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
622 if (ioctl(SockFD, SIOCGIFHWADDR, &ifreq) < 0)
623 {
624 close(SockFD);
625 return JIM_ERR;
626 }
627
628 close(SockFD);
629
630
631 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
632
633 char buffer[256];
634 sprintf(buffer, "%02x-%02x-%02x-%02x-%02x-%02x",
635 ifreq.ifr_hwaddr.sa_data[0]&0xff,
636 ifreq.ifr_hwaddr.sa_data[1]&0xff,
637 ifreq.ifr_hwaddr.sa_data[2]&0xff,
638 ifreq.ifr_hwaddr.sa_data[3]&0xff,
639 ifreq.ifr_hwaddr.sa_data[4]&0xff,
640 ifreq.ifr_hwaddr.sa_data[5]&0xff);
641
642 Jim_AppendString(interp, tclOutput, buffer, strlen(buffer));
643
644 Jim_SetResult(interp, tclOutput);
645
646 return JIM_OK;
647 }
648 }
649 close(SockFD);
650
651 return JIM_ERR;
652
653 }
654
655
656
657 int ioutil_init(struct command_context_s *cmd_ctx)
658 {
659 register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
660 "remove file");
661
662 register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
663 "display file content");
664
665 register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
666 "truncate a file to 0 size");
667
668 register_command(cmd_ctx, NULL, "cp", handle_cp_command,
669 COMMAND_ANY, "copy a file <from> <to>");
670
671 register_command(cmd_ctx, NULL, "append_file", handle_append_command,
672 COMMAND_ANY, "append a variable number of strings to a file");
673
674 register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
675 COMMAND_ANY, "display available ram memory");
676
677 Jim_CreateCommand(interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
678
679 Jim_CreateCommand(interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);
680 Jim_CreateCommand(interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);
681 Jim_CreateCommand(interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);
682
683 Jim_CreateCommand(interp, "mac", zylinjtag_Jim_Command_mac,
684 NULL, NULL);
685
686 Jim_CreateCommand(interp, "ip", zylinjtag_Jim_Command_ip,
687 NULL, NULL);
688
689 return ERROR_OK;
690 }
691
692

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)