-#endif /* NO_DEFAULT_BUBBLE */
-
-#endif /* HAVE_XPM */
-
-/*
- * File I/O stuff
- */
-
-#ifdef BUBBLES_IO
-
-static DIR *
-my_opendir(char *name)
-/* Like opendir() but checks for things so we don't have to do it multiple
-times in the code. */
-{
- DIR *rv;
-
- if (name == (char *)NULL) {
- fprintf(stderr, "NULL directory name\n");
- return (DIR *)NULL;
- }
-
- if ((rv = opendir(name)) == NULL) {
- perror(name);
- return (DIR *)NULL;
- }
-
- return rv;
-}
-
-static int
-regular_file(char *name)
-/* Check to see if we can use the named file. This was broken under Linux
-1.3.45 but seems to be okay under 1.3.54. The parameter "name" was being
-trashed if the file didn't exist. Yeah, I know 1.3.x are development
-kernels....
-*/
-{
- int fd;
-
- if ((fd = open(name, O_RDONLY)) == -1) {
- perror(name);
- return 0;
- } else {
- close(fd);
- return 1;
- }
-}
-
-static char *
-get_random_name(char *dir)
-/* Pick an appropriate file at random out of the files in the directory dir */
-{
- STRUCT_DIRENT *dp;
- DIR *dfd;
- int numentries = 0;
- int entnum;
- int x;
- char buf[PATH_BUF_SIZE];
- char *rv;
-
- if ((dfd = my_opendir(dir)) == (DIR *)NULL)
- return (char *)NULL;
-
- while ((dp = readdir(dfd)) != NULL) {
- if ((strcmp(DIRENT_NAME, ".") == 0) || (strcmp(DIRENT_NAME, "..") == 0))
- continue;
- if ((strlen(dir)+strlen(DIRENT_NAME)+2) > 1024) {
- fprintf(stderr, "name %s/%s too long\n", dir, DIRENT_NAME);
- continue;
- }
- if (sprintf(buf, "%s/%s", dir, DIRENT_NAME) > (PATH_BUF_SIZE-1)) {
- fprintf(stderr, "path buffer overflowed in get_random_name()\n");
- continue;
- }
- if (regular_file(buf))
- ++numentries;
- }
- closedir(dfd);
- if (numentries == 0) {
- fprintf(stderr, "No suitable files found in %s\n", dir);
- return (char *)NULL;
- }
- entnum = ya_random() % numentries;
- x = 0;
-
- if ((dfd = my_opendir(dir)) == (DIR *)NULL)
- return (char *)NULL;
- while ((dp = readdir(dfd)) != NULL) {
- if ((strcmp(DIRENT_NAME, ".") == 0) || (strcmp(DIRENT_NAME, "..") == 0))
- continue;
- if ((strlen(dir)+strlen(DIRENT_NAME)+2) > 1024) {
- /* We warned about this previously */
- continue;
- }
- if (sprintf(buf, "%s/%s", dir, DIRENT_NAME) > (PATH_BUF_SIZE-1)) {
- fprintf(stderr, "path buffer overflowed in get_random_name()\n");
- continue;
- }
- if (regular_file(buf)) {
- if (x == entnum) {
- rv = (char *)xmalloc(1024 * sizeof(char));
- strcpy(rv, buf);
- closedir(dfd);
- return rv;
- }
- ++x;
- }
- }
- /* We've screwed up if we reach here - someone must have deleted all the
- files while we were counting them... */
- fprintf(stderr, "get_random_name(): Oops!\n");
- exit(1);
-}
-
-static int
-read_line(int fd, char **buf, int bufsize)
-/* A line is read from fd until a '\n' is found or EOF is reached. (*buf)
-is initially of length bufsize and is extended by bufsize chars if need
-be (for as many times as it takes). */
-{
- char x;
- int pos = 0;
- int size = bufsize;
- int rv;
- char *newbuf;
-
- while (1) {
- rv = read(fd, &x, 1);
- if (rv == -1) {
- perror("read_line(): ");
- return IO_ERROR;
- } else if (rv == 0) {
- (*buf)[pos] = '\0';
- return EOF_REACHED;
- } else if (x == '\n') {
- (*buf)[pos] = '\0';
- return LINE_READ;
- } else {
- (*buf)[pos++] = x;
- if (pos == (size - 1)) {
- /* We've come to the end of the space */
- newbuf = (char *)xmalloc((size+bufsize) * sizeof(char));
- strncpy(newbuf, *buf, (size - 1));
- free(*buf);
- *buf = newbuf;
- size += bufsize;
- }
- }
- }
-}
-
-static int
-create_temp_file(char **name)
-/* Create a temporary file in /tmp and return a filedescriptor to it */
-{
- int rv;
-
- if (*name != (char *)NULL)
- free(*name);
-
- if ((*name = tempnam("/tmp", "abxdfes")) == (char *)NULL) {
- fprintf(stderr, "Couldn't make new temporary file\n");
- exit(1);
- }
-/* printf("Temp file created : %s\n", *name); */
- if ((rv = creat(*name, 0644)) == -1) {
- fprintf(stderr, "Couldn't open temporary file\n");
- exit(1);
- }
-
- return rv;
-}
-
-
-#ifdef BUBBLES_IO
-static void
-make_pixmap_from_file(char *fname, Bubble_Step *bl)
-/* Read the pixmap in file fname into structure bl which must already
- be allocated. */
-{
- int result;
- XGCValues gcv;
-
- if (bl == (Bubble_Step *)NULL) {
- fprintf(stderr, "NULL pointer passed to make_pixmap()\n");
- exit(1);
- }
-
- bl->xpmattrs.closeness = 40000;
- bl->xpmattrs.valuemask = XpmColormap | XpmCloseness;
- bl->xpmattrs.colormap = defcmap;
-
- result = XpmReadFileToPixmap(defdsp, defwin, fname, &bl->ball,
- &bl->shape_mask, &bl->xpmattrs);
-
- switch(result) {
- case XpmColorError:
- fprintf(stderr, "xpm: color substitution performed\n");
- /* fall through */
- case XpmSuccess:
- bl->radius = MAX(bl->xpmattrs.width, bl->xpmattrs.height) / 2;
- bl->area = calc_bubble_area(bl->radius);
- break;
- case XpmColorFailed:
- fprintf(stderr, "xpm: color allocation failed\n");
- exit(1);
- case XpmNoMemory:
- fprintf(stderr, "xpm: out of memory\n");
- exit(1);
- default:
- fprintf(stderr, "xpm: unknown error code %d\n", result);
- exit(1);
- }
-
- gcv.plane_mask = AllPlanes;
- gcv.foreground = default_fg_pixel;
- gcv.function = GXcopy;
- bl->draw_gc = XCreateGC (defdsp, defwin, GCForeground, &gcv);
- XSetClipMask(defdsp, bl->draw_gc, bl->shape_mask);
-
- gcv.foreground = default_bg_pixel;
- gcv.function = GXcopy;
- bl->erase_gc = XCreateGC (defdsp, defwin, GCForeground, &gcv);
- XSetClipMask(defdsp, bl->erase_gc, bl->shape_mask);
-}
-#endif /* BUBBLES_IO */
-
-static void
-read_file_to_pixmaps(char *fname)
-/* Read the pixmaps contained in the file fname into memory. THESE SHOULD
-BE UNCOMPRESSED AND READY TO GO! */
-{
- int fd, tmpfd=0, rv;
- int inxpm = 0;
- int xpmseen = 0;
- char *buf = (char *)NULL;
- char *tmpname = (char *)NULL;
- Bubble_Step *pixmap_list = (Bubble_Step *)NULL;
- Bubble_Step *newpix, *tmppix;
-
- /* We first create a linked list of pixmaps before allocating
- memory for the array */
-
- if ((fd = open(fname, O_RDONLY)) == -1) {
- fprintf(stderr, "Couldn't open %s\n", fname);
- exit(1);
- }
-
-#ifdef SIGNAL_NONSENSE
- /* Make sure pixmaps are freed when program is terminated */
- /* This is when I hit ^C */
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, onintr);
- /* xscreensaver sends SIGTERM */
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, onintr);
-#ifdef DEBUG
- if (signal(SIGSEGV, SIGN_IGN) != SIG_IGN)
- signal(SIGSEGV, onsegv);
-#endif /* DEBUG */
-#endif /* SIGNAL_NONSENSE */
-
- while (1) {
- if (inxpm == 2)
- break;
-
- buf = (char *)malloc(READ_LINE_BUF_SIZE * sizeof(char));
-
- switch ((rv = read_line(fd, &buf, READ_LINE_BUF_SIZE))) {
- case IO_ERROR:
- fprintf(stderr, "An I/O error occurred\n");
- exit(1);
- case EOF_REACHED:
- if (inxpm) {
- fprintf(stderr, "EOF occurred inside an XPM block\n");
- exit(1);
- } else
- inxpm = 2;
- break;
- case LINE_READ:
- if (inxpm) {
- if (strncmp("};", buf, 2) == 0) {
- inxpm = 0;
- write(tmpfd, buf, strlen(buf));
- write(tmpfd, "\n", 1);
- close(tmpfd);
- /* Now process the tmpfile */
- newpix = (Bubble_Step *)xmalloc(sizeof(Bubble_Step));
- make_pixmap_from_file(tmpname, newpix);
- /* Now add to list */
- if (pixmap_list == (Bubble_Step *)NULL) {
- pixmap_list = newpix;
- } else {
- tmppix = pixmap_list;
- while (tmppix->next != (Bubble_Step *)NULL)
- tmppix = tmppix->next;
- tmppix->next = newpix;
- }
- newpix->next = (Bubble_Step *)NULL;
- unlink(tmpname);
- } else {
- write(tmpfd, buf, strlen(buf));
- write(tmpfd, "\n", 1);
- }
- } else {
- if (strncmp("/* XPM */", buf, 9) == 0) {
- tmpfd = create_temp_file(&tmpname);
-/* This proves XPM's performance is kinda pathetic */
-#ifdef DEBUG
- printf("New XPM detected : %s, fd=%d\n", tmpname, tmpfd);
-#endif /* DEBUG */
- inxpm = 1;
- xpmseen = 1;
- }
- write(tmpfd, buf, strlen(buf));
- write(tmpfd, "\n", 1);
- }
- break;
- default:
- fprintf(stderr, "read_line returned unknown code %d\n", rv);
- exit(1);
- }
-
- free(buf);
- }
-
- close(fd);
- if (buf != (char *)NULL)
- free(buf);
- if (tmpname != (char *)NULL)
- free(tmpname);
-
- if (! xpmseen) {
- fprintf(stderr, "There was no XPM data in the file %s\n", fname);
- exit(1);
- }
-
- /* Finally construct step_pixmaps[] */
- make_pixmap_array(pixmap_list);
-}
-
-static void
-shell_exec(char *command)
-/* Forks a shell to execute "command" then waits for command to finish */
-{
- int pid, status, wval;