void close_record( void ) { /* Close recording file */ if ( rfp != NULL ) { fclose( rfp ); rfp = NULL; /* Cleanup */ if ( recording == ON ) { file_cleanup( record_name, GAME_RECORD ); } else /* (replaying == ON) */ { file_cleanup( record_name, GAME_PLAYBACK ); } } /* Set recording and replaying off */ recording = OFF; replaying = OFF; } /* close_record */
/* * close_script * * Close the scripting file. * */ void close_script( void ) { /* Close scripting file if open */ if ( scripting == ON ) { fclose( sfp ); #if 0 /* Cleanup */ file_cleanup( script_name, GAME_SCRIPT ); #endif /* Turn off scripting */ scripting = OFF; } /* Set the scripting flag in the game file flags */ if ( scripting == OFF ) { set_word( H_FLAGS, get_word( H_FLAGS ) & ( ~SCRIPTING_FLAG ) ); } else { set_word( H_FLAGS, get_word( H_FLAGS ) | SCRIPTING_FLAG ); } } /* close_script */
/** * Handles an ABORT message from a server */ void handle_abort(struct group_list_t *group, const unsigned char *message, unsigned meslen) { const struct abort_h *abort_hdr; int found; abort_hdr = (const struct abort_h *)message; if (meslen < (abort_hdr->hlen * 4U) || ((abort_hdr->hlen * 4U) < sizeof(struct abort_h))) { glog1(group, "Rejecting ABORT from server: invalid message size"); return; } found = 0; if (abort_hdr->host == 0) { if (((abort_hdr->flags & FLAG_CURRENT_FILE) != 0) && (group->phase == PHASE_MIDGROUP)) { found = 0; } else { found = 1; } } else if (abort_hdr->host == uid) { found = 1; } if (found) { glog1(group, "Transfer aborted by server: %s", abort_hdr->message); flush_disk_cache(group); file_cleanup(group, 1); } }
/* Module functions */ static int init(const struct mpdcron_config *conf, GKeyFile *fd) { GError *error; g_debug("Initializing"); /* Load configuration */ if (file_load(conf, fd) < 0) return MPDCRON_INIT_FAILURE; /* Initialize database */ error = NULL; if (!db_init(globalconf.dbpath, true, false, &error)) { g_critical("Failed to initialize database `%s': %s", globalconf.dbpath, error->message); g_error_free(error); file_cleanup(); return MPDCRON_INIT_FAILURE; } /* Initialize, bind and start the server */ server_init(); for (unsigned int i = 0; globalconf.addrs[i] != NULL; i++) { if (strncmp(globalconf.addrs[i], "any", 4) == 0) server_bind(NULL, globalconf.port); else if (globalconf.addrs[i][0] == '/') server_bind(globalconf.addrs[i], -1); else server_bind(globalconf.addrs[i], globalconf.port); } server_start(); timer = g_timer_new(); return MPDCRON_INIT_SUCCESS; }
static int file_daq_stop (void* handle) { FileImpl* impl = (FileImpl*)handle; file_cleanup(impl); impl->state = DAQ_STATE_STOPPED; return DAQ_SUCCESS; }
int if_file_exists(const char* path) { int exists; file_t file; file_init(&file, path, 1); exists = (file_stat(&file) >= 0); file_cleanup(&file); return exists; }
/** * Handles an ABORT message from a server */ void handle_abort(int listidx, const unsigned char *message, int meslen) { struct abort_h *abort; struct uftp2_h *v2_header; const char *v2_message; int found, i; if (group_list[listidx].version == UFTP_V2_VER) { v2_header = (struct uftp2_h *)message; v2_message = (const char *)message + sizeof(struct uftp2_h); log0(group_list[listidx].group_id, group_list[listidx].file_id, "Transfer aborted by server: %s", v2_message); file_cleanup(listidx, 1); return; } abort = (struct abort_h *)message; if (meslen != sizeof(struct abort_h)) { log1(group_list[listidx].group_id, group_list[listidx].file_id, "Rejecting ABORT from server: invalid message size"); } if (abort->host == 0) { if (((abort->flags & FLAG_CURRENT_FILE) != 0) && (group_list[listidx].phase == PHASE_MIDGROUP)) { found = 0; } else { found = 1; } } else { for (i = 0, found = 0; (i < interface_count) && !found; i++) { if (abort->host == m_interface[i].addr.s_addr) { found = 1; } } } if (found) { log0(group_list[listidx].group_id, group_list[listidx].file_id, "Transfer aborted by server: %s", abort->message); file_cleanup(listidx, 1); } }
apr_status_t wapr_unix_file_cleanup(void *thefile) { wapr_file_t *file = thefile; apr_status_t flush_rv = APR_SUCCESS, rv = APR_SUCCESS; if (file->buffered) flush_rv = wapr_file_flush(file); rv = file_cleanup(file); return rv != APR_SUCCESS ? rv : flush_rv; }
static void destroy(void) { g_message("Exiting"); if (prev != NULL) mpd_song_free(prev); g_timer_destroy(timer); server_close(); db_close(); file_cleanup(); }
/** * Free memory allocated by the file_search_data structure */ void destroy_file_search_data(file_search_data* data) { size_t i; /* clean the memory allocated by file_t elements */ for (i = 0; i < data->root_files.size; i++) { file_t* file = get_root_file(data, i); file_cleanup(file); } rsh_blocks_vector_destroy(&data->root_files); }
int is_regular_file(const char* path) { int is_regular = 0; file_t file; file_init(&file, path, 1); if (file_stat(&file) >= 0) { is_regular = FILE_ISREG(&file); } file_cleanup(&file); return is_regular; }
static void destroy(void) { g_message("Exiting"); as_save_cache(); as_cleanup(); http_client_finish(); file_cleanup(); g_timer_destroy(timer); g_source_remove(save_source_id); if (prev != NULL) mpd_song_free(prev); }
/** * Sends an ABORT message to a server */ void send_abort(struct group_list_t *group, const char *message) { unsigned char *buf, *encrypted, *outpacket; struct uftp_h *header; struct abort_h *abort_hdr; int payloadlen, enclen; buf = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; abort_hdr = (struct abort_h *)(buf + sizeof(struct uftp_h)); set_uftp_header(header, ABORT, group); abort_hdr->func = ABORT; abort_hdr->hlen = sizeof(struct abort_h) / 4; abort_hdr->host = 0; strncpy(abort_hdr->message, message, sizeof(abort_hdr->message) - 1); payloadlen = sizeof(struct abort_h); if ((group->phase != PHASE_REGISTERED) && (group->keytype != KEY_NONE)) { encrypted = NULL; if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen, group->keytype, group->groupkey, group->groupsalt,&group->ivctr, group->ivlen, group->hashtype, group->grouphmackey, group->hmaclen, group->sigtype, group->keyextype, group->client_privkey, group->client_privkeylen)) { glog0(group, "Error encrypting ABORT"); free(buf); return; } outpacket = encrypted; payloadlen = enclen; } else { encrypted = NULL; outpacket = buf; } payloadlen += sizeof(struct uftp_h); if (nb_sendto(listener, outpacket, payloadlen, 0, (struct sockaddr *)&group->replyaddr, family_len(group->replyaddr)) == SOCKET_ERROR) { gsockerror(group, "Error sending ABORT"); } flush_disk_cache(group); file_cleanup(group, 1); free(buf); free(encrypted); }
/** * Cleanup routine set up by atexit */ void cleanup(void) { int i; for (i = 0; i < MAXLIST; i++) { if (group_list[i].group_id != 0) { send_abort(&group_list[i], "Client shutting down"); file_cleanup(&group_list[i], 1); } } if (!parent) { for (i = 0; i < pub_multi_count; i++) { if (server_count > 0) { multicast_leave(listener, 0, &pub_multi[i], m_interface, interface_count, server_keys, server_count); if (has_proxy) { multicast_leave(listener, 0, &pub_multi[i], m_interface, interface_count, &proxy_info, 1); } } else { multicast_leave(listener, 0, &pub_multi[i], m_interface, interface_count, NULL, 0); } } } closesocket(listener); for (i = 0; i < key_count; i++) { if (privkey_type[i] == KEYBLOB_RSA) { free_RSA_key(privkey[i].rsa); } else { free_EC_key(privkey[i].ec); } } crypto_cleanup(); #ifdef WINDOWS WSACleanup(); #endif close_log(); }
/** * Cleanup routine set up by atexit */ void cleanup(void) { int i; for (i = 0; i < MAXLIST; i++) { if (group_list[i].group_id != 0) { file_cleanup(i, 1); } } if (!parent) { for (i = 0; i < pub_multi_count; i++) { if (server_count > 0) { multicast_leave(listener, 0, &pub_multi[i], m_interface, interface_count, server_keys, server_count); if (has_proxy) { multicast_leave(listener, 0, &pub_multi[i], m_interface, interface_count, &proxy_info, 1); } } else { multicast_leave(listener, 0, &pub_multi[i], m_interface, interface_count, NULL, 0); } } } closesocket(listener); for (i = 0; i < key_count; i++) { free_RSA_key(privkey[i]); } crypto_cleanup(); #ifdef WINDOWS WSACleanup(); #endif fclose(stderr); }
apr_status_t wapr_unix_child_file_cleanup(void *thefile) { return file_cleanup(thefile); }
/** * Reads in the contents of the restart file. */ void read_restart_file(struct group_list_t *group) { struct client_restart_t *restart; char restart_name[MAXPATHNAME]; int fd, i, rval; // Don't bother if we're not using a temp directory. if (!strcmp(tempdir, "")) { return; } // First abort any prior session with the same group_id. // This creates the restart file. for (i = 0; i < MAXLIST; i++) { if ((group_list[i].group_id == group->group_id) && (group_list[i].group_inst < group->group_inst)) { file_cleanup(&group_list[i], 1); } } glog2(group, "Reading restart file"); snprintf(restart_name, sizeof(restart_name), "%s%c_group_%08X_restart", tempdir, PATH_SEP, group->group_id); if ((fd = open(restart_name, OPENREAD, 0644)) == -1) { gsyserror(group, "Failed to read restart file"); return; } // Read header restart = safe_calloc(sizeof(struct client_restart_t), 1); if ((rval = file_read(fd, restart, sizeof(struct client_restart_t), 0)) == -1) { glog0(group, "Failed to read header for restart file"); goto err1; } if (rval != sizeof(struct client_restart_t)) { glog0(group, "Failed to read header for restart file " "(read %d, expected %d)", rval,sizeof(struct client_restart_t)); goto err1; } // Read NAK list if (restart->blocks) { restart->naklist = safe_calloc(restart->blocks, 1); if (file_read(fd, restart->naklist, restart->blocks, 0) == -1) { glog0(group, "Failed to read NAK list for restart file"); goto err2; } } // Read section_done list if (restart->sections) { restart->section_done = safe_calloc(restart->sections, 1); if (file_read(fd, restart->section_done, restart->sections, 0) == -1) { glog0(group, "Failed to read section_done list for restart file"); goto err3; } } close(fd); unlink(restart_name); group->restartinfo = restart; glog3(group, "Reading restart file done"); return; err3: free(restart->section_done); err2: free(restart->naklist); err1: free(restart); close(fd); }
int z_restore( int argc, zword_t table, zword_t bytes, zword_t name ) { char new_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1]; char default_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1]; FILE *afp; #if defined BUFFER_FILES char afpbuffer[BUFSIZ]; #endif int status; status = 0; if ( argc == 3 ) { get_default_name( default_name, name ); if ( get_file_name( new_name, default_name, GAME_LOAD_AUX ) == 0 ) { goto finished; } if ( ( afp = fopen( new_name, "rb" ) ) == NULL ) { goto finished; } #if defined BUFFER_FILES setbuf( afp, afpbuffer ); #endif status = fread( datap + table, bytes, 1, afp ); fclose( afp ); if ( status != 0 ) { strcpy( auxilary_name, default_name ); } status = !status; } else { /* Get the file name */ status = 1; if ( get_file_name( new_name, save_name, GAME_RESTORE ) == 0 ) { /* Do the restore operation */ if ( save_restore( new_name, GAME_RESTORE ) == 0 ) { /* Reset the status region (this is just for Seastalker) */ if ( h_type < V4 ) { z_split_window( 0 ); blank_status_line( ); } /* Cleanup file */ file_cleanup( new_name, GAME_SAVE ); /* Save the new name as the default file name */ strcpy( save_name, new_name ); /* Indicate success */ status = 0; } } } finished: /* Return result of save to Z-code */ if ( h_type < V4 ) { conditional_jump( status == 0 ); } else { store_operand( (zword_t)(( status == 0 ) ? 2 : 0) ); } return ( status ); } /* z_restore */
/** * Sends an ABORT message to a server */ void send_abort(int listidx, const char *message) { unsigned char *buf, *encrypted, *outpacket; struct uftp_h *header; struct abort_h *abort; struct uftp2_h *v2_header; char *v2_message; int payloadlen; buf = calloc(group_list[listidx].mtu, 1); if (buf == NULL) { syserror(0, 0, "calloc failed!"); exit(1); } if (group_list[listidx].version == UFTP_V2_VER) { v2_header = (struct uftp2_h *)buf; v2_message = (char *)v2_header + sizeof(struct uftp2_h); v2_header->uftp_id = htonl(V2_UFTP_ID); v2_header->func = htonl(V2_ABORT); v2_header->tx_id = htonl(group_list[listidx].group_id); v2_header->blsize = htonl(strlen(message)); payloadlen = sizeof(struct uftp2_h) + strlen(message); strncpy(v2_message, message, V2_BLOCKSIZE - 1); encrypted = NULL; outpacket = buf; } else { header = (struct uftp_h *)buf; abort = (struct abort_h *)(buf + sizeof(struct uftp_h)); set_uftp_header(header, ABORT, listidx); abort->func = ABORT; abort->host = 0; strncpy(abort->message, message, sizeof(abort->message) - 1); payloadlen = sizeof(struct abort_h); if ((group_list[listidx].phase != PHASE_REGISTERED) && (group_list[listidx].keytype != KEY_NONE)) { encrypted = NULL; if (!encrypt_and_sign(buf, &encrypted, payloadlen, group_list[listidx].mtu, group_list[listidx].keytype, group_list[listidx].groupkey, group_list[listidx].groupsalt, group_list[listidx].ivlen, group_list[listidx].hashtype, group_list[listidx].grouphmackey, group_list[listidx].hmaclen, group_list[listidx].sigtype, group_list[listidx].clientkey, group_list[listidx].client_keylen)) { log0(0, 0, "Error encrypting ABORT"); free(buf); return; } outpacket = encrypted; payloadlen = ntohs(((struct uftp_h *)outpacket)->blsize); } else { encrypted = NULL; outpacket = buf; header->blsize = htons(payloadlen); } payloadlen += sizeof(struct uftp_h); } if (nb_sendto(listener, outpacket, payloadlen, 0, (struct sockaddr *)&group_list[listidx].replyaddr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { sockerror(group_list[listidx].group_id, group_list[listidx].file_id, "Error sending ABORT"); } file_cleanup(listidx, 1); free(buf); free(encrypted); }
/** * Gets the current timeout value to use for the main loop * * First check to see if any active groups have an expired timeout, and * handle that timeout. Once all expired timeouts have been handled, find * the active group with the earliest timeout and return the time until that * timeout. If there are no active groups, return NULL. */ struct timeval *getrecenttimeout(void) { static struct timeval tv = {0,0}; struct timeval current_timestamp, min_timestamp; int i, found_timeout, done, sent_naks; struct group_list_t *group; unsigned int section, nak_count; unsigned char *naks; gettimeofday(¤t_timestamp, NULL); done = 0; while (!done) { found_timeout = 0; done = 1; for (i = 0; i < MAXLIST; i++) { group = &group_list[i]; if (group->group_id != 0) { if (cmptimestamp(current_timestamp, group->timeout_time) >= 0) { switch (group->phase) { case PHASE_REGISTERED: send_register(group); break; case PHASE_RECEIVING: case PHASE_MIDGROUP: glog1(group, "Transfer timed out"); send_abort(group, "Transfer timed out"); break; case PHASE_COMPLETE: send_complete(group, 0); break; } done = 0; } else if ((!found_timeout) || (cmptimestamp(group->timeout_time, min_timestamp) < 0)) { glog5(group, "found min timeout time: %d:%06d", group->timeout_time.tv_sec, group->timeout_time.tv_usec); min_timestamp = group->timeout_time; found_timeout = 1; } // Check for a NAK timeout for sending a STATUS or COMPLETE if ((group->fileinfo.nak_time.tv_sec != 0) && cmptimestamp(current_timestamp, group->fileinfo.nak_time) >= 0) { group->fileinfo.nak_time.tv_sec = 0; group->fileinfo.nak_time.tv_usec = 0; // Send NAKs sent_naks = 0; retry_naks: for (section = group->fileinfo.nak_section_first; section < group->fileinfo.nak_section_last; section++) { naks = NULL; nak_count = get_naks(group, section, &naks); glog3(group, "read %d NAKs for section %d", nak_count, section); if (nak_count > 0) { send_status(group, section, naks, nak_count); sent_naks = 1; } free(naks); naks = NULL; } if (file_done(group, 1)) { glog2(group, "File transfer complete"); send_complete(group, 0); file_cleanup(group, 0); } else if (group->fileinfo.got_done && !sent_naks) { // We didn't send any NAKs since the last time // but the server is asking for some, // so check all prior sections group->fileinfo.nak_section_last = group->fileinfo.nak_section_first; group->fileinfo.nak_section_first = 0; group->fileinfo.got_done = 0; goto retry_naks; } } else if ((group->fileinfo.nak_time.tv_sec != 0) && ((!found_timeout) || (cmptimestamp(group->fileinfo.nak_time, min_timestamp) < 0))) { glog5(group, "found min nak time: %d:%06d", group->fileinfo.nak_time.tv_sec, group->fileinfo.nak_time.tv_usec); min_timestamp = group->fileinfo.nak_time; found_timeout = 1; } // Check congestion control feedback timer if (!group->isclr) { if ((group->cc_time.tv_sec != 0) && (cmptimestamp(current_timestamp, group->cc_time) >= 0)) { send_cc_ack(group); } else if ((group->cc_time.tv_sec != 0) && ((!found_timeout) || (cmptimestamp(group->cc_time, min_timestamp) < 0))) { glog5(group, "found min CC time: %d:%06d", group->cc_time.tv_sec, group->cc_time.tv_usec); min_timestamp = group->cc_time; found_timeout = 1; } } } } // Check timeout for proxy key request if (has_proxy && (proxy_pubkey.key == 0)) { if (cmptimestamp(current_timestamp, next_keyreq_time) >= 0) { send_key_req(); done = 0; } else if ((!found_timeout) || (cmptimestamp(next_keyreq_time, min_timestamp) < 0)) { min_timestamp = next_keyreq_time; found_timeout = 1; } } // Check timeout for sending heartbeat if (hbhost_count) { if (cmptimestamp(current_timestamp, next_hb_time) >= 0) { send_hb_request(listener, hb_hosts, hbhost_count, &next_hb_time, hb_interval, uid); done = 0; } else if ((!found_timeout) || (cmptimestamp(next_hb_time, min_timestamp) < 0)) { min_timestamp = next_hb_time; found_timeout = 1; } } } if (found_timeout) { tv = diff_timeval(min_timestamp, current_timestamp); return &tv; } else { return NULL; } }
/** * Sends back a COMPLETE message in response to a DONE or FILEINFO */ void send_complete(struct group_list_t *group, int set_freespace) { unsigned char *buf, *encrypted, *outpacket; struct uftp_h *header; struct complete_h *complete; struct freespace_info_he *freespace; int payloadlen, enclen; struct timeval tv; gettimeofday(&tv, NULL); if ((group->phase == PHASE_COMPLETE) && (cmptimestamp(tv, group->expire_time) >= 0)) { glog1(group, "Completion unconfirmed by server"); move_files(group); file_cleanup(group, 0); return; } buf = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; complete = (struct complete_h *)(buf + sizeof(struct uftp_h)); freespace = (struct freespace_info_he *)((unsigned char *)complete + sizeof(struct complete_h)); set_uftp_header(header, COMPLETE, group); complete->func = COMPLETE; if (set_freespace) { complete->hlen = (sizeof(struct complete_h) + sizeof(struct freespace_info_he)) / 4; } else { complete->hlen = sizeof(struct complete_h) / 4; } complete->status = group->fileinfo.comp_status; complete->file_id = htons(group->file_id); if (set_freespace) { set_freespace_info(group, freespace); } payloadlen = complete->hlen * 4; if ((group->phase != PHASE_REGISTERED) && (group->keytype != KEY_NONE)) { encrypted = NULL; if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen, group->keytype, group->groupkey, group->groupsalt,&group->ivctr, group->ivlen, group->hashtype, group->grouphmackey, group->hmaclen, group->sigtype, group->keyextype, group->client_privkey, group->client_privkeylen)) { glog0(group, "Error encrypting COMPLETE"); free(buf); return; } outpacket = encrypted; payloadlen = enclen; } else { encrypted = NULL; outpacket = buf; } payloadlen += sizeof(struct uftp_h); if (nb_sendto(listener, outpacket, payloadlen, 0, (struct sockaddr *)&group->replyaddr, family_len(group->replyaddr)) == SOCKET_ERROR) { gsockerror(group, "Error sending COMPLETE"); } else { glog2(group, "COMPLETE sent"); } set_timeout(group, 0); free(buf); free(encrypted); }
APR_DECLARE(apr_status_t) apr_file_pipe_create_pools(apr_file_t **in, apr_file_t **out, apr_int32_t blocking, apr_pool_t *pool_in, apr_pool_t *pool_out) { #ifdef _WIN32_WCE return APR_ENOTIMPL; #else SECURITY_ATTRIBUTES sa; static unsigned long id = 0; DWORD dwPipeMode; DWORD dwOpenMode; sa.nLength = sizeof(sa); #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE sa.bInheritHandle = FALSE; #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI sa.bInheritHandle = TRUE; #endif sa.lpSecurityDescriptor = NULL; (*in) = (apr_file_t *)apr_pcalloc(pool_in, sizeof(apr_file_t)); (*in)->pool = pool_in; (*in)->fname = NULL; (*in)->pipe = 1; (*in)->timeout = -1; (*in)->ungetchar = -1; (*in)->eof_hit = 0; (*in)->filePtr = 0; (*in)->bufpos = 0; (*in)->dataRead = 0; (*in)->direction = 0; (*in)->pOverlapped = NULL; #if APR_FILES_AS_SOCKETS (void) apr_pollset_create(&(*in)->pollset, 1, p, 0); #endif (*out) = (apr_file_t *)apr_pcalloc(pool_out, sizeof(apr_file_t)); (*out)->pool = pool_out; (*out)->fname = NULL; (*out)->pipe = 1; (*out)->timeout = -1; (*out)->ungetchar = -1; (*out)->eof_hit = 0; (*out)->filePtr = 0; (*out)->bufpos = 0; (*out)->dataRead = 0; (*out)->direction = 0; (*out)->pOverlapped = NULL; #if APR_FILES_AS_SOCKETS (void) apr_pollset_create(&(*out)->pollset, 1, p, 0); #endif if (apr_os_level >= APR_WIN_NT) { char rand[8]; int pid = getpid(); #define FMT_PIPE_NAME "\\\\.\\pipe\\apr-pipe-%x.%lx." /* ^ ^ ^ * pid | | * | | * id | * | * hex-escaped rand[8] (16 bytes) */ char name[sizeof FMT_PIPE_NAME + 2 * sizeof(pid) + 2 * sizeof(id) + 2 * sizeof(rand)]; apr_size_t pos; /* Create the read end of the pipe */ dwOpenMode = PIPE_ACCESS_INBOUND; #ifdef FILE_FLAG_FIRST_PIPE_INSTANCE dwOpenMode |= FILE_FLAG_FIRST_PIPE_INSTANCE; #endif if (blocking == APR_WRITE_BLOCK /* READ_NONBLOCK */ || blocking == APR_FULL_NONBLOCK) { dwOpenMode |= FILE_FLAG_OVERLAPPED; (*in)->pOverlapped = (OVERLAPPED*) apr_pcalloc((*in)->pool, sizeof(OVERLAPPED)); (*in)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); (*in)->timeout = 0; } dwPipeMode = 0; apr_generate_random_bytes(rand, sizeof rand); pos = apr_snprintf(name, sizeof name, FMT_PIPE_NAME, pid, id++); apr_escape_hex(name + pos, rand, sizeof rand, 0, NULL); (*in)->filehand = CreateNamedPipe(name, dwOpenMode, dwPipeMode, 1, /* nMaxInstances, */ 0, /* nOutBufferSize, */ 65536, /* nInBufferSize, */ 1, /* nDefaultTimeOut, */ &sa); if ((*in)->filehand == INVALID_HANDLE_VALUE) { apr_status_t rv = apr_get_os_error(); file_cleanup(*in); return rv; } /* Create the write end of the pipe */ dwOpenMode = FILE_ATTRIBUTE_NORMAL; if (blocking == APR_READ_BLOCK /* WRITE_NONBLOCK */ || blocking == APR_FULL_NONBLOCK) { dwOpenMode |= FILE_FLAG_OVERLAPPED; (*out)->pOverlapped = (OVERLAPPED*) apr_pcalloc((*out)->pool, sizeof(OVERLAPPED)); (*out)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); (*out)->timeout = 0; } (*out)->filehand = CreateFile(name, GENERIC_WRITE, /* access mode */ 0, /* share mode */ &sa, /* Security attributes */ OPEN_EXISTING, /* dwCreationDisposition */ dwOpenMode, /* Pipe attributes */ NULL); /* handle to template file */ if ((*out)->filehand == INVALID_HANDLE_VALUE) { apr_status_t rv = apr_get_os_error(); file_cleanup(*out); file_cleanup(*in); return rv; } } else { /* Pipes on Win9* are blocking. Live with it. */ if (!CreatePipe(&(*in)->filehand, &(*out)->filehand, &sa, 65536)) { return apr_get_os_error(); } } apr_pool_cleanup_register((*in)->pool, (void *)(*in), file_cleanup, apr_pool_cleanup_null); apr_pool_cleanup_register((*out)->pool, (void *)(*out), file_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; #endif /* _WIN32_WCE */ }
/* allocate and fill the file_search_data */ file_search_data* create_file_search_data(rsh_tchar** paths, size_t count, int max_depth) { size_t i; file_search_data* data = (file_search_data*)rsh_malloc(sizeof(file_search_data)); memset(data, 0, sizeof(file_search_data)); rsh_blocks_vector_init(&data->root_files); data->max_depth = max_depth; #ifdef _WIN32 /* expand wildcards and fill the root_files */ for (i = 0; i < count; i++) { int added = 0; size_t length, index; wchar_t* path = paths[i]; wchar_t* p = wcschr(path, L'\0') - 1; /* strip trailing '\','/' symbols (if not preceded by ':') */ for (; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--) *p = 0; /* Expand a wildcard in the current file path and store results into data->root_files. * If a wildcard is not found then just the file path is stored. * NB, only wildcards in the last filename of the path are expanded. */ length = p - path + 1; index = wcscspn(path, L"*?"); if (index < length && wcscspn(path + index, L"/\\") >= (length - index)) { /* a wildcard is found without a directory separator after it */ wchar_t* parent; WIN32_FIND_DATAW d; HANDLE handle; /* find a directory separator before the file name */ for (; index > 0 && !IS_PATH_SEPARATOR(path[index]); index--); parent = (IS_PATH_SEPARATOR(path[index]) ? path : 0); handle = FindFirstFileW(path, &d); if (INVALID_HANDLE_VALUE != handle) { do { file_t file; int failed; if (IS_CURRENT_OR_PARENT_DIRW(d.cFileName)) continue; memset(&file, 0, sizeof(file)); file.wpath = make_pathw(parent, index + 1, d.cFileName); if (!file.wpath) continue; /* skip directories if not in recursive mode */ if (data->max_depth == 0 && (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue; /* convert file name */ file.path = wchar_to_cstr(file.wpath, WIN_DEFAULT_ENCODING, &failed); if (!failed) { failed = (file_statw(&file) < 0); } /* quietly skip unconvertible file names */ if (!file.path || failed) { if (failed) { data->errors_count++; } free(file.path); free(file.wpath); continue; } /* fill the file information */ file.mode |= FILE_IFROOT; add_root_file(data, &file); added++; } while (FindNextFileW(handle, &d)); FindClose(handle); } else { /* report error on the specified wildcard */ char * cpath = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, NULL); set_errno_from_last_file_error(); log_file_error(cpath); free(cpath); data->errors_count++; } } else { int failed; file_t file; memset(&file, 0, sizeof(file)); /* if filepath is a dash string "-" */ if ((path[0] == L'-' && path[1] == L'\0')) { file.mode = FILE_IFSTDIN; file.path = rsh_strdup("(stdin)"); } else { file.path = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, &failed); if (failed) { log_error(_("Can't convert the path to local encoding: %s\n"), file.path); free(file.path); data->errors_count++; continue; } file.wpath = path; if (file_statw(&file) < 0) { log_file_error(file.path); free(file.path); data->errors_count++; continue; } } /* mark the file as obtained from the command line */ file.mode |= FILE_IFROOT; file.wpath = rsh_wcsdup(path); add_root_file(data, &file); } } /* for */ #else /* copy file paths */ for (i = 0; i < count; i++) { file_t file; file_init(&file, paths[i], 0); if (IS_DASH_STR(file.path)) { file.mode = FILE_IFSTDIN; } else if (file_stat2(&file, USE_LSTAT) < 0) { log_file_error(file.path); file_cleanup(&file); data->errors_count++; continue; } file.mode |= FILE_IFROOT; add_root_file(data, &file); } #endif return data; }
/** * Walk directory tree and call given callback function to process each file/directory. * * @param start_dir path to the directory to walk recursively * @param data the options specifying how to walk the directory tree * @return 0 on success, -1 on error */ static int dir_scan(file_t* start_dir, file_search_data* data) { dir_entry *dirs_stack = NULL; /* root of the dir_list */ dir_iterator* it; int level = 0; int max_depth = data->max_depth; int options = data->options; file_t file; if (max_depth < 0 || max_depth >= MAX_DIRS_DEPTH) { max_depth = MAX_DIRS_DEPTH - 1; } /* skip the directory if max_depth == 0 */ if (!max_depth) return 0; if (!FILE_ISDIR(start_dir)) { errno = ENOTDIR; return -1; } /* check if we should descend into the root directory */ if ((options & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)) == 0) { if (!data->call_back(start_dir, data->call_back_data)) return 0; } /* allocate array of counters of directory elements */ it = (dir_iterator*)malloc((MAX_DIRS_DEPTH + 1) * sizeof(dir_iterator)); if (!it) { return -1; } /* push dummy counter for the root element */ it[0].count = 1; it[0].dir_path = 0; memset(&file, 0, sizeof(file)); while (!(data->options & FIND_CANCEL)) { dir_entry **insert_at; char* dir_path; DIR *dp; struct dirent *de; /* climb down from the tree */ while (--it[level].count < 0) { /* do not need this dir_path anymore */ free(it[level].dir_path); if (--level < 0) { /* walked the whole tree */ assert(!dirs_stack); free(it); return 0; } } assert(level >= 0 && it[level].count >= 0); /* take a filename from dirs_stack and construct the next path */ if (level) { assert(dirs_stack != NULL); dir_path = make_path(it[level].dir_path, dirs_stack->filename); dir_entry_drop_head(&dirs_stack); } else { /* the first cycle: start from a root directory */ dir_path = rsh_strdup(start_dir->path); } if (!dir_path) continue; /* fill the next level of directories */ level++; assert(level < MAX_DIRS_DEPTH); it[level].count = 0; it[level].dir_path = dir_path; if ((options & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)) == FIND_WALK_DEPTH_FIRST) { int res; file_init(&file, dir_path, 1); res = file_stat2(&file, USE_LSTAT); /* check if we should skip the directory */ if (res < 0 || !data->call_back(&file, data->call_back_data)) { if (res < 0 && (options & FIND_LOG_ERRORS)) { data->errors_count++; } file_cleanup(&file); continue; } } file_cleanup(&file); /* step into directory */ dp = opendir(dir_path); if (!dp) continue; insert_at = &dirs_stack; while ((de = readdir(dp)) != NULL) { int res; /* skip the "." and ".." directories */ if (IS_CURRENT_OR_PARENT_DIR(de->d_name)) continue; file.mode = 0; file.path = make_path(dir_path, de->d_name); if (!file.path) continue; res = file_stat2(&file, USE_LSTAT); if (res >= 0) { /* process the file or directory */ if (FILE_ISDIR(&file) && (options & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS))) { res = ((options & FIND_FOLLOW_SYMLINKS) || !FILE_ISLNK(&file)); } else if (FILE_ISREG(&file)) { /* handle file by callback function */ res = data->call_back(&file, data->call_back_data); } /* check if file is a directory and we need to walk it, */ /* but don't go deeper than max_depth */ if (FILE_ISDIR(&file) && res && level < max_depth && ((options & FIND_FOLLOW_SYMLINKS) || !FILE_ISLNK(&file))) { /* add the directory name to the dirs_stack */ if (dir_entry_insert(insert_at, de->d_name, file.mode)) { /* the directory name was successfully inserted */ insert_at = &((*insert_at)->next); it[level].count++; } } } else if (options & FIND_LOG_ERRORS) { /* report error only if FIND_LOG_ERRORS option is set */ log_file_error(file.path); data->errors_count++; } file_cleanup(&file); } closedir(dp); } while (dirs_stack) { dir_entry_drop_head(&dirs_stack); } while (level) { free(it[level--].dir_path); } free(it); assert(file.path == 0); return 0; }
int main(int argc, char **argv) { daemonize_close_stdin(); parse_cmdline(argc, argv); if (!file_read_config()) g_error("cannot read configuration file\n"); log_init(file_config.log, file_config.verbose); daemonize_init(file_config.daemon_user, file_config.pidfile); if (!file_config.no_daemon) daemonize_detach(); daemonize_write_pidfile(); daemonize_set_user(); #ifndef NDEBUG if (!file_config.no_daemon) #endif daemonize_close_stdout_stderr(); main_loop = g_main_loop_new(NULL, FALSE); lmc_connect(file_config.host, file_config.port); http_client_init(); as_init(file_config.scrobblers); setup_signals(); timer = g_timer_new(); /* set up timeouts */ save_source_id = g_timeout_add_seconds(file_config.journal_interval, timer_save_journal, NULL); /* run the main loop */ g_main_loop_run(main_loop); /* cleanup */ g_message("shutting down\n"); g_source_remove(save_source_id); g_main_loop_unref(main_loop); g_timer_destroy(timer); as_save_cache(); as_cleanup(); http_client_finish(); lmc_disconnect(); file_cleanup(); log_deinit(); daemonize_finish(); return 0; }