/** * Match and create font from given fontconfig pattern */ decltype(auto) make_font(cairo_t* cairo, string&& fontname, double offset, double dpi_x, double dpi_y) { static bool fc_init{false}; if (!fc_init && !(fc_init = FcInit())) { throw application_error("Could not load fontconfig"); } else if (FT_Init_FreeType(&g_ftlib) != FT_Err_Ok) { throw application_error("Could not load FreeType"); } static auto fc_cleanup = scope_util::make_exit_handler([] { FT_Done_FreeType(g_ftlib); FcFini(); }); auto pattern = FcNameParse((FcChar8*)fontname.c_str()); FcDefaultSubstitute(pattern); FcConfigSubstitute(nullptr, pattern, FcMatchPattern); FcResult result; FcPattern* match = FcFontMatch(nullptr, pattern, &result); FcPatternDestroy(pattern); if (match == nullptr) { throw application_error("Could not load font \"" + fontname + "\""); } #ifdef DEBUG_FONTCONFIG FcPatternPrint(match); #endif return make_shared<font_fc>(cairo, match, offset, dpi_x, dpi_y); }
static CK_RV commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len, const CK_MECHANISM_TYPE *mechs, int mechs_len, const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, struct st_object **o) { CK_RV ret; int i; *o = NULL; if ((ret = object_handle_to_object(hKey, o)) != CKR_OK) return ret; ret = attributes_match(*o, attr_match, attr_match_len); if (!ret) { application_error("called commonInit on key that doesn't " "support required attr"); return CKR_ARGUMENTS_BAD; } for (i = 0; i < mechs_len; i++) if (mechs[i] == pMechanism->mechanism) break; if (i == mechs_len) { application_error("called mech (%08lx) not supported\n", pMechanism->mechanism); return CKR_ARGUMENTS_BAD; } return CKR_OK; }
/** * Construct config object */ config::config(const logger& logger, string&& path, string&& bar) : m_log(logger), m_file(forward<string>(path)), m_barname(forward<string>(bar)) { if (!file_util::exists(m_file)) { throw application_error("Could not find config file: " + m_file); } m_log.info("Loading config: %s", m_file); parse_file(); copy_inherited(); bool found_bar{false}; for (auto&& p : m_sections) { if (p.first == section()) { found_bar = true; break; } } if (!found_bar) { throw application_error("Undefined bar: " + m_barname); } m_log.trace("config: Current bar section: [%s]", section()); }
size_t render(const string& text, double x = 0.0, double y = 0.0) override { cairo_glyph_t* glyphs{nullptr}; cairo_text_cluster_t* clusters{nullptr}; cairo_text_cluster_flags_t cf{}; int nglyphs = 0, nclusters = 0; string utf8 = string(text); auto status = cairo_scaled_font_text_to_glyphs( m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status)); } size_t bytes = 0; for (int g = 0; g < nglyphs; g++) { if (glyphs[g].index) { bytes += clusters[g].num_bytes; } else { break; } } if (bytes && bytes < text.size()) { cairo_glyph_free(glyphs); cairo_text_cluster_free(clusters); utf8 = text.substr(0, bytes); auto status = cairo_scaled_font_text_to_glyphs( m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status)); } } if (bytes) { // auto lock = make_unique<utils::device_lock>(cairo_surface_get_device(cairo_get_target(m_cairo))); // if (lock.get()) { // cairo_glyph_path(m_cairo, glyphs, nglyphs); // } cairo_text_extents_t extents{}; cairo_scaled_font_glyph_extents(m_scaled, glyphs, nglyphs, &extents); cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf); cairo_fill(m_cairo); cairo_move_to(m_cairo, x + extents.x_advance, 0.0); } cairo_glyph_free(glyphs); cairo_text_cluster_free(clusters); return bytes; }
/** * Query for the XSYNC extension */ void query_extension(connection& conn) { conn.sync().initialize(XCB_SYNC_MAJOR_VERSION, XCB_SYNC_MINOR_VERSION); if (!conn.extension<xpp::sync::extension>()->present) { throw application_error("Missing X extension: Sync"); } }
explicit font_fc(cairo_t* cairo, FcPattern* pattern, double offset, double dpi_x, double dpi_y) : font(cairo, offset), m_pattern(pattern) { cairo_matrix_t fm; cairo_matrix_t ctm; cairo_matrix_init_scale(&fm, size(dpi_x), size(dpi_y)); cairo_get_matrix(m_cairo, &ctm); auto fontface = cairo_ft_font_face_create_for_pattern(m_pattern); auto opts = cairo_font_options_create(); m_scaled = cairo_scaled_font_create(fontface, &fm, &ctm, opts); cairo_font_options_destroy(opts); cairo_font_face_destroy(fontface); auto status = cairo_scaled_font_status(m_scaled); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status)); } auto lock = make_unique<utils::ft_face_lock>(m_scaled); auto face = static_cast<FT_Face>(*lock); if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) { return; } else if (FT_Select_Charmap(face, FT_ENCODING_BIG5) == FT_Err_Ok) { return; } else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) { return; } lock.reset(); }
/** * Query for the XKB extension */ void query_extension(connection& conn) { conn.xkb().use_extension(XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); if (!conn.extension<xpp::xkb::extension>()->present) { throw application_error("Missing X extension: XKb"); } }
/** * Query for the XDAMAGE extension */ void query_extension(connection& conn) { conn.damage().query_version(XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); if (!conn.extension<xpp::damage::extension>()->present) { throw application_error("Missing X extension: Damage"); } }
/** * Check if required X extensions are available */ void connection::query_extensions() { #ifdef ENABLE_DAMAGE_EXT damage().query_version(XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); if (!extension<xpp::damage::extension>()->present) throw application_error("Missing X extension: Damage"); #endif #ifdef ENABLE_RENDER_EXT render().query_version(XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MINOR_VERSION); if (!extension<xpp::render::extension>()->present) throw application_error("Missing X extension: Render"); #endif #ifdef ENABLE_RANDR_EXT randr().query_version(XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION); if (!extension<xpp::randr::extension>()->present) throw application_error("Missing X extension: RandR"); #endif }
/** * Set output verbosity */ void logger::verbosity(loglevel&& level) { #ifndef DEBUG_LOGGER if (level == loglevel::TRACE) { throw application_error("Trace logging is not enabled..."); } #endif m_level = forward<decltype(level)>(level); }
/** * Query for the XCOMPOSITE extension */ void query_extension(connection&) { #if 0 conn.composite().query_version(XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION); if (!conn.extension<xpp::composite::extension>()->present) { throw application_error("Missing X extension: Composite"); } #endif }
static void close_session(struct session_state *state) { if (state->find.attributes) { application_error("application didn't do C_FindObjectsFinal\n"); find_object_final(state); } state->session_handle = CK_INVALID_HANDLE; soft_token.application = NULL_PTR; soft_token.notify = NULL_PTR; reset_crypto_state(state); }
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) { struct session_state *state; int i; INIT_CONTEXT(); st_logf("FindObjects\n"); VERIFY_SESSION_HANDLE(hSession, &state); if (state->find.next_object == -1) { application_error("application didn't do C_FindObjectsInit\n"); return CKR_ARGUMENTS_BAD; } if (ulMaxObjectCount == 0) { application_error("application asked for 0 objects\n"); return CKR_ARGUMENTS_BAD; } *pulObjectCount = 0; for (i = state->find.next_object; i < soft_token.object.num_objs; i++) { st_logf("FindObjects: %d\n", i); state->find.next_object = i + 1; if (attributes_match(soft_token.object.objs[i], state->find.attributes, state->find.num_attributes)) { *phObject++ = soft_token.object.objs[i]->object_handle; ulMaxObjectCount--; (*pulObjectCount)++; if (ulMaxObjectCount == 0) break; } } return CKR_OK; }
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) { struct session_state *state; INIT_CONTEXT(); st_logf("CloseSession\n"); if (verify_session_handle(hSession, &state) != CKR_OK) application_error("closed session not open"); else close_session(state); return CKR_OK; }
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { struct session_state *state; st_logf("FindObjectsInit\n"); INIT_CONTEXT(); VERIFY_SESSION_HANDLE(hSession, &state); if (state->find.next_object != -1) { application_error("application didn't do C_FindObjectsFinal\n"); find_object_final(state); } if (ulCount) { CK_ULONG i; print_attributes(pTemplate, ulCount); state->find.attributes = calloc(1, ulCount * sizeof(state->find.attributes[0])); if (state->find.attributes == NULL) return CKR_DEVICE_MEMORY; for (i = 0; i < ulCount; i++) { state->find.attributes[i].pValue = malloc(pTemplate[i].ulValueLen); if (state->find.attributes[i].pValue == NULL) { find_object_final(state); return CKR_DEVICE_MEMORY; } memcpy(state->find.attributes[i].pValue, pTemplate[i].pValue, pTemplate[i].ulValueLen); state->find.attributes[i].type = pTemplate[i].type; state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen; } state->find.num_attributes = ulCount; state->find.next_object = 0; } else { st_logf("find all objects\n"); state->find.attributes = NULL; state->find.num_attributes = 0; state->find.next_object = 0; } return CKR_OK; }
CK_RV C_Finalize(CK_VOID_PTR args) { size_t i; INIT_CONTEXT(); st_logf("Finalize\n"); for (i = 0; i < MAX_NUM_SESSION; i++) { if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) { application_error("application finalized without " "closing session\n"); close_session(&soft_token.state[i]); } } return CKR_OK; }
static CK_RV verify_session_handle(CK_SESSION_HANDLE hSession, struct session_state **state) { size_t i; for (i = 0; i < MAX_NUM_SESSION; i++){ if (soft_token.state[i].session_handle == hSession) break; } if (i == MAX_NUM_SESSION) { application_error("use of invalid handle: 0x%08lx\n", (unsigned long)hSession); return CKR_SESSION_HANDLE_INVALID; } if (state) *state = &soft_token.state[i]; return CKR_OK; }
static void print_attributes(const CK_ATTRIBUTE *attributes, CK_ULONG num_attributes) { CK_ULONG i; st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes); for (i = 0; i < num_attributes; i++) { st_logf(" type: "); switch (attributes[i].type) { case CKA_TOKEN: { CK_BBOOL *ck_true; if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) { application_error("token attribute wrong length\n"); break; } ck_true = attributes[i].pValue; st_logf("token: %s", *ck_true ? "TRUE" : "FALSE"); break; } case CKA_CLASS: { CK_OBJECT_CLASS *class; if (attributes[i].ulValueLen != sizeof(CK_ULONG)) { application_error("class attribute wrong length\n"); break; } class = attributes[i].pValue; st_logf("class "); switch (*class) { case CKO_CERTIFICATE: st_logf("certificate"); break; case CKO_PUBLIC_KEY: st_logf("public key"); break; case CKO_PRIVATE_KEY: st_logf("private key"); break; case CKO_SECRET_KEY: st_logf("secret key"); break; case CKO_DOMAIN_PARAMETERS: st_logf("domain parameters"); break; default: st_logf("[class %lx]", (long unsigned)*class); break; } break; } case CKA_PRIVATE: st_logf("private"); break; case CKA_LABEL: st_logf("label"); break; case CKA_APPLICATION: st_logf("application"); break; case CKA_VALUE: st_logf("value"); break; case CKA_ID: st_logf("id"); break; default: st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type); break; } st_logf("\n"); } }
PUBLIC int HTLoadHTTP ARGS4 ( char *, arg, HTParentAnchor *, anAnchor, HTFormat, format_out, HTStream*, sink) { int s; /* Socket number for returned data */ char *command; /* The whole command */ char *eol; /* End of line if found */ char *start_of_data; /* Start of body of reply */ int status; /* tcp return */ int bytes_already_read; char crlf[3]; /* A CR LF equivalent string */ HTStream *target; /* Unconverted data */ HTFormat format_in; /* Format arriving in the message */ char *line_buffer; char *line_kept_clean; BOOL extensions; /* Assume good HTTP server */ int compressed; char line[2048]; /* bumped up to cover Kerb huge headers */ int length, doing_redirect, rv; int already_retrying = 0; int return_nothing; int i; int keepingalive = 0; char *p; /*SWP*/ int statusError=0; if (!arg) { status = -3; HTProgress ("Bad request."); goto done; } if (!*arg) { status = -2; HTProgress ("Bad request."); goto done; } sprintf(crlf, "%c%c", CR, LF); /* At this point, we're talking HTTP/1.0. */ extensions = YES; try_again: /* All initializations are moved down here from up above, so we can start over here... */ eol = 0; bytes_already_read = 0; length = 0; doing_redirect = 0; compressed = 0; target = NULL; line_buffer = NULL; line_kept_clean = NULL; return_nothing = 0; /* okay... addr looks like http://hagbard.ncsa.uiuc.edu/blah/etc.html lets crop it at the 3rd '/' */ for(p = arg,i=0;*p && i!=3;p++) if(*p=='/') i++; if(i==3) i = p-arg; /* i = length not counting last '/' */ else i = 0; if((lsocket != -1) && i && addr && !strncmp(addr,arg,i)){ /* keepalive is active and addresses match -- try the old socket */ s = lsocket; keepingalive = 1; /* flag in case of network error due to server timeout*/ lsocket = -1; /* prevent looping on failure */ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Keep-Alive reusing '%s'\n",addr); #endif /* if (addr && *addr) { sprintf(tmpbuf,"Reusing socket from %s.",addr); HTProgress(tmpbuf); } */ } else { if(addr) free(addr); /* save the address for next time around */ addr = malloc(i+1); strncpy(addr,arg,i); *(addr+i)=0; keepingalive = 0; /* just normal opening of the socket */ if(lsocket != -1) NETCLOSE(lsocket); /* no socket leaks here */ lsocket = -1; /*dont assign until we know the server says okay */ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Keep-Alive saving '%s'\n",addr); #endif /* if (addr && *addr) { sprintf(tmpbuf,"Saving %s for possible socket reuse.",addr); HTProgress(tmpbuf); } */ } if (!keepingalive) { status = HTDoConnect (arg, "HTTP", TCP_PORT, &s); if (status == HT_INTERRUPTED){ /* Interrupt cleanly. */ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Interrupted on connect; recovering cleanly.\n"); #endif HTProgress ("Connection interrupted."); /* status already == HT_INTERRUPTED */ goto done; } if (status < 0) { #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "HTTP: Unable to connect to remote host for `%s' (errno = %d).\n", arg, errno); #endif HTProgress ("Unable to connect to remote host."); status = HT_NO_DATA; goto done; } } /* Ask that node for the document, ** omitting the host name & anchor */ { char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION); command = malloc(5 + strlen(p1)+ 2 + 31); if (do_post && !do_put) strcpy(command, "POST "); else if (do_post && do_put) strcpy(command, "PUT "); else if (do_head) strcpy(command, "HEAD "); else if (do_meta) strcpy(command, "META "); else strcpy(command, "GET "); /* * For a gateway, the beginning '/' on the request must * be stripped before appending to the gateway address. */ if ((using_gateway)||(using_proxy)) { strcat(command, p1+1); } else strcat(command, p1); free(p1); } if (extensions) { strcat(command, " "); strcat(command, HTTP_VERSION); } strcat(command, crlf); /* CR LF, as in rfc 977 */ if (extensions) { #ifdef SAM_NOT_YET /* SAM This produces an absolutely huge Accept: line. While there is probably a better way to turn this off, just compiling it out works for now. */ int n, i; if (!HTPresentations) HTFormatInit(); n = HTList_count(HTPresentations); begin_ptr=command+strlen(command); env_length=0; sprintf(line, "Accept:"); env_length+=strlen(line); StrAllocCat(command, line); /* KCMS Accept Header - swp */ if (KCMS_Return_Format==JPEG) { sprintf(line," image/x-pcd-jpeg,"); StrAllocCat(command, line); env_length+=strlen(line); } else if (KCMS_Return_Format==JYCC) { sprintf(line," image/x-pcd-jycc,"); StrAllocCat(command, line); env_length+=strlen(line); } else if (KCMS_Return_Format==GIF) { sprintf(line," image/x-pcd-gif,"); StrAllocCat(command, line); env_length+=strlen(line); } for(i=0; i<n; i++) { HTPresentation * pres = HTList_objectAt(HTPresentations, i); if (pres->rep_out == WWW_PRESENT) { sprintf(line, " %s,",HTAtom_name(pres->rep)); env_length+=strlen(line); StrAllocCat(command, line); if (env_length>200) { if ((tmp_ptr=strrchr(command,','))!=NULL) { *tmp_ptr='\0'; } sprintf(line, "%c%c",CR,LF); StrAllocCat(command, line); begin_ptr=command+strlen(command); sprintf(line, "Accept:"); env_length=strlen(line); StrAllocCat(command, line); } } } /* This gets rid of the last comma. */ if ((tmp_ptr=strrchr(command,','))!=NULL) { *tmp_ptr='\0'; sprintf(line, "%c%c",CR,LF); StrAllocCat(command, line); } else { /* No accept stuff...get rid of "Accept:" */ begin_ptr='\0'; } #endif /* if reloading, send no-cache pragma to proxy servers. --swp */ /* original patch from Ari L. <*****@*****.**> */ if (reloading) { sprintf(line, "Pragma: no-cache%c%c", CR, LF); StrAllocCat(command, line); } /*This is just used for "not" sending this header on a proxy request*/ if (useKeepAlive) { sprintf(line, "Connection: keep-alive%c%c", CR, LF); StrAllocCat(command, line); } if (sendAgent) { sprintf(line, "User-Agent: %s%c%c",agent[selectedAgent],CR,LF); /* sprintf(line, "User-Agent: %s/%s libwww/%s%c%c", HTAppName ? HTAppName : "unknown", HTAppVersion ? HTAppVersion : "0.0", HTLibraryVersion, CR, LF); */ StrAllocCat(command, line); } if (sendReferer) { /* HTTP Referer field, specifies back-link URL - amb */ if (HTReferer) { sprintf(line, "Referer: %s%c%c", HTReferer, CR, LF); StrAllocCat(command, line); HTReferer = NULL; } } { char *tmp,*startPtr,*endPtr; /* addr is always in URL form */ if (addr && !using_proxy && !using_gateway) { tmp=strdup(addr); startPtr=strchr(tmp,'/'); if (startPtr) { startPtr+=2; /*now at begining of hostname*/ if (*startPtr) { endPtr=strchr(startPtr,':'); if (!endPtr) { endPtr=strchr(startPtr,'/'); if (endPtr && *endPtr) { *endPtr='\0'; } } else { *endPtr='\0'; } sprintf(line, "Host: %s%c%c", startPtr, CR, LF); StrAllocCat(command, line); free(tmp); tmp=startPtr=endPtr=NULL; } } } else if (using_proxy || using_gateway) { sprintf(line, "Host: %s%c%c", proxy_host_fix, CR, LF); StrAllocCat(command, line); } } /* SWP -- 7/10/95 */ /* HTTP Extension headers */ /* Domain Restriction */ sprintf(line,"Extension: Notify-Domain-Restriction%c%c",CR,LF); StrAllocCat(command,line); /* BJS -- 12/05/95 -- allow arbitrary headers sent from browser */ if(extra_headers){ int h; for(h=0;extra_headers[h];h++){ sprintf(line,"%s%c%c",extra_headers[h],CR,LF); StrAllocCat(command,line); } } { char *docname; char *hostname; char *colon; int portnumber; char *auth; docname = HTParse(arg, "", PARSE_PATH); hostname = HTParse(arg, "", PARSE_HOST); if (hostname && NULL != (colon = strchr(hostname, ':'))) { *(colon++) = '\0'; /* Chop off port number */ portnumber = atoi(colon); } else portnumber = 80; if (NULL!=(auth=HTAA_composeAuth(hostname, portnumber, docname))) { sprintf(line, "%s%c%c", auth, CR, LF); StrAllocCat(command, line); } #ifndef DISABLE_TRACE if (www2Trace) { if (auth) fprintf(stderr, "HTTP: Sending authorization: %s\n", auth); else fprintf(stderr, "HTTP: Not sending authorization (yet)\n"); } #endif FREE(hostname); FREE(docname); } } if (do_post && !do_put) { #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Doing post, content-type '%s'\n", post_content_type); #endif sprintf (line, "Content-type: %s%c%c", post_content_type ? post_content_type : "lose", CR, LF); StrAllocCat(command, line); { int content_length; if (!post_data) content_length = 4; /* 4 == "lose" :-) */ else content_length = strlen (post_data); sprintf (line, "Content-length: %d%c%c", content_length, CR, LF); StrAllocCat(command, line); } StrAllocCat(command, crlf); /* Blank line means "end" */ if (post_data) StrAllocCat(command, post_data); else StrAllocCat(command, "lose"); } else if (do_post && do_put) { sprintf (line, "Content-length: %d%c%c", put_file_size, CR, LF); StrAllocCat(command, line); StrAllocCat(command, crlf); /* Blank line means "end" */ } else { StrAllocCat(command, crlf); /* Blank line means "end" */ } #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "Writing:\n%s----------------------------------\n", command); #endif /* HTProgress ("Sending HTTP request."); */ status = NETWRITE(s, command, (int)strlen(command)); if (do_post && do_put) { char buf[BUFSIZ]; int upcnt=0,n; while (status>0) { n=fread(buf,1,BUFSIZ-1,put_fp); upcnt+= status = NETWRITE(s, buf, n); #ifndef DISABLE_TRACE if (www2Trace) { fprintf(stderr,"[%d](%d) %s",status,n,buf); } #endif if (feof(put_fp)) { break; } } if (status<0 || !feof(put_fp) || upcnt!=put_file_size) { char tmpbuf[BUFSIZ]; sprintf(tmpbuf,"Status: %d -- EOF: %d -- UpCnt/FileSize: %d/%d\n\nThe server you connected to either does not support\nthe PUT method, or an error occurred.\n\nYour upload was corrupted! Please try again!",status,(feof(put_fp)?1:0),upcnt,put_file_size); application_error(tmpbuf,"Upload Error!"); } } /* Twirl on each request to make things look nicer -- SWP */ HTCheckActiveIcon(1); #ifndef DISABLE_TRACE if (httpTrace) { fprintf(stderr,"%s",command); } #endif free (command); if (status <= 0) { if (status == 0) { #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Got status 0 in initial write\n"); #endif /* Do nothing. */ } else if ((errno == ENOTCONN || errno == ECONNRESET || errno == EPIPE) && !already_retrying && /* Don't retry if we're posting. */ !do_post) { /* Arrrrgh, HTTP 0/1 compability problem, maybe. */ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: BONZO ON WRITE Trying again with HTTP0 request.\n"); #endif /* HTProgress ("Retrying as HTTP0 request."); */ NETCLOSE(s); // SAM extensions = NO; already_retrying = 1; goto try_again; } else { if(keepingalive){ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Timeout on Keep-Alive. Retrying.\n"); #endif HTProgress("Server Timeout: Reconnecting"); goto try_again; } #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Hit unexpected network WRITE error; aborting connection.\n"); #endif NETCLOSE (s); status = -1; HTProgress ("Unexpected network write error; connection aborted."); goto done; } } #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: WRITE delivered OK\n"); #endif HTProgress ("Done sending HTTP request; waiting for response."); /* Read the first line of the response ** ----------------------------------- */ { /* Get numeric status etc */ BOOL end_of_file = NO; int buffer_length = INIT_LINE_SIZE; line_buffer = (char *) malloc(buffer_length * sizeof(char)); do { /* Loop to read in the first line */ /* Extend line buffer if necessary for those crazy WAIS URLs ;-) */ if (buffer_length - length < LINE_EXTEND_THRESH) { buffer_length = buffer_length + buffer_length; line_buffer = (char *) realloc(line_buffer, buffer_length * sizeof(char)); } #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Trying to read %d\n", buffer_length - length - 1); #endif status = NETREAD(s, line_buffer + length, buffer_length - length - 1); #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Read %d\n", status); #endif if (status <= 0) { /* Retry if we get nothing back too; bomb out if we get nothing twice. */ if (status == HT_INTERRUPTED) { #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Interrupted initial read.\n"); #endif HTProgress ("Connection interrupted."); status = HT_INTERRUPTED; NETCLOSE (s); goto clean_up; } else if (status < 0 && (errno == ENOTCONN || errno == ECONNRESET || errno == EPIPE) && !already_retrying && !do_post) { /* Arrrrgh, HTTP 0/1 compability problem, maybe. */ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: BONZO Trying again with HTTP0 request.\n"); #endif NETCLOSE(s); if (line_buffer) free(line_buffer); if (line_kept_clean) free(line_kept_clean); extensions = NO; already_retrying = 1; HTProgress ("Retrying as HTTP0 request."); goto try_again; } else { if(keepingalive){ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Timeout on Keep-Alive. Retrying.\n"); #endif HTProgress("Server Timeout: Reconnecting"); goto try_again; } #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Hit unexpected network read error; aborting connection; status %d.\n", status); #endif HTProgress ("Unexpected network read error; connection aborted."); NETCLOSE (s); status = -1; goto clean_up; } } bytes_already_read += status; { char line[256]; sprintf (line, "Read %d bytes of data.", bytes_already_read); HTProgress (line); } if (status == 0) { end_of_file = YES; break; } line_buffer[length+status] = 0; if (line_buffer) { if (line_kept_clean) free (line_kept_clean); line_kept_clean = (char *)malloc (buffer_length * sizeof (char)); /* bcopy (line_buffer, line_kept_clean, buffer_length); */ memcpy (line_kept_clean, line_buffer, buffer_length); } eol = strchr(line_buffer + length, LF); /* Do we *really* want to do this? */ if (eol && eol != line_buffer && *(eol-1) == CR) *(eol-1) = ' '; length = length + status; /* Do we really want to do *this*? */ if (eol) *eol = 0; /* Terminate the line */ /* All we need is the first line of the response. If it's a HTTP/1.0 response, then the first line will be absurdly short and therefore we can safely gate the number of bytes read through this code (as opposed to below) to ~1000. */ /* Well, let's try 100. */ } while (!eol && !end_of_file && bytes_already_read < 100); } /* Scope of loop variables */ /* We now have a terminated unfolded line. Parse it. ** ------------------------------------------------- */ #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "HTTP: Rx: %s\n", line_buffer); #endif { int fields; char server_version[VERSION_LENGTH+1]; int server_status; /*SWP*/ statusError=0; server_version[0] = 0; fields = sscanf(line_buffer, "%20s %d", server_version, &server_status); #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Scanned %d fields from line_buffer\n", fields); #endif #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: line_buffer '%s'\n", line_buffer); #endif /* Rule out HTTP/1.0 reply as best we can. */ if (fields < 2 || !server_version[0] || server_version[0] != 'H' || server_version[1] != 'T' || server_version[2] != 'T' || server_version[3] != 'P' || server_version[4] != '/' || server_version[6] != '.') { /* HTTP0 reply */ HTAtom * encoding; #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "--- Talking HTTP0.\n"); #endif format_in = HTFileFormat(arg, &encoding, WWW_HTML, &compressed); start_of_data = line_kept_clean; } else { /* Decode full HTTP response */ format_in = HTAtom_for("www/mime"); /* We set start_of_data to "" when !eol here because there will be a put_block done below; we do *not* use the value of start_of_data (as a pointer) in the computation of length or anything else in this situation. */ start_of_data = eol ? eol + 1 : ""; length = eol ? length - (start_of_data - line_buffer) : 0; #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "--- Talking HTTP1.\n"); #endif switch (server_status / 100) { case 3: /* Various forms of redirection */ /* We now support this in the parser, at least. */ doing_redirect = 1; break; case 4: /* "I think I goofed" */ switch (server_status) { case 403: statusError=1; /* 403 is "forbidden"; display returned text. */ break; case 401: /* length -= start_of_data - text_buffer; */ if (HTAA_shouldRetryWithAuth(start_of_data, length, s)) { (void)NETCLOSE(s); lsocket = -1; if (line_buffer) free(line_buffer); if (line_kept_clean) free(line_kept_clean); #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "%s %d %s\n", "HTTP: close socket", s, "to retry with Access Authorization"); #endif HTProgress ("Retrying with access authorization information."); goto try_again; break; } else { statusError=1; /* Fall through. */ } default: statusError=1; break; } /* case 4 switch */ break; case 5: /* I think you goofed */ statusError=1; break; case 2: /* Good: Got MIME object */ switch (server_status) { case 204: return_nothing = 1; format_in = HTAtom_for("text/html"); break; case 200: if (do_head) { if (!start_of_data || !*start_of_data) { headData=NULL; } else { char *ptr; headData=strdup(start_of_data); ptr=strchr(headData,'\n'); *ptr='\0'; } } break; default: break; } break; default: /* bad number */ statusError=1; HTAlert("Unknown status reply from server!"); break; } /* Switch on server_status/100 */ } /* Full HTTP reply */ } /* scope of fields */ /* Set up the stream stack to handle the body of the message */ target = HTStreamStack(format_in, format_out, compressed, sink, anAnchor); if (!target) { char buffer[1024]; /* @@@@@@@@ */ sprintf(buffer, "Sorry, no known way of converting %s to %s.", HTAtom_name(format_in), HTAtom_name(format_out)); HTProgress (buffer); status = -1; NETCLOSE (s); lsocket = -1; goto clean_up; } if (!return_nothing) { #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Doing put_block, '%s'\n", start_of_data); #endif /* BJS: parse start_of_data...*/ for(p=start_of_data;*p;p++){ /* if(*p=='C' && !strncmp("Content-length: ",p,16)){ i = 0; p+=16; while(*p && isdigit(*p)){ i = i*10 + *p-'0'; p++; } p--; #ifndef DISABLE_TRACE if(www2Trace) fprintf(stderr, "HTTP: Content Length is %d\n",i); #endif } */ if(*p=='K' && !strncmp("Keep-Alive:",p,11)){ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Server Agrees to Keep-Alive\n"); #endif lsocket = s; p+=10; } } #ifndef DISABLE_TRACE if (www2Trace && lsocket == -1) fprintf (stderr, "HTTP: Server does not agree to Keep-Alive\n"); #endif /* Recycle the first chunk of data, in all cases. */ (*target->isa->put_block)(target, start_of_data, length); /* Go pull the bulk of the data down. */ /* if we dont use length, header length is wrong due to the discarded first line - bjs*/ rv = HTCopy(s, target, length /*bytes_already_read*/); if (rv == -1) { (*target->isa->handle_interrupt) (target); status = HT_INTERRUPTED; NETCLOSE (s); lsocket = -1; goto clean_up; } if (rv == -2 && !already_retrying && !do_post) { /* Aw hell. */ #ifndef DISABLE_TRACE if (www2Trace) fprintf (stderr, "HTTP: Trying again with HTTP0 request.\n"); #endif /* May as well consider it an interrupt -- right? */ (*target->isa->handle_interrupt) (target); NETCLOSE(s); if (line_buffer) free(line_buffer); if (line_kept_clean) free(line_kept_clean); extensions = NO; already_retrying = 1; HTProgress ("Retrying as HTTP0 request."); goto try_again; } } else { /* return_nothing is high. */ (*target->isa->put_string) (target, "<mosaic-access-override>\n"); HTProgress ("And silence filled the night."); } (*target->isa->end_document)(target); /* Close socket before doing free. */ if(lsocket == -1){ NETCLOSE(s); #ifndef DISABLE_TRACE if(www2Trace) fprintf(stderr,"HTTP: Closing connection\n"); #endif } else { HTProgress("Leaving Server Connection Open"); #ifndef DISABLE_TRACE if(www2Trace) fprintf(stderr,"HTTP: Keeping connection alive\n"); #endif } /* else { NETCLOSE(s); #ifndef DISABLE_TRACE if(www2Trace) fprintf(stderr,"HTTP: Closing connection\n"); #endif } */ (*target->isa->free)(target); if (doing_redirect) { /* OK, now we've got the redirection URL temporarily stored in external variable redirecting_url, exported from HTMIME.c, since there's no straightforward way to do this in the library currently. Do the right thing. */ status = HT_REDIRECTING; } else { status = HT_LOADED; } /* Clean up */ clean_up: if (line_buffer) free(line_buffer); if (line_kept_clean) free(line_kept_clean); done: /* Clear out on exit, just in case. */ do_post = 0; if (statusError) { securityType=HTAA_NONE; #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr,"Resetting security type to NONE.\n"); #endif } return status; }
void write_png(const string& dst) { auto status = cairo_surface_write_to_png(m_s, dst.c_str()); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_surface_write_to_png(): " << cairo_status_to_string(status)); } }