/************************************************************************* Writes buf to socket and returns the response in an fz_FILE. Use only on blocking sockets. *************************************************************************/ fz_FILE *fc_querysocket(int sock, void *buf, size_t size) { FILE *fp; #ifdef HAVE_FDOPEN fp = fdopen(sock, "r+b"); if (fwrite(buf, 1, size, fp) != size) { log_error("socket %d: write error", sock); } fflush(fp); /* we don't use fc_closesocket on sock here since when fp is closed * sock will also be closed. fdopen doesn't dup the socket descriptor. */ #else /* HAVE_FDOPEN */ { char tmp[4096]; int n; #ifdef WIN32_NATIVE /* tmpfile() in mingw attempts to make a temp file in the root directory * of the current drive, which we may not have write access to. */ { char filename[MAX_PATH]; GetTempPath(sizeof(filename), filename); sz_strlcat(filename, "fctmp"); fp = fc_fopen(filename, "w+b"); } #else /* WIN32_NATIVE */ fp = tmpfile(); #endif /* WIN32_NATIVE */ if (fp == NULL) { return NULL; } fc_writesocket(sock, buf, size); while ((n = fc_readsocket(sock, tmp, sizeof(tmp))) > 0) { if (fwrite(tmp, 1, n, fp) != n) { log_error("socket %d: write error", sock); } } fflush(fp); fc_closesocket(sock); rewind(fp); } #endif /* HAVE_FDOPEN */ return fz_from_stream(fp); }
/************************************************************************** Writes the supplied string into the file defined by the variable 'default_chat_logfile'. **************************************************************************/ void write_chatline_content(const char *txt) { FILE *fp = fc_fopen(default_chat_logfile, "w"); char buf[512]; fc_snprintf(buf, sizeof(buf), _("Exporting output window to '%s' ..."), default_chat_logfile); output_window_append(ftc_client, buf); if (fp) { fputs(txt, fp); fclose(fp); output_window_append(ftc_client, _("Export complete.")); } else { output_window_append(ftc_client, _("Export failed, couldn't write to file.")); } }
/*************************************************************************** ... ***************************************************************************/ struct sprite *load_gfxfile(const char *filename) { png_structp pngp; png_infop infop; png_int_32 width, height, x, y; FILE *fp; int npalette, ntrans; png_colorp palette; png_bytep trans; png_bytep buf, pb; png_uint_32 stride; unsigned long *pcolorarray; bool *ptransarray; struct sprite *mysprite; XImage *xi; int has_mask; png_byte color_type; png_byte alpha; bool pixel, reported; fp = fc_fopen(filename, "rb"); if (!fp) { log_fatal("Failed reading PNG file: \"%s\"", filename); exit(EXIT_FAILURE); } pngp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pngp) { log_fatal("Failed creating PNG struct"); exit(EXIT_FAILURE); } infop = png_create_info_struct(pngp); if (!infop) { log_fatal("Failed creating PNG struct"); exit(EXIT_FAILURE); } if (setjmp(png_jmpbuf(pngp))) { log_fatal("Failed while reading PNG file: \"%s\"", filename); exit(EXIT_FAILURE); } png_init_io(pngp, fp); png_set_strip_16(pngp); png_set_packing(pngp); png_read_info(pngp, infop); width = png_get_image_width(pngp, infop); height = png_get_image_height(pngp, infop); color_type = png_get_color_type(pngp, infop); if (color_type == PNG_COLOR_TYPE_PALETTE) { if (png_get_PLTE(pngp, infop, &palette, &npalette)) { int i; XColor *mycolors; pcolorarray = fc_malloc(npalette * sizeof(*pcolorarray)); mycolors = fc_malloc(npalette * sizeof(*mycolors)); for (i = 0; i < npalette; i++) { mycolors[i].red = palette[i].red << 8; mycolors[i].green = palette[i].green << 8; mycolors[i].blue = palette[i].blue << 8; } alloc_colors(mycolors, npalette); for (i = 0; i < npalette; i++) { pcolorarray[i] = mycolors[i].pixel; } free(mycolors); } else { log_fatal("PNG file has no palette: \"%s\"", filename); exit(EXIT_FAILURE); } has_mask = png_get_tRNS(pngp, infop, &trans, &ntrans, NULL); if (has_mask) { int i; ptransarray = fc_calloc(npalette, sizeof(*ptransarray)); reported = FALSE; for (i = 0; i < ntrans; i++) { if (trans[i] < npalette) { ptransarray[trans[i]] = TRUE; } else if (!reported) { log_verbose("PNG: Transparent array entry is out of palette: " "\"%s\"", filename); reported = TRUE; } } } else { ptransarray = NULL; } } else { pcolorarray = NULL; ptransarray = NULL; npalette = 0; if ((color_type == PNG_COLOR_TYPE_RGB_ALPHA) || (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) { has_mask = 1; } else { has_mask = 0; } ntrans = 0; } png_read_update_info(pngp, infop); { png_bytep *row_pointers; stride = png_get_rowbytes(pngp, infop); buf = fc_malloc(stride * height); row_pointers = fc_malloc(height * sizeof(png_bytep)); for (y = 0, pb = buf; y < height; y++, pb += stride) { row_pointers[y] = pb; } png_read_image(pngp, row_pointers); png_read_end(pngp, infop); fclose(fp); free(row_pointers); if (infop != NULL) { png_destroy_read_struct(&pngp, &infop, (png_infopp)NULL); } else { log_error("PNG info struct is NULL (non-fatal): \"%s\"", filename); png_destroy_read_struct(&pngp, (png_infopp)NULL, (png_infopp)NULL); } } mysprite = fc_malloc(sizeof(*mysprite)); xi = XCreateImage(display, DefaultVisual(display, screen_number), display_depth, ZPixmap, 0, NULL, width, height, 32, 0); xi->data = fc_calloc(xi->bytes_per_line * xi->height, 1); pb = buf; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { if (pcolorarray) { XPutPixel(xi, x, y, pcolorarray[pb[x]]); } else { if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { XPutPixel(xi, x, y, (pb[2 * x] << 16) + (pb[2 * x] << 8) + pb[2 * x]); } else { if (has_mask) { XPutPixel(xi, x, y, (pb[4 * x] << 16) + (pb[4 * x + 1] << 8) + pb[4 * x + 2]); } else { XPutPixel(xi, x, y, (pb[3 * x] << 16) + (pb[3 * x + 1] << 8) + pb[3 * x + 2]); } } } } pb += stride; } mysprite->pixmap = image2pixmap(xi); XDestroyImage(xi); if (has_mask) { XImage *xm; xm = XCreateImage(display, DefaultVisual(display, screen_number), 1, XYBitmap, 0, NULL, width, height, 8, 0); xm->data = fc_calloc(xm->bytes_per_line * xm->height, 1); pb = buf; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { if (ptransarray) { XPutPixel(xm, x, y, !ptransarray[pb[x]]); } else { if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { alpha = pb[2 * x + 1]; } else { alpha = pb[4 * x + 3]; } if (alpha > 204) { pixel = FALSE; } else if (alpha > 153) { if ((y + x * 2) % 4 == 0) { pixel = TRUE; } else { pixel = FALSE; } } else if (alpha > 102) { if ((y + x) % 2 == 0) { pixel = TRUE; } else { pixel = FALSE; } } else if (alpha > 51) { if ((y + x * 2) % 4 == 0) { pixel = FALSE; } else { pixel = TRUE; } } else { pixel = TRUE; } XPutPixel(xm, x, y, !pixel); } } pb += stride; } mysprite->mask = image2pixmap(xm); XDestroyImage(xm); } mysprite->has_mask = has_mask; mysprite->width = width; mysprite->height = height; mysprite->pcolorarray = pcolorarray; mysprite->ncols = npalette; if (ptransarray) { free(ptransarray); } free(buf); return mysprite; }
/**************************************************************************** Read the request string (or part of it) from the metaserver. ****************************************************************************/ static void meta_read_response(struct server_scan *scan) { char buf[4096]; int result; if (!scan->meta.fp) { #ifdef WIN32_NATIVE char filename[MAX_PATH]; GetTempPath(sizeof(filename), filename); cat_snprintf(filename, sizeof(filename), "fctmp%d", myrand(1000)); scan->meta.fp = fc_fopen(filename, "w+b"); #else scan->meta.fp = tmpfile(); #endif if (!scan->meta.fp) { scan->error_func(scan, _("Could not open temp file.")); } } while (1) { result = fc_readsocket(scan->sock, buf, sizeof(buf)); if (result < 0) { if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { /* Keep waiting. */ return; } scan->error_func(scan, fc_strerror(fc_get_errno())); return; } else if (result == 0) { fz_FILE *f; char str[4096]; /* We're done! */ rewind(scan->meta.fp); f = fz_from_stream(scan->meta.fp); assert(f != NULL); /* skip HTTP headers */ /* XXX: TODO check for magic Content-Type: text/x-ini -vasc */ while (fz_fgets(str, sizeof(str), f) && strcmp(str, "\r\n") != 0) { /* nothing */ } /* XXX: TODO check for magic Content-Type: text/x-ini -vasc */ /* parse HTTP message body */ scan->servers = parse_metaserver_data(f); scan->meta.state = META_DONE; /* 'f' (hence 'meta.fp') was closed in parse_metaserver_data(). */ scan->meta.fp = NULL; if (NULL == scan->servers) { my_snprintf(str, sizeof(str), _("Failed to parse the metaserver data from http://%s."), scan->meta.name); scan->error_func(scan, str); } return; } else { if (fwrite(buf, 1, result, scan->meta.fp) != result) { scan->error_func(scan, fc_strerror(fc_get_errno())); } } } }