2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "gnashconfig.h"
23 #include "GnashSystemIOHeaders.h" // write()
26 #include <sys/types.h>
35 extern int optind
, getopt(int, char *const *, const char *);
40 #include <sys/types.h>
41 #if !defined(HAVE_WINSOCK_H) && !defined(__riscos__) && !defined(__OS2__) && !defined(__amigaos4__)
45 #elif !defined(__riscos__) && !defined(__OS2__) && !defined(__amigaos4__)
55 #if defined(__STDC_HOSTED__) || !defined(__GNUC__)
74 using namespace gnash
;
76 #ifdef BOOST_NO_EXCEPTIONS
80 void throw_exception(std::exception
const & e
)
87 // #error "No supported shared memory type for this platform"
89 static void usage (void);
90 void dump_ctrl(void *ptr
);
91 void dump_shm(bool convert
, bool out
);
94 const int PIDSTART
= 20000;
95 const int PIDEND
= 23000;
96 const int LINELEN
= 80;
97 const unsigned int LOOPCNT
= 5;
98 const int DEFAULT_SHM_SIZE
= 64528;
101 const int SHM_STAT
= 13;
102 const int SHM_INFO
= 14;
106 gnash::LogFile
& dbglogfile
= gnash::LogFile::getDefaultInstance();
107 gnash::RcInitFile
& rcfile
= gnash::RcInitFile::getDefaultInstance();
110 const char *DUMPSHM_VERSION
= "0.5";
113 main(int argc
, char *argv
[])
116 bool listfiles
= false;
118 bool convert
= false;
120 string filespec
, realname
, tmpname
;
121 vector
<const char *> dirlist
;
123 // Enable native language support, i.e. internationalization
125 std::setlocale (LC_ALL
, "");
126 bindtextdomain (PACKAGE
, LOCALEDIR
);
127 textdomain (PACKAGE
);
129 // scan for the two main standard GNU options
130 for (c
= 0; c
< argc
; c
++) {
131 if (strcmp("--help", argv
[c
]) == 0) {
135 if (strcmp("--version", argv
[c
]) == 0) {
136 printf (_("Gnash dumpshm version: %s, Gnash version: %s\n"),
137 DUMPSHM_VERSION
, VERSION
);
142 while ((c
= getopt (argc
, argv
, "hircv")) != -1) {
164 // turn on verbosity for the libraries
165 dbglogfile
.setVerbosity();
175 // If no command line arguments have been supplied, do nothing but
176 // print the usage message.
182 #if defined(USE_SYSV_SHM) && defined(HAVE_IPC_INFO)
183 // Just list the shared memory segments
184 if (listfiles
&& sysv
) {
190 if (optind
<= argc
- 1) {
191 if (*argv
[optind
] == '-') {
197 if (filespec
== "-") {
198 dump_shm(convert
, true);
200 dump_shm(convert
, false);
207 size
= DEFAULT_SHM_SIZE
;
210 // get the file name from the command line
212 filespec
= argv
[optind
];
214 log_debug(_("Will use \"%s\" for memory segment file"), filespec
);
220 // Dump the older style SYS V shared memory segments
222 dump_shm(bool convert
, bool out
)
224 // These are here for debugging purposes. It
227 key_t key
= rcfile
.getLCShmKey();
230 log_debug(_("No LcShmKey set in ~/.gnashrc, trying to find it ourselves"));
231 #if defined(USE_SYSV_SHM) && defined(HAVE_IPC_INFO)
236 int size
= 64528; // 1007 bytes less than unsigned
239 log_debug(_("No shared memory segments found!"));
242 if (dbglogfile
.getVerbosity()) {
243 log_debug(_("Existing SHM Key is: %s, Size is: %s"),
244 boost::io::group(hex
, showbase
, key
), size
);
251 // If the -c convert options was specified, dump the memory segment to disk.
252 // This makes it easy to store them as well as to examine them in great detail.
254 int fd
= open("segment.raw",O_WRONLY
|O_CREAT
, S_IRWXU
);
258 log_debug(_("Writing memory segment to disk: \"segment.raw\""));
259 shmaddr
= lc
.getAddr();
260 write(fd
, shmaddr
, size
);
263 log_debug(_("The data is: 0x%s"), hexify((uint8_t *)shmaddr
, size
, false));
273 #if defined(USE_SYSV_SHM) && defined(HAVE_IPC_INFO)
277 int maxid
, shmid
, id
;
278 struct shmid_ds shmseg
;
280 // #ifdef USE_POSIX_SHM
281 // if (library_dir != NULL) {
282 // for (i=0; entry>0; i++) {
283 // entry = readdir(library_dir);
284 // if (entry != NULL) {
285 // cout << "Found segment: " << entry->d_name << endl;
289 // cout << _("Sorry, we can only list the files on systems with"
290 // " disk based shared memory") << endl;
294 // If we're using SYSV shared memory, we can get a list of shared memory segments.
295 // By examing the size of each one, we can make a reasonable guess if it's one
296 // used for flash. As permissions apply, this will only list the segments created
297 // by the user running dumpshm.
298 // struct shm_info shm_info;
299 // maxid = shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
300 struct shmid_ds shm_info
;
301 maxid
= shmctl(0, SHM_INFO
, &shm_info
);
303 log_debug(_("kernel not configured for shared memory"));
307 // struct shminfo shminfo;
308 if ((shmctl(0, IPC_INFO
, &shm_info
)) < 0) {
311 for (id
= 0; id
<= maxid
; id
++) {
312 shmid
= shmctl(id
, SHM_STAT
, &shmseg
);
317 if (shmseg
.shm_segsz
== 64528) {
318 log_debug(_("Found it! \"set LCShmKey %s\" in your ~/.gnashrc"),
319 boost::io::group(hex
, showbase
,
320 shmseg
.shm_perm
.IPC_PERM_KEY
));
321 log_debug(_("Last changed on: %s"), ctime(&shmseg
.shm_ctime
));
322 log_debug(_("Last attached on: %s"), ctime(&shmseg
.shm_atime
));
323 log_debug(_("Last detached on: %s"), ctime(&shmseg
.shm_dtime
));
324 return shmseg
.shm_perm
.IPC_PERM_KEY
;
326 #endif // end of IPC_PERM_KEY
329 // # error "No supported shared memory type for this platform"
330 //#endif // end of USE_POSIX_SHM
332 // Didn't find any segments of the right size
333 return static_cast<key_t
>(0);
335 #endif // end of USE_SYSV_SHM & HAVE_IPC_INFO
337 /// \brief Display the command line arguments
341 cerr
<< _("This program dumps the internal data of a shared memory segment")
343 cerr
<< _("Usage: dumpshm [hdsanlif] filename") << endl
;
344 cerr
<< _("-h\tHelp") << endl
;
345 cerr
<< _("-i\tList segments") << endl
;
346 cerr
<< _("-r\tDump SYSV segments") << endl
;
347 cerr
<< _("-c\tDump SYSV segments to disk") << endl
;
348 cerr
<< _("-v\tVerbose output") << endl
;
352 /// \brief Dumps the internal data of the found ShmControl
353 /// block. We do our own dumping, rather than letting
354 /// ShmControl::dump() do it, cause that's for debugging,
355 /// and this is for user display purposes.
356 void dump_ctrl(void *inmem
)
358 Shm
*ptr
= static_cast<Shm
*>(inmem
);
360 cerr
<< _("\tBase address of this segment: ")
361 << static_cast<void *>(ptr
->getAddr()) << endl
;
362 cerr
<< _("\tFilespec: ") << ptr
->getName() << endl
;
363 cerr
<< _("\t# Bytes allocated: ") << ptr
->getAllocated() << endl
;
364 cerr
<< _("\tTotal # of bytes: ") << ptr
->getSize() << endl
;
369 // indent-tabs-mode: t