// new Function([arg1[, arg2[, ...]],] functionBody) js_val * func_new(js_val *instance, js_args *args, eval_state *state) { unsigned arglen = ARGLEN(args); unsigned i = 0; char *arg_lst = NULL; char *tmp; for (i = 0; arglen > 0 && i < (arglen - 1); i++) { if (!arg_lst) { arg_lst = TO_STR(ARG(args, i))->string.ptr; } else { tmp = arg_lst; arg_lst = fh_str_concat(arg_lst, ", "); free(tmp); tmp = arg_lst; arg_lst = fh_str_concat(arg_lst, TO_STR(ARG(args, i))->string.ptr); free(tmp); } } if (arglen <= 1) arg_lst = ""; char *body = arglen > 0 ? TO_STR(ARG(args, i))->string.ptr : ""; char *fmt = "(function(%s) { %s });"; int size = snprintf(NULL, 0, fmt, arg_lst, body) + 1; char *func_def = malloc(size); snprintf(func_def, size, fmt, arg_lst, body); return fh_eval_string(func_def, state->ctx); }
void mprintf(const char *str, ...) { va_list args; FILE *fd; char buffer[512], *abuffer = NULL, *buff; size_t len; if(mprintf_disabled) return; fd = stdout; /* legend: * ! - error * @ - error with logging * ... */ /* * ERROR WARNING STANDARD * normal stderr stderr stdout * * verbose stderr stderr stdout * * quiet stderr no no */ ARGLEN(args, str, len); if(len <= sizeof(buffer)) { len = sizeof(buffer); buff = buffer; } else { abuffer = malloc(len); if(!abuffer) { len = sizeof(buffer); buff = buffer; } else { buff = abuffer; } } va_start(args, str); vsnprintf(buff, len, str, args); va_end(args); buff[len - 1] = 0; #ifdef _WIN32 do { int tmplen = len + 1; wchar_t *tmpw = malloc(tmplen*sizeof(wchar_t)); char *nubuff; if(!tmpw) break; if(!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buff, -1, tmpw, tmplen)) { free(tmpw); break; } /* FIXME CHECK IT'S REALLY UTF8 */ nubuff = (char *)malloc(tmplen); if(!nubuff) { free(tmpw); break; } if(!WideCharToMultiByte(CP_OEMCP, 0, tmpw, -1, nubuff, tmplen, NULL, NULL)) { free(nubuff); free(tmpw); break; } free(tmpw); if(len > sizeof(buffer)) free(abuffer); abuffer = buff = nubuff; len = sizeof(buffer) + 1; } while(0); #endif if(buff[0] == '!') { if(!mprintf_stdout) fd = stderr; fprintf(fd, "ERROR: %s", &buff[1]); } else if(buff[0] == '@') { if(!mprintf_stdout) fd = stderr; fprintf(fd, "ERROR: %s", &buff[1]); } else if(!mprintf_quiet) { if(buff[0] == '^') { if(!mprintf_nowarn) { if(!mprintf_stdout) fd = stderr; fprintf(fd, "WARNING: %s", &buff[1]); } } else if(buff[0] == '*') { if(mprintf_verbose) fprintf(fd, "%s", &buff[1]); } else if(buff[0] == '~') { fprintf(fd, "%s", &buff[1]); } else fprintf(fd, "%s", buff); } if(fd == stdout) fflush(stdout); if(len > sizeof(buffer)) free(abuffer); }
/* * legend: * ! - ERROR: * ^ - WARNING: * ~ - normal * # - normal, not foreground (logfile and syslog only) * * - verbose * $ - debug * none - normal * * Default Foreground LogVerbose Debug Syslog * ! yes mprintf yes yes LOG_ERR * ^ yes mprintf yes yes LOG_WARNING * ~ yes mprintf yes yes LOG_INFO * # yes no yes yes LOG_INFO * * no mprintf yes yes LOG_DEBUG * $ no mprintf no yes LOG_DEBUG * none yes mprintf yes yes LOG_INFO */ int logg(const char *str, ...) { va_list args; char buffer[1025], *abuffer = NULL, *buff; time_t currtime; size_t len; mode_t old_umask; #ifdef F_WRLCK struct flock fl; #endif if ((*str == '$' && logg_verbose < 2) || (*str == '*' && !logg_verbose)) return 0; ARGLEN(args, str, len); if(len <= sizeof(buffer)) { len = sizeof(buffer); buff = buffer; } else { abuffer = malloc(len); if(!abuffer) { len = sizeof(buffer); buff = buffer; } else { buff = abuffer; } } va_start(args, str); vsnprintf(buff, len, str, args); va_end(args); buff[len - 1] = 0; #ifdef CL_THREAD_SAFE pthread_mutex_lock(&logg_mutex); #endif logg_open(); if(!logg_fp && logg_file) { old_umask = umask(0037); if((logg_fp = fopen(logg_file, "at")) == NULL) { umask(old_umask); #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&logg_mutex); #endif printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file); if(len > sizeof(buffer)) free(abuffer); return -1; } else umask(old_umask); #ifdef F_WRLCK if(logg_lock) { memset(&fl, 0, sizeof(fl)); fl.l_type = F_WRLCK; if(fcntl(fileno(logg_fp), F_SETLK, &fl) == -1) { #ifdef EOPNOTSUPP if(errno == EOPNOTSUPP) printf("WARNING: File locking not supported (NFS?)\n"); else #endif { #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&logg_mutex); #endif printf("ERROR: %s is locked by another process\n", logg_file); if(len > sizeof(buffer)) free(abuffer); return -1; } } } #endif } if(logg_fp) { char flush = !logg_noflush; /* Need to avoid logging time for verbose messages when logverbose is not set or we get a bunch of timestamps in the log without newlines... */ if(logg_time && ((*buff != '*') || logg_verbose)) { char timestr[32]; time(&currtime); cli_ctime(&currtime, timestr, sizeof(timestr)); /* cut trailing \n */ timestr[strlen(timestr)-1] = '\0'; fprintf(logg_fp, "%s -> ", timestr); } if(*buff == '!') { fprintf(logg_fp, "ERROR: %s", buff + 1); flush = 1; } else if(*buff == '^') { if(!logg_nowarn) fprintf(logg_fp, "WARNING: %s", buff + 1); flush = 1; } else if(*buff == '*' || *buff == '$') { fprintf(logg_fp, "%s", buff + 1); } else if(*buff == '#' || *buff == '~') { fprintf(logg_fp, "%s", buff + 1); } else fprintf(logg_fp, "%s", buff); if (flush) fflush(logg_fp); } if(logg_foreground) { if(buff[0] != '#') mprintf("%s", buff); } #if defined(USE_SYSLOG) && !defined(C_AIX) if(logg_syslog) { cli_chomp(buff); if(buff[0] == '!') { syslog(LOG_ERR, "%s", buff + 1); } else if(buff[0] == '^') { if(!logg_nowarn) syslog(LOG_WARNING, "%s", buff + 1); } else if(buff[0] == '*' || buff[0] == '$') { syslog(LOG_DEBUG, "%s", buff + 1); } else if(buff[0] == '#' || buff[0] == '~') { syslog(LOG_INFO, "%s", buff + 1); } else syslog(LOG_INFO, "%s", buff); } #endif #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&logg_mutex); #endif if(len > sizeof(buffer)) free(abuffer); return 0; }
int mdprintf(int desc, const char *str, ...) { va_list args; char buffer[512], *abuffer = NULL, *buff; int bytes, todo, ret=0; size_t len; ARGLEN(args, str, len); if(len <= sizeof(buffer)) { len = sizeof(buffer); buff = buffer; } else { abuffer = malloc(len); if(!abuffer) { len = sizeof(buffer); buff = buffer; } else { buff = abuffer; } } va_start(args, str); bytes = vsnprintf(buff, len, str, args); va_end(args); buff[len - 1] = 0; if(bytes < 0) { if(len > sizeof(buffer)) free(abuffer); return bytes; } if((size_t) bytes >= len) bytes = len - 1; todo = bytes; #ifdef CL_THREAD_SAFE /* make sure we don't mix sends from multiple threads, * important for IDSESSION */ pthread_mutex_lock(&mdprintf_mutex); #endif while (todo > 0) { ret = send(desc, buff, bytes, 0); if (ret < 0) { struct timeval tv; if (errno != EWOULDBLOCK) break; /* didn't send anything yet */ #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&mdprintf_mutex); #endif tv.tv_sec = 0; tv.tv_usec = mprintf_send_timeout*1000; do { fd_set wfds; FD_ZERO(&wfds); FD_SET(desc, &wfds); ret = select(desc+1, NULL, &wfds, NULL, &tv); } while (ret < 0 && errno == EINTR); #ifdef CL_THREAD_SAFE pthread_mutex_lock(&mdprintf_mutex); #endif if (!ret) { /* timed out */ ret = -1; break; } } else { todo -= ret; buff += ret; } } #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&mdprintf_mutex); #endif if(len > sizeof(buffer)) free(abuffer); return ret < 0 ? -1 : bytes; }
azt_val * print_sayln(azt_val *instance, azt_args *args, eval_state *state) { unsigned i; for (i = 0; i < ARGLEN(args); i++) fh_debug(stdout, fh_to_primitive(ARG(args, i), T_STRING), 0, 1); return AZTUNDEF(); }