const std::string& str(bool utf8) // returns UTF-8 encoded buffer content { #if defined(_WIN32) && !defined(XS_STRING_UTF8) if (utf8) #endif _buffer_str.assign(_buffer, _wptr-_buffer); #if defined(_WIN32) && !defined(XS_STRING_UTF8) else _buffer_str = get_utf8(_buffer, _wptr-_buffer); #endif return _buffer_str; }
/** @brief Collect characters into a character string. @param parser Pointer to a Parser. @return Pointer to parser->str_buf if successful, or NULL upon error. Translate the usual escape sequences. In particular, "\u" escapes a sequence of four hex characters; turn the hex into the corresponding UTF-8 byte sequence. Return the string we have built, without the enclosing quotation marks, in parser->str_buf. In case of error, log an error message. */ static const char* get_string( Parser* parser ) { if( parser->str_buf ) buffer_reset( parser->str_buf ); else parser->str_buf = buffer_init( 64 ); growing_buffer* gb = parser->str_buf; // Collect the characters. for( ;; ) { char c = parser_nextc( parser ); if( '"' == c ) break; else if( !c ) { report_error( parser, parser->buff[ parser->index - 1 ], "Quoted string not terminated" ); return NULL; } else if( '\\' == c ) { c = parser_nextc( parser ); switch( c ) { case '"' : OSRF_BUFFER_ADD_CHAR( gb, '"' ); break; case '\\' : OSRF_BUFFER_ADD_CHAR( gb, '\\' ); break; case '/' : OSRF_BUFFER_ADD_CHAR( gb, '/' ); break; case 'b' : OSRF_BUFFER_ADD_CHAR( gb, '\b' ); break; case 'f' : OSRF_BUFFER_ADD_CHAR( gb, '\f' ); break; case 'n' : OSRF_BUFFER_ADD_CHAR( gb, '\n' ); break; case 'r' : OSRF_BUFFER_ADD_CHAR( gb, '\r' ); break; case 't' : OSRF_BUFFER_ADD_CHAR( gb, '\t' ); break; case 'u' : { Unibuff unibuff; if( get_utf8( parser, &unibuff ) ) { return NULL; // bad UTF-8 } else if( unibuff.buff[0] ) { OSRF_BUFFER_ADD( gb, (char*) unibuff.buff ); } else { report_error( parser, 'u', "Unicode sequence encodes a nul byte" ); return NULL; } break; } default : OSRF_BUFFER_ADD_CHAR( gb, c ); break; } } else OSRF_BUFFER_ADD_CHAR( gb, c ); } return OSRF_BUFFER_C_STR( gb ); }
static void parse_dive_cylinder(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; cylinder_t *cylinder = dive->cylinder + cylinder_index; cylinder_index++; cylinder->type.description = get_utf8(str); for (;;) { char c; while (isspace(c = *line)) line++; if (!c) break; line = parse_keyvalue_entry(parse_cylinder_keyvalue, cylinder, line); } }
static void parse_dive_weightsystem(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; weightsystem_t *ws = dive->weightsystem + weightsystem_index; weightsystem_index++; ws->description = get_utf8(str); for (;;) { char c; while (isspace(c = *line)) line++; if (!c) break; line = parse_keyvalue_entry(parse_weightsystem_keyvalue, ws, line); } }
static void parse_dive_location(char *line, struct membuffer *str, void *_dive) { uint32_t uuid; char *name = get_utf8(str); struct dive *dive = _dive; struct dive_site *ds = get_dive_site_for_dive(dive); if (!ds) { uuid = get_dive_site_uuid_by_name(name, NULL); if (!uuid) uuid = create_dive_site(name, dive->when); dive->dive_site_uuid = uuid; } else { // we already had a dive site linked to the dive if (same_string(ds->name, "")) { ds->name = strdup(name); } else { // and that dive site had a name. that's weird - if our name is different, add it to the notes if (!same_string(ds->name, name)) ds->notes = add_to_string(ds->notes, translate("gettextFromC", "additional name for site: %s\n"), name); } } free(name); }
static void parse_dive_notes(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; dive->notes = get_utf8(str); }
static void parse_dive_suit(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; dive->suit = get_utf8(str); }
static void parse_dive_buddy(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; dive->buddy = get_utf8(str); }
static void parse_picture_filename(char *line, struct membuffer *str, void *_pic) { struct picture *pic = _pic; pic->filename = get_utf8(str); }
static void parse_trip_location(char *line, struct membuffer *str, void *_trip) { dive_trip_t *trip = _trip; trip->location = get_utf8(str); }
static void parse_picture_hash(char *line, struct membuffer *str, void *_pic) { struct picture *pic = _pic; pic->hash = get_utf8(str); }
/// encode XML string literals std::string EncodeXMLString(const XS_String& str, bool cdata) { LPCXSSTR s = str.c_str(); size_t l = XS_len(s); if (cdata) { // encode the whole string in a CDATA section std::string ret = CDATA_START; #ifdef XS_STRING_UTF8 ret += str; #else ret += get_utf8(str); #endif ret += CDATA_END; return ret; } else if (l <= BUFFER_LEN) { LPXSSTR buffer = (LPXSSTR)alloca(6*sizeof(XS_CHAR)*XS_len(s)); // worst case """ / "'" LPXSSTR o = buffer; for(LPCXSSTR p=s; *p; ++p) switch(*p) { case '&': *o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';'; // "&" break; case '<': *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';'; // "<" break; case '>': *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';'; // ">" break; case '"': *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';'; // """ break; case '\'': *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';'; // "'" break; default: if ((unsigned)*p<0x20 && *p!='\t' && *p!='\r' && *p!='\n') { char b[16]; sprintf(b, "&#%d;", (unsigned)*p); for(const char*q=b; *q; ) *o++ = *q++; } else *o++ = *p; } #ifdef XS_STRING_UTF8 return XS_String(buffer, o-buffer); #else return get_utf8(buffer, o-buffer); #endif } else { // l > BUFFER_LEN // alternative code for larger strings using ostringstream // and avoiding to use alloca() for preallocated memory fast_ostringstream out; LPCXSSTR s = str.c_str(); for(LPCXSSTR p=s; *p; ++p) switch(*p) { case '&': out << "&"; break; case '<': out << "<"; break; case '>': out << ">"; break; case '"': out << """; break; case '\'': out << "'"; break; default: if ((unsigned)*p<0x20 && *p!='\t' && *p!='\r' && *p!='\n') out << "&#" << (unsigned)*p << ";"; else out << *p; } #ifdef XS_STRING_UTF8 return XS_String(out.str()); #else return get_utf8(out.str()); #endif } }
static Int rl_to_codes(Term TEnd, int do_as_binary, int arity USES_REGS) { int sno = Yap_CheckStream(ARG1, Input_Stream_f, "read_line_to_codes/2"); StreamDesc *st = GLOBAL_Stream + sno; Int status; UInt max_inp, buf_sz, sz; unsigned char *buf; bool binary_stream; int ch; if (sno < 0) return false; status = GLOBAL_Stream[sno].status; binary_stream = GLOBAL_Stream[sno].status & Binary_Stream_f; if (status & Eof_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof)); } max_inp = (ASP - HR) / 2 - 1024; buf = (unsigned char *)TR; buf_sz = (unsigned char *)LOCAL_TrailTop - buf; while (true) { if (buf_sz > max_inp) { buf_sz = max_inp; } if (do_as_binary && !binary_stream) { GLOBAL_Stream[sno].status |= Binary_Stream_f; } if (st->status & Binary_Stream_f) { char *b = (char *)TR; sz = fread(b, 1, buf_sz, GLOBAL_Stream[sno].file); } else { unsigned char *pt = buf; do { ch = st->stream_wgetc_for_read(sno); if (ch < 127) { *pt++ = ch; if (ch < 0) { ch = '\n'; pt[-1] = '\n'; } } else { pt += get_utf8(pt, 4, &ch); if (pt + 4 == buf + buf_sz) break; } } while (ch != '\n'); sz = pt - buf; } if (do_as_binary && !binary_stream) GLOBAL_Stream[sno].status &= ~Binary_Stream_f; if (sz == -1 || sz == 0) { if (GLOBAL_Stream[sno].status & Eof_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof)); } UNLOCK(GLOBAL_Stream[sno].streamlock); } if (GLOBAL_Stream[sno].status & Eof_Stream_f || buf[sz - 1] == 10) { /* we're done */ Term end; if (!(do_as_binary || GLOBAL_Stream[sno].status & Eof_Stream_f)) { UNLOCK(GLOBAL_Stream[sno].streamlock); /* handle CR before NL */ if ((Int)sz - 2 >= 0 && buf[sz - 2] == 13) buf[sz - 2] = '\0'; else buf[sz - 1] = '\0'; } else { UNLOCK(GLOBAL_Stream[sno].streamlock); } if (arity == 2) end = TermNil; else end = Deref(XREGS[arity]); return Yap_unify( ARG2, Yap_UTF8ToDiffListOfCodes((const char *)TR, end PASS_REGS)); } buf += (buf_sz - 1); max_inp -= (buf_sz - 1); if (max_inp <= 0) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(RESOURCE_ERROR_STACK, ARG1, "read_line_to_codes/%d", arity); return FALSE; } } }
static Int read_line_to_string(USES_REGS1) { int sno = Yap_CheckStream(ARG1, Input_Stream_f, "read_line_to_codes/2"); Int status; UInt max_inp, buf_sz; unsigned char *buf; size_t sz; StreamDesc *st = GLOBAL_Stream + sno; int ch; if (sno < 0) return false; status = GLOBAL_Stream[sno].status; if (status & Eof_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof)); } max_inp = (ASP - HR) / 2 - 1024; buf = (unsigned char *)TR; buf_sz = (unsigned char *)LOCAL_TrailTop - buf; if (buf_sz > max_inp) { buf_sz = max_inp; } if (st->status & Binary_Stream_f) { char *b = (char *)TR; sz = fread(b, 1, buf_sz, GLOBAL_Stream[sno].file); } else { unsigned char *pt = buf; do { ch = st->stream_wgetc_for_read(sno); if (ch < 127) { *pt++ = ch; if (ch < 0) { ch = '\n'; pt[-1] = '\n'; } } else { pt += get_utf8(pt, 4, &ch); if (pt + 4 == buf + buf_sz) break; } } while (ch != '\n'); sz = pt - buf; } if (sz == -1 || sz == 0) { if (GLOBAL_Stream[sno].status & Eof_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof)); } UNLOCK(GLOBAL_Stream[sno].streamlock); return false; } if (GLOBAL_Stream[sno].status & Eof_Stream_f || buf[sz - 1] == 10) { /* we're done */ if (!(GLOBAL_Stream[sno].status & Eof_Stream_f)) { UNLOCK(GLOBAL_Stream[sno].streamlock); /* handle CR before NL */ if ((Int)sz - 2 >= 0 && buf[sz - 2] == 13) buf[sz - 2] = '\0'; else { buf[sz - 1] = '\0'; } } else { UNLOCK(GLOBAL_Stream[sno].streamlock); } } if (GLOBAL_Stream[sno].encoding == ENC_ISO_UTF8) { return Yap_unify(ARG2, Yap_UTF8ToString((const char *)TR PASS_REGS)); } else if (GLOBAL_Stream[sno].encoding == ENC_WCHAR) { return Yap_unify(ARG2, Yap_WCharsToString((const wchar_t *)TR PASS_REGS)); } else { return Yap_unify( ARG2, Yap_CharsToString((const char *)TR, ENC_ISO_LATIN1 PASS_REGS)); } buf += (buf_sz - 1); max_inp -= (buf_sz - 1); if (max_inp <= 0) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(RESOURCE_ERROR_STACK, ARG1, NULL); return FALSE; } }
jboolean Java_com_caucho_bootjni_JniProcess_exec(JNIEnv *env, jobject obj, jobjectArray j_argv, jobjectArray j_envp, jstring j_chroot, jstring j_pwd, jstring j_user, jstring j_group) { char **argv; char **envp; char chroot_path[4096]; char pwd[4096]; char user[256]; char group[256]; int uid = -1; int gid = -1; int len; int i; int pipe_fds[2]; int pid; jclass c_jni_process; jfieldID f_stdoutFd; jfieldID f_pid; #ifdef WIN32 if (1) return -1; #endif /* WIN32 */ user[0] = 0; group[0] = 0; chroot_path[0] = 0; if (! j_argv) { resin_printf_exception(env, "java/lang/NullPointerException", "argv"); return 0; } if (! j_envp) { resin_printf_exception(env, "java/lang/NullPointerException", "argv"); return 0; } if (! j_pwd) { resin_printf_exception(env, "java/lang/NullPointerException", "pwd"); return 0; } c_jni_process = (*env)->FindClass(env, "com/caucho/bootjni/JniProcess"); if (! c_jni_process) { resin_printf_exception(env, "java/lang/NullPointerException", "can't load JniProcess"); return 0; } f_stdoutFd = (*env)->GetFieldID(env, c_jni_process, "_stdoutFd", "I"); if (! f_stdoutFd) { resin_printf_exception(env, "java/lang/NullPointerException", "can't load field"); return 0; } f_pid = (*env)->GetFieldID(env, c_jni_process, "_pid", "I"); if (! f_pid) { resin_printf_exception(env, "java/lang/NullPointerException", "can't load field"); return 0; } len = (*env)->GetArrayLength(env, j_argv); argv = malloc((len + 1) * sizeof(char*)); argv[len] = 0; for (i = 0; i < len; i++) { jstring j_string; j_string = (*env)->GetObjectArrayElement(env, j_argv, i); if (j_string) { int strlen = (*env)->GetStringUTFLength(env, j_string); argv[i] = (char *) malloc(strlen + 1); argv[i] = get_utf8(env, j_string, argv[i], strlen + 1); } } len = (*env)->GetArrayLength(env, j_envp); envp = malloc((len + 1) * sizeof(char*)); envp[len] = 0; for (i = 0; i < len; i++) { jstring j_string; j_string = (*env)->GetObjectArrayElement(env, j_envp, i); if (j_string) { int strlen = (*env)->GetStringUTFLength(env, j_string); envp[i] = (char *) malloc(strlen + 1); envp[i] = get_utf8(env, j_string, envp[i], strlen + 1); } } if (j_chroot) { int strlen = (*env)->GetStringUTFLength(env, j_chroot); get_utf8(env, j_chroot, chroot_path, strlen + 1); } else chroot_path[0] = 0; if (j_pwd) { int strlen = (*env)->GetStringUTFLength(env, j_pwd); get_utf8(env, j_pwd, pwd, strlen + 1); } #ifndef WIN32 if (j_user) { struct passwd *passwd; int strlen = (*env)->GetStringUTFLength(env, j_user); get_utf8(env, j_user, user, strlen + 1); passwd = getpwnam(user); if (! passwd) { resin_printf_exception(env, "java/lang/IllegalArgumentException", "%s is an unknown user", user); return 0; } uid = passwd->pw_uid; gid = passwd->pw_gid; } if (j_group) { struct group *group_ent; int strlen = (*env)->GetStringUTFLength(env, j_group); get_utf8(env, j_group, group, strlen + 1); group_ent = getgrnam(group); if (! group_ent) { resin_printf_exception(env, "java/lang/IllegalArgumentException", "%s is an unknown group", group); return 0; } gid = group_ent->gr_gid; } pipe(pipe_fds); pid = fork(); if (pid > 0) { close(pipe_fds[1]); (*env)->SetIntField(env, obj, f_stdoutFd, pipe_fds[0]); (*env)->SetIntField(env, obj, f_pid, pid); return 1; } else if (pid < 0) { close(pipe_fds[0]); close(pipe_fds[1]); resin_printf_exception(env, "java/lang/NullPointerException", "can't fork"); return 0; } close(pipe_fds[0]); /* if (fork()) exit(0); setsid(); */ #ifndef WIN32 if (chroot_path[0]) { chroot(chroot_path); } #endif if (gid >= 0) setregid(gid, gid); if (uid >= 0) { setreuid(uid, uid); if (getuid() != uid) { fprintf(stderr, "Can't setuid to %d, received %d\n", uid, getuid()); exit(1); } } chdir(pwd); #endif dup2(pipe_fds[1], 1); dup2(pipe_fds[1], 2); for (i = 0; envp[i]; i++) putenv(envp[i]); execvp(argv[0], argv); fprintf(stderr, "exec failed %s -> %d\n", argv[0], errno); exit(1); return -1; }
static void parse_dc_model(char *line, struct membuffer *str, void *_dc) { struct divecomputer *dc = _dc; dc->model = get_utf8(str); }
static void parse_dive_location(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; dive->location = get_utf8(str); }
static void parse_trip_notes(char *line, struct membuffer *str, void *_trip) { dive_trip_t *trip = _trip; trip->notes = get_utf8(str); }
static void parse_dive_divemaster(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; dive->divemaster = get_utf8(str); }
/* input line with encoding conversion */ long input_line2(FILE *fp, unsigned char *buff, long pos, const long buffsize, int *lastchar) { long i; static boolean injis = false; const int fd = fileno(fp); if (infile_enc[fd] == ENC_UNKNOWN) { /* just after opened */ ungetbuff[fd].size = 0; if (isUTF8Nstream(fp)) infile_enc[fd] = ENC_UTF8; else infile_enc[fd] = get_file_enc(); } buffer = buff; first = last = pos; while (last < buffsize-30 && (i=getc4(fp)) != EOF && i!='\n' && i!='\r') { /* 30 is enough large size for one char */ /* attention: 4 times of write_hex() eats 16byte */ #ifdef WIN32 if (i == 0x1a && first == last && fd == fileno(stdin) && _isatty(fd)) { /* Ctrl+Z on console */ i = EOF; break; } else #endif if (i == ESC) { if ((i=getc4(fp)) == '$') { /* ESC '$' (Kanji-in) */ i = getc4(fp); if (i == '@' || i == 'B') { injis = true; } else { /* broken Kanji-in */ buffer[last++] = ESC; buffer[last++] = '$'; if (is_tail(&i, fp)) break; buffer[last++] = i; } } else if (i == '(') { /* ESC '(' (Kanji-out) */ i = getc4(fp); if (i == 'J' || i == 'B' || i == 'H') { injis = false; } else { /* broken Kanji-out */ buffer[last++] = ESC; buffer[last++] = '('; if (is_tail(&i, fp)) break; buffer[last++] = i; } } else { /* broken ESC */ buffer[last++] = ESC; if (is_tail(&i, fp)) break; buffer[last++] = i; } } else { /* rather than ESC */ if (injis) { /* in JIS */ long j = getc4(fp); if (is_tail(&j, fp)) { buffer[last++] = i; i = j; break; } else { /* JIS encoding */ i = fromJIS(HILO(i,j)); if (i == 0) i = fromUCS(U_REPLACEMENT_CHARACTER); write_multibyte(toBUFF(i)); } } else { /* normal */ if (infile_enc[fd] == ENC_SJIS && isSJISkanji1(i)) { get_sjis(i, fp); } else if (infile_enc[fd] == ENC_EUC && isEUCkanji1(i)) { get_euc(i, fp); } else if (infile_enc[fd] == ENC_UTF8 && UTF8length(i) > 1) { get_utf8(i, fp); } else { buffer[last++] = i; } } } } buffer[last] = '\0'; if (i == EOF || i == '\n' || i == '\r') injis = false; if (lastchar != NULL) *lastchar = i; return last; }
JNIEXPORT jint JNICALL Java_com_caucho_server_boot_ResinBoot_execDaemon(JNIEnv *env, jobject obj, jobjectArray j_argv, jobjectArray j_envp, jstring j_pwd) { char **argv; char **envp; char *pwd; int len; int i; if (! j_argv) resin_printf_exception(env, "java/lang/NullPointerException", "argv"); if (! j_envp) resin_printf_exception(env, "java/lang/NullPointerException", "argv"); if (! j_pwd) resin_printf_exception(env, "java/lang/NullPointerException", "pwd"); #ifdef WIN32 resin_printf_exception(env, "java/lang/UnsupportedOperationException", "win32"); #else len = (*env)->GetArrayLength(env, j_argv); argv = malloc((len + 1) * sizeof(char*)); argv[len] = 0; for (i = 0; i < len; i++) { jstring j_string; j_string = (*env)->GetObjectArrayElement(env, j_argv, i); if (j_string) { int strlen = (*env)->GetStringUTFLength(env, j_string); argv[i] = (char *) malloc(strlen + 1); argv[i] = get_utf8(env, j_string, argv[i], strlen + 1); } } len = (*env)->GetArrayLength(env, j_envp); envp = malloc((len + 1) * sizeof(char*)); envp[len] = 0; for (i = 0; i < len; i++) { jstring j_string; j_string = (*env)->GetObjectArrayElement(env, j_envp, i); if (j_string) { int strlen = (*env)->GetStringUTFLength(env, j_string); envp[i] = (char *) malloc(strlen + 1); envp[i] = get_utf8(env, j_string, envp[i], strlen + 1); } } { int strlen = (*env)->GetStringUTFLength(env, j_pwd); char *pwd; pwd = (char *) malloc(strlen + 1); pwd = get_utf8(env, j_pwd, pwd, strlen + 1); chdir(pwd); } if (fork()) return 1; if (fork()) exit(0); #ifndef WIN32 setsid(); #endif /* WIN32 */ execve(argv[0], argv, envp); fprintf(stderr, "exec failed %s -> %d\n", argv[0], errno); exit(1); #endif return -1; }