uschar * string_domain_alabel_to_utf8(const uschar * alabel, uschar ** err) { #ifdef SUPPORT_I18N_2008 const uschar * label; int sep = '.'; gstring * g = NULL; while (label = string_nextinlist(&alabel, &sep, NULL, 0)) if ( string_is_alabel(label) && !(label = string_localpart_alabel_to_utf8_(label, err)) ) return NULL; else g = string_append_listele(g, '.', label); return string_from_gstring(g); #else uschar * s1, * s; int rc; if ( (rc = idna_to_unicode_8z8z(CCS alabel, CSS &s1, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) { if (err) *err = US idna_strerror(rc); return NULL; } s = string_copy(s1); free(s1); return s; #endif }
static void compose_console_string (RIP_MANAGER_INFO *rmi, TRACK_INFO* ti) { mchar console_string[SR_MAX_PATH]; msnprintf (console_string, SR_MAX_PATH, m_S m_(" - ") m_S, ti->artist, ti->title); string_from_gstring (rmi, rmi->filename, SR_MAX_PATH, console_string, CODESET_LOCALE); }
static int parse_external_byte (RIP_MANAGER_INFO* rmi, External_Process* ep, TRACK_INFO* ti, char c) { int got_metadata = 0; if (c != '\r' && c != '\n') { if (ep->line_buf_idx < MAX_EXT_LINE_LEN-1) { ep->line_buf[ep->line_buf_idx++] = c; ep->line_buf[ep->line_buf_idx] = 0; } } else { if (!strcmp (".",ep->line_buf)) { /* Found end of record! */ mchar tmp_raw_metadata[MAX_TRACK_LEN]; gstring_from_string (rmi, ti->artist, MAX_TRACK_LEN, ep->artist_buf, CODESET_METADATA); gstring_from_string (rmi, ti->album, MAX_TRACK_LEN, ep->album_buf, CODESET_METADATA); gstring_from_string (rmi, ti->title, MAX_TRACK_LEN, ep->title_buf, CODESET_METADATA); g_snprintf (tmp_raw_metadata, MAX_TRACK_LEN, "%s - %s", ti->artist, ti->title); string_from_gstring (rmi, ti->raw_metadata, MAX_TRACK_LEN, tmp_raw_metadata, CODESET_METADATA); ti->have_track_info = 1; ti->save_track = TRUE; ep->artist_buf[0] = 0; ep->album_buf[0] = 0; ep->title_buf[0] = 0; got_metadata = 1; } else if (!strncmp ("ARTIST=", ep->line_buf, strlen("ARTIST="))) { strcpy (ep->artist_buf, &ep->line_buf[strlen("ARTIST=")]); } else if (!strncmp ("ALBUM=", ep->line_buf, strlen("ALBUM="))) { strcpy (ep->album_buf, &ep->line_buf[strlen("ALBUM=")]); } else if (!strncmp ("TITLE=", ep->line_buf, strlen("TITLE="))) { strcpy (ep->title_buf, &ep->line_buf[strlen("TITLE=")]); } ep->line_buf[0] = 0; ep->line_buf_idx = 0; } return got_metadata; }
/* Ok, the end_track()'s function is actually to move * tracks out from the incomplete directory. It does * get called, but only after the 2nd track is played. * the first track is *never* complete. */ error_code rip_manager_end_track (RIP_MANAGER_INFO* rmi, TRACK_INFO* ti) { mchar mfullpath[SR_MAX_PATH]; char fullpath[SR_MAX_PATH]; if (rmi->write_data) { filelib_end (rmi, ti, rmi->prefs->overwrite, GET_TRUNCATE_DUPS(rmi->prefs->flags), mfullpath); } post_status(rmi, 0); string_from_gstring (rmi, fullpath, SR_MAX_PATH, mfullpath, CODESET_FILESYS); rmi->status_callback (rmi, RM_TRACK_DONE, (void*)fullpath); return SR_SUCCESS; }
void compose_metadata(RIP_MANAGER_INFO * rmi, TRACK_INFO * ti) { int num_bytes; unsigned char num_16_bytes; mchar w_composed_metadata[MAX_METADATA_LEN + 1]; if (ti->have_track_info) { if (ti->artist[0]) { msnprintf(w_composed_metadata, MAX_METADATA_LEN, m_("StreamTitle='") m_S m_(" - ") m_S m_("';"), ti->artist, ti->title); } else { msnprintf(w_composed_metadata, MAX_METADATA_LEN, m_("StreamTitle='") m_S m_("';"), ti->title); } } else { debug_printf("No track info when composing relay metadata\n"); } debug_printf("Converting relay string to char\n"); num_bytes = string_from_gstring(rmi, &ti->composed_metadata[1], MAX_METADATA_LEN, w_composed_metadata, CODESET_RELAY); ti->composed_metadata[MAX_METADATA_LEN] = 0; // note, not LEN-1 num_16_bytes = (num_bytes + 15) / 16; ti->composed_metadata[0] = num_16_bytes; }
uschar * rfc2047_decode2(uschar *string, BOOL lencheck, uschar *target, int zeroval, int *lenptr, int *sizeptr, uschar **error) { int size = Ustrlen(string); size_t dlen; uschar *dptr; gstring *yield; uschar *mimeword, *q1, *q2, *endword; *error = NULL; mimeword = decode_mimeword(string, lencheck, &q1, &q2, &endword, &dlen, &dptr); if (!mimeword) { if (lenptr) *lenptr = size; return string; } /* Scan through the string, decoding MIME words and copying intermediate text, building the result as we go. The result may be longer than the input if it is translated into a multibyte code such as UTF-8. That's why we use the dynamic string building code. */ yield = store_get(sizeof(gstring) + ++size); yield->size = size; yield->ptr = 0; yield->s = US(yield + 1); while (mimeword) { #if HAVE_ICONV iconv_t icd = (iconv_t)(-1); #endif if (mimeword != string) yield = string_catn(yield, string, mimeword - string); /* Do a charset translation if required. This is supported only on hosts that have the iconv() function. Translation errors set error, but carry on, using the untranslated data. If there is more than one error, the message passed back refers to the final one. We use a loop to cater for the case of long strings - the RFC puts limits on the length, but it's best to be robust. */ #if HAVE_ICONV *q1 = 0; if (target != NULL && strcmpic(target, mimeword+2) != 0) { icd = iconv_open(CS target, CS(mimeword+2)); if (icd == (iconv_t)(-1)) { *error = string_sprintf("iconv_open(\"%s\", \"%s\") failed: %s%s", target, mimeword+2, strerror(errno), (errno == EINVAL)? " (maybe unsupported conversion)" : ""); } } *q1 = '?'; #endif while (dlen > 0) { uschar *tptr = NULL; /* Stops compiler warning */ int tlen = -1; #if HAVE_ICONV uschar tbuffer[256]; uschar *outptr = tbuffer; size_t outleft = sizeof(tbuffer); /* If translation is required, go for it. */ if (icd != (iconv_t)(-1)) { (void)iconv(icd, (ICONV_ARG2_TYPE)(&dptr), &dlen, CSS &outptr, &outleft); /* If outptr has been adjusted, there is some output. Set up to add it to the output buffer. The function will have adjusted dptr and dlen. If iconv() stopped because of an error, we'll pick it up next time when there's no output. If there is no output, we expect there to have been a translation error, because we know there was at least one input byte. We leave the value of tlen as -1, which causes the rest of the input to be copied verbatim. */ if (outptr > tbuffer) { tptr = tbuffer; tlen = outptr - tbuffer; } else { DEBUG(D_any) debug_printf("iconv error translating \"%.*s\" to %s: " "%s\n", (int)(endword + 2 - mimeword), mimeword, target, strerror(errno)); } } #endif /* No charset translation is happening or there was a translation error; just set up the original as the string to be added, and mark it all used. */ if (tlen == -1) { tptr = dptr; tlen = dlen; dlen = 0; } /* Deal with zero values; convert them if requested. */ if (zeroval != 0) for (int i = 0; i < tlen; i++) if (tptr[i] == 0) tptr[i] = zeroval; /* Add the new string onto the result */ yield = string_catn(yield, tptr, tlen); } #if HAVE_ICONV if (icd != (iconv_t)(-1)) iconv_close(icd); #endif /* Update string past the MIME word; skip any white space if the next thing is another MIME word. */ string = endword + 2; mimeword = decode_mimeword(string, lencheck, &q1, &q2, &endword, &dlen, &dptr); if (mimeword) { uschar *s = string; while (isspace(*s)) s++; if (s == mimeword) string = s; } } /* Copy the remaining characters of the string, zero-terminate it, and return the length as well if requested. */ yield = string_cat(yield, string); if (lenptr) *lenptr = yield->ptr; if (sizeptr) *sizeptr = yield->size; return string_from_gstring(yield); }