]> git.sur5r.net Git - openocd/blob - src/helper/ioutil.c
- add missing svn props from r1243 commit
[openocd] / 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 "types.h"
28 #include "configuration.h"
29 #include "target.h"
30
31 #include "command.h"
32
33 #include <time_support.h>
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #include <strings.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #if !BUILD_ECOSBOARD
42 #include <malloc.h>
43 #endif
44 #include <errno.h>
45
46
47 #include <fcntl.h>
48 #include <sys/stat.h>
49 #include <dirent.h>
50 #include <netinet/tcp.h>
51 #include <sys/ioctl.h>
52 #include <sys/socket.h>
53 #include <netinet/in.h>
54 #include <net/if.h>
55 #include <arpa/inet.h>
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <netdb.h>
59 #include <netinet/in.h>
60 #include <unistd.h>
61 #include <arpa/inet.h>
62 #include <stdio.h>
63 #include <string.h>
64
65
66 #include <unistd.h>
67 #include <stdio.h>
68
69 int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
70                 char **args, int argc)
71 {
72         if (argc != 1)
73         {
74                 command_print(cmd_ctx, "rm <filename>");
75                 return ERROR_INVALID_ARGUMENTS;
76         }
77
78         if (unlink(args[0]) != 0)
79         {
80                 command_print(cmd_ctx, "failed: %d", errno);
81         }
82
83         return ERROR_OK;
84 }
85
86
87 /* loads a file and returns a pointer to it in memory. The file contains
88  * a 0 byte(sentinel) after len bytes - the length of the file. */
89 int loadFile(const char *fileName, void **data, int *len)
90 {
91         FILE * pFile;
92         pFile = fopen(fileName,"rb");
93         if (pFile==NULL)
94         {
95                 LOG_ERROR("Can't open %s\n", fileName);
96                 return ERROR_FAIL;
97         }
98         if (fseek(pFile, 0, SEEK_END)!=0)
99         {
100                 LOG_ERROR("Can't open %s\n", fileName);
101                 fclose(pFile);
102                 return ERROR_FAIL;
103         }
104         *len=ftell(pFile);
105         if (*len==-1)
106         {
107                 LOG_ERROR("Can't open %s\n", fileName);
108                 fclose(pFile);
109                 return ERROR_FAIL;
110         }
111
112         if (fseek(pFile, 0, SEEK_SET)!=0)
113         {
114                 LOG_ERROR("Can't open %s\n", fileName);
115                 fclose(pFile);
116                 return ERROR_FAIL;
117         }
118         *data=malloc(*len+1);
119         if (*data==NULL)
120         {
121                 LOG_ERROR("Can't open %s\n", fileName);
122                 fclose(pFile);
123                 return ERROR_FAIL;
124         }
125
126         if (fread(*data, 1, *len, pFile)!=*len)
127         {
128                 fclose(pFile);
129                 free(*data);
130                 LOG_ERROR("Can't open %s\n", fileName);
131                 return ERROR_FAIL;
132         }
133         fclose(pFile);
134         *(((char *)(*data))+*len)=0; /* sentinel */
135
136         return ERROR_OK;
137
138
139
140 }
141
142
143
144 int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
145                 char **args, int argc)
146 {
147         if (argc != 1)
148         {
149                 command_print(cmd_ctx, "cat <filename>");
150                 return ERROR_INVALID_ARGUMENTS;
151         }
152
153         // NOTE!!! we only have line printing capability so we print the entire file as a single line.
154         void *data;
155         int len;
156
157         int retval = loadFile(args[0], &data, &len);
158         if (retval == ERROR_OK)
159         {
160                 command_print(cmd_ctx, "%s", data);
161                 free(data);
162         }
163         else
164         {
165                 command_print(cmd_ctx, "%s not found %d", args[0], retval);
166         }
167
168         return ERROR_OK;
169 }
170 int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
171                 char **args, int argc)
172 {
173         if (argc != 1)
174         {
175                 command_print(cmd_ctx, "trunc <filename>");
176                 return ERROR_INVALID_ARGUMENTS;
177         }
178
179         FILE *config_file = NULL;
180         config_file = fopen(args[0], "w");
181         if (config_file != NULL)
182                 fclose(config_file);
183
184         return ERROR_OK;
185 }
186
187
188 int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
189 {
190         static int prev = 0;
191         struct mallinfo info;
192
193         if (argc != 0)
194         {
195                 command_print(cmd_ctx, "meminfo");
196                 return ERROR_INVALID_ARGUMENTS;
197         }
198
199         info = mallinfo();
200
201         if (prev > 0)
202         {
203                 command_print(cmd_ctx, "Diff:            %d", prev - info.fordblks);
204         }
205         prev = info.fordblks;
206
207         command_print(cmd_ctx, "Available ram:   %d", info.fordblks );
208
209         return ERROR_OK;
210 }
211
212
213 int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
214                 char **args, int argc)
215 {
216         if (argc < 1)
217         {
218                 command_print(cmd_ctx,
219                                 "append <filename> [<string1>, [<string2>, ...]]");
220                 return ERROR_INVALID_ARGUMENTS;
221         }
222
223         FILE *config_file = NULL;
224         config_file = fopen(args[0], "a");
225         if (config_file != NULL)
226         {
227                 int i;
228                 fseek(config_file, 0, SEEK_END);
229
230                 for (i = 1; i < argc; i++)
231                 {
232                         fwrite(args[i], strlen(args[i]), 1, config_file);
233                         if (i != argc - 1)
234                         {
235                                 fwrite(" ", 1, 1, config_file);
236                         }
237                 }
238                 fwrite("\n", 1, 1, config_file);
239                 fclose(config_file);
240         }
241
242         return ERROR_OK;
243 }
244
245
246
247 int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
248 {
249         if (argc != 2)
250         {
251                 return ERROR_INVALID_ARGUMENTS;
252         }
253
254         // NOTE!!! we only have line printing capability so we print the entire file as a single line.
255         void *data;
256         int len;
257
258         int retval = loadFile(args[0], &data, &len);
259         if (retval != ERROR_OK)
260                 return retval;
261
262         FILE *f = fopen(args[1], "wb");
263         if (f == NULL)
264                 retval = ERROR_INVALID_ARGUMENTS;
265
266         int pos = 0;
267         for (;;)
268         {
269                 int chunk = len - pos;
270                 static const int maxChunk = 512 * 1024; // ~1/sec
271                 if (chunk > maxChunk)
272                 {
273                         chunk = maxChunk;
274                 }
275
276                 if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
277                         retval = ERROR_INVALID_ARGUMENTS;
278
279                 if (retval != ERROR_OK)
280                 {
281                         break;
282                 }
283
284                 command_print(cmd_ctx, "%d", len - pos);
285
286                 pos += chunk;
287
288                 if (pos == len)
289                         break;
290         }
291
292         if (retval == ERROR_OK)
293         {
294                 command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
295         } else
296         {
297                 command_print(cmd_ctx, "Failed: %d", retval);
298         }
299
300         if (data != NULL)
301                 free(data);
302         if (f != NULL)
303                 fclose(f);
304
305         if (retval != ERROR_OK)
306                 unlink(args[1]);
307
308         return retval;
309 }
310
311
312
313
314 #define SHOW_RESULT(a, b) LOG_ERROR(#a " failed %d\n", (int)b)
315
316 #define IOSIZE 512
317 void copyfile(char *name2, char *name1)
318 {
319
320         int err;
321         char buf[IOSIZE];
322         int fd1, fd2;
323         ssize_t done, wrote;
324
325         fd1 = open(name1, O_WRONLY | O_CREAT);
326         if (fd1 < 0)
327                 SHOW_RESULT( open, fd1 );
328
329         fd2 = open(name2, O_RDONLY);
330         if (fd2 < 0)
331                 SHOW_RESULT( open, fd2 );
332
333         for (;;)
334         {
335                 done = read(fd2, buf, IOSIZE );
336                 if (done < 0)
337                 {
338                         SHOW_RESULT( read, done );
339                         break;
340                 }
341
342         if( done == 0 ) break;
343
344                 wrote = write(fd1, buf, done);
345         if( wrote != done ) SHOW_RESULT( write, wrote );
346
347         if( wrote != done ) break;
348         }
349
350         err = close(fd1);
351     if( err < 0 ) SHOW_RESULT( close, err );
352
353         err = close(fd2);
354     if( err < 0 ) SHOW_RESULT( close, err );
355
356 }
357
358 /* utility fn to copy a directory */
359 void copydir(char *name, char *destdir)
360 {
361         int err;
362         DIR *dirp;
363
364         dirp = opendir(destdir);
365         if (dirp==NULL)
366         {
367                 mkdir(destdir, 0777);
368         } else
369         {
370                 err = closedir(dirp);
371         }
372
373         dirp = opendir(name);
374     if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
375
376         for (;;)
377         {
378                 struct dirent *entry = readdir(dirp);
379
380                 if (entry == NULL)
381                         break;
382
383                 if (strcmp(entry->d_name, ".") == 0)
384                         continue;
385                 if (strcmp(entry->d_name, "..") == 0)
386                         continue;
387
388                 int isDir = 0;
389                 struct stat buf;
390                 char fullPath[PATH_MAX];
391                 strncpy(fullPath, name, PATH_MAX);
392                 strcat(fullPath, "/");
393                 strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
394
395                 if (stat(fullPath, &buf) == -1)
396                 {
397                         LOG_ERROR("unable to read status from %s", fullPath);
398                         break;
399                 }
400                 isDir = S_ISDIR(buf.st_mode) != 0;
401
402                 if (isDir)
403                         continue;
404
405                 //        diag_printf("<INFO>: entry %14s",entry->d_name);
406                 char fullname[PATH_MAX];
407                 char fullname2[PATH_MAX];
408
409                 strcpy(fullname, name);
410                 strcat(fullname, "/");
411                 strcat(fullname, entry->d_name);
412
413                 strcpy(fullname2, destdir);
414                 strcat(fullname2, "/");
415                 strcat(fullname2, entry->d_name);
416                 //        diag_printf("from %s to %s\n", fullname, fullname2);
417                 copyfile(fullname, fullname2);
418
419                 //       diag_printf("\n");
420         }
421
422         err = closedir(dirp);
423     if( err < 0 ) SHOW_RESULT( stat, err );
424 }
425
426
427
428
429 static int
430 zylinjtag_Jim_Command_rm(Jim_Interp *interp,
431                                    int argc,
432                 Jim_Obj * const *argv)
433 {
434         int del;
435         if (argc != 2)
436         {
437                 Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
438                 return JIM_ERR;
439         }
440
441         del = 0;
442         if (unlink(Jim_GetString(argv[1], NULL)) == 0)
443                 del = 1;
444         if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
445                 del = 1;
446
447         return del ? JIM_OK : JIM_ERR;
448 }
449
450
451 static int
452 zylinjtag_Jim_Command_ls(Jim_Interp *interp,
453                                    int argc,
454                 Jim_Obj * const *argv)
455 {
456         if (argc != 2)
457         {
458                 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
459                 return JIM_ERR;
460         }
461
462         char *name = (char*) Jim_GetString(argv[1], NULL);
463
464         DIR *dirp = NULL;
465         dirp = opendir(name);
466         if (dirp == NULL)
467         {
468                 return JIM_ERR;
469         }
470         Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
471
472         for (;;)
473         {
474                 struct dirent *entry = NULL;
475                 entry = readdir(dirp);
476                 if (entry == NULL)
477                         break;
478
479                 if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
480                         continue;
481
482         Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
483         }
484         closedir(dirp);
485
486         Jim_SetResult(interp, objPtr);
487
488         return JIM_OK;
489 }
490
491 int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
492 {
493         if (argc != 1)
494         {
495                 return ERROR_COMMAND_SYNTAX_ERROR;
496         }
497         volatile int *address=(volatile int *)strtoul(args[0], NULL, 0);
498         int value=*address;
499         command_print(cmd_ctx, "0x%x : 0x%x", address, value);
500         return ERROR_OK;
501 }
502
503 int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
504 {
505         if (argc != 2)
506         {
507                 return ERROR_INVALID_ARGUMENTS;
508         }
509         volatile int *address=(volatile int *)strtoul(args[0], NULL, 0);
510         int value=strtoul(args[1], NULL, 0);
511         *address=value;
512         return ERROR_OK;
513 }
514
515 static int
516 zylinjtag_Jim_Command_peek(Jim_Interp *interp,
517                                    int argc,
518                 Jim_Obj * const *argv)
519 {
520         if (argc != 2)
521         {
522                 Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
523                 return JIM_ERR;
524         }
525
526         long address;
527         if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
528                 return JIM_ERR;
529
530         int value = *((volatile int *) address);
531
532         Jim_SetResult(interp, Jim_NewIntObj(interp, value));
533
534         return JIM_OK;
535 }
536
537 static int
538 zylinjtag_Jim_Command_poke(Jim_Interp *interp,
539                                    int argc,
540                 Jim_Obj * const *argv)
541 {
542         if (argc != 3)
543         {
544                 Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
545                 return JIM_ERR;
546         }
547
548         long address;
549         if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
550                 return JIM_ERR;
551         long value;
552         if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
553                 return JIM_ERR;
554
555         *((volatile int *) address) = value;
556
557         return JIM_OK;
558 }
559
560 int ioutil_init(struct command_context_s *cmd_ctx)
561 {
562         register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
563                         "remove file");
564
565         register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
566                         "display file content");
567
568         register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
569                         "truncate a file to 0 size");
570
571         register_command(cmd_ctx, NULL, "cp", handle_cp_command,
572                                          COMMAND_ANY, "copy a file <from> <to>");
573
574         register_command(cmd_ctx, NULL, "append_file", handle_append_command,
575                         COMMAND_ANY, "append a variable number of strings to a file");
576
577         register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
578                         COMMAND_ANY, "display available ram memory");
579
580     Jim_CreateCommand(interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
581
582     Jim_CreateCommand(interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);
583     Jim_CreateCommand(interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);
584     Jim_CreateCommand(interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);
585
586
587     return ERROR_OK;
588 }
589
590