int tvh_gzip_deflate_fd ( int fd, const uint8_t *data, size_t orig, size_t *size, int speed ) { int r = 0, err; z_stream zstr; uint8_t *bufout; size_t alloc; assert(speed >= Z_BEST_SPEED && speed <= Z_BEST_COMPRESSION); /* Setup buffers */ *size = 0; alloc = MIN(orig, 256*1024); bufout = malloc(alloc); /* Setup zlib */ memset(&zstr, 0, sizeof(zstr)); err = deflateInit2(&zstr, speed, Z_DEFLATED, MAX_WBITS + 16 /* gzip */, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); zstr.avail_in = orig; zstr.next_in = (z_const uint8_t *)data; zstr.avail_out = alloc; zstr.next_out = bufout; /* Compress */ while (1) { err = deflate(&zstr, Z_FINISH); /* Need more space */ if (err == Z_OK && zstr.avail_out == 0) { r = tvh_write(fd, bufout, alloc); if (r) { r = -1; break; } zstr.avail_out = alloc; zstr.next_out = bufout; continue; } /* Error */ if ( (err != Z_STREAM_END && err != Z_OK) || zstr.total_out == 0 ) { r = -1; } else { if (zstr.avail_out != alloc) r = tvh_write(fd, bufout, alloc - zstr.avail_out); *size = zstr.total_out; } break; } deflateEnd(&zstr); free(bufout); return r; }
void hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) { char path[PATH_MAX]; char tmppath[PATH_MAX]; int fd; va_list ap; htsbuf_queue_t hq; htsbuf_data_t *hd; int ok, r, pack; if(settingspath == NULL) return; /* Clean the path */ va_start(ap, pathfmt); _hts_settings_buildpath(path, sizeof(path), pathfmt, ap, settingspath); va_end(ap); /* Create directories */ if (hts_settings_makedirs(path)) return; tvhdebug("settings", "saving to %s", path); /* Create tmp file */ snprintf(tmppath, sizeof(tmppath), "%s.tmp", path); if((fd = tvh_open(tmppath, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { tvhlog(LOG_ALERT, "settings", "Unable to create \"%s\" - %s", tmppath, strerror(errno)); return; } /* Store data */ #if ENABLE_ZLIB pack = strstr(path, "/muxes/") != NULL && /* ugly, redesign API */ strstr(path, "/networks/") != NULL && strstr(path, "/input/") != NULL; #else pack = 0; #endif ok = 1; if (!pack) { htsbuf_queue_init(&hq, 0); htsmsg_json_serialize(record, &hq, 1); TAILQ_FOREACH(hd, &hq.hq_q, hd_link) if(tvh_write(fd, hd->hd_data + hd->hd_data_off, hd->hd_data_len)) { tvhlog(LOG_ALERT, "settings", "Failed to write file \"%s\" - %s", tmppath, strerror(errno)); ok = 0; break; } htsbuf_queue_flush(&hq); } else {
void hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) { char path[256]; char tmppath[256]; int fd; va_list ap; htsbuf_queue_t hq; htsbuf_data_t *hd; int ok; if(settingspath == NULL) return; /* Clean the path */ va_start(ap, pathfmt); _hts_settings_buildpath(path, sizeof(path), pathfmt, ap, settingspath); va_end(ap); /* Create directories */ if (hts_settings_makedirs(path)) return; tvhdebug("settings", "saving to %s", path); /* Create tmp file */ snprintf(tmppath, sizeof(tmppath), "%s.tmp", path); if((fd = tvh_open(tmppath, O_CREAT | O_TRUNC | O_RDWR, 0700)) < 0) { tvhlog(LOG_ALERT, "settings", "Unable to create \"%s\" - %s", tmppath, strerror(errno)); return; } /* Store data */ ok = 1; htsbuf_queue_init(&hq, 0); htsmsg_json_serialize(record, &hq, 1); TAILQ_FOREACH(hd, &hq.hq_q, hd_link) if(tvh_write(fd, hd->hd_data + hd->hd_data_off, hd->hd_data_len)) { tvhlog(LOG_ALERT, "settings", "Failed to write file \"%s\" - %s", tmppath, strerror(errno)); ok = 0; break; } close(fd); htsbuf_queue_flush(&hq); /* Move */ if(ok) { rename(tmppath, path); /* Delete tmp */ } else unlink(tmppath); }
int tcp_write_queue(int fd, htsbuf_queue_t *q) { htsbuf_data_t *hd; int l, r = 0; void *p; while((hd = TAILQ_FIRST(&q->hq_q)) != NULL) { if (!r) { l = hd->hd_data_len - hd->hd_data_off; p = hd->hd_data + hd->hd_data_off; r = tvh_write(fd, p, l); } htsbuf_data_free(q, hd); } q->hq_size = 0; return r; }