void run_tests2(void) { int i; int64_t arr[SIZE]; int64_t dst[SIZE]; double start_time; double end_time; double total_time; printf("Running tests - 2\n"); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); qsort(dst, SIZE, sizeof(int64_t), simple_cmp2); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("stdlib qsort time: %.2f us per iteration\n", total_time / RUNS); #ifndef __linux__ srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); heapsort(dst, SIZE, sizeof(int64_t), simple_cmp2); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("stdlib heapsort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); mergesort(dst, SIZE, sizeof(int64_t), simple_cmp2); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("stdlib mergesort time: %.2f us per iteration\n", total_time / RUNS); #endif srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_quick_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("quick sort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_bubble_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("bubble sort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_merge_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("merge sort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_binary_insertion_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("binary insertion sort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_heap_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("heap sort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_shell_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("shell sort time: %.2f us per iteration\n", total_time / RUNS); srand48(SEED); total_time = 0.0; for (i = 0; i < RUNS; i++) { fill(arr, SIZE); memcpy(dst, arr, sizeof(int64_t) * SIZE); start_time = utime(); sorter2_tim_sort(dst, SIZE); end_time = utime(); total_time += end_time - start_time; verify2(dst, SIZE); } printf("tim sort time: %.2f us per iteration\n", total_time / RUNS); }
static int set_info_func (CameraFilesystem *fs, const char *folder, const char *file, CameraFileInfo info, void *data, GPContext *context) { int retval; char path[1024]; Camera *camera = (Camera*)data; retval = _get_path (camera->port, folder, file, path, sizeof(path)); if (retval < GP_OK) return retval; /* We don't support updating permissions (yet) */ if (info.file.fields & GP_FILE_INFO_PERMISSIONS) return (GP_ERROR_NOT_SUPPORTED); if (info.file.fields & GP_FILE_INFO_MTIME) { struct utimbuf utimbuf; utimbuf.actime = info.file.mtime; utimbuf.modtime = info.file.mtime; if (utime (path, &utimbuf) != 0) { gp_context_error (context, _("Could not change " "time of file '%s' in '%s' (%m)."), file, folder); return (GP_ERROR); } } #if 0 /* implement this using new api -Marcus */ if (info.file.fields & GP_FILE_INFO_NAME) { if (!strcasecmp (info.file.name, file)) return (GP_OK); /* We really have to rename the poor file... */ if (strlen (folder) == 1) { snprintf (path_old, sizeof (path_old), "/%s", file); snprintf (path_new, sizeof (path_new), "/%s", info.file.name); } else { snprintf (path_old, sizeof (path_old), "%s/%s", folder, file); snprintf (path_new, sizeof (path_new), "%s/%s", folder, info.file.name); } retval = rename (path_old, path_new); if (retval != 0) { switch (errno) { case EISDIR: return (GP_ERROR_DIRECTORY_EXISTS); case EEXIST: return (GP_ERROR_FILE_EXISTS); case EINVAL: return (GP_ERROR_BAD_PARAMETERS); case EIO: return (GP_ERROR_IO); case ENOMEM: return (GP_ERROR_NO_MEMORY); case ENOENT: return (GP_ERROR_FILE_NOT_FOUND); default: return (GP_ERROR); } } } #endif return (GP_OK); }
MODRET site_misc_utime(cmd_rec *cmd) { if (cmd->argc < 2) return DECLINED(cmd); if (strcasecmp(cmd->argv[1], "UTIME") == 0) { register unsigned int i; char c, *p, *path = ""; unsigned int year, month, day, hour, min; struct utimbuf tmbuf; unsigned char *authenticated; if (cmd->argc < 4) return DECLINED(cmd); authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE); if (!authenticated || *authenticated == FALSE) { pr_response_add_err(R_530, "Please login with USER and PASS"); return ERROR(cmd); } if (strlen(cmd->argv[2]) != 12) { pr_response_add_err(R_500, "%s: %s", cmd->arg, strerror(EINVAL)); return ERROR(cmd); } for (i = 3; i < cmd->argc; i++) path = pstrcat(cmd->tmp_pool, path, *path ? " " : "", cmd->argv[i], NULL); if (!dir_check(cmd->tmp_pool, "SITE_UTIME", G_WRITE, path, NULL)) { pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EPERM)); return ERROR(cmd); } if (site_misc_check_filters(cmd, path) < 0) { pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EPERM)); return ERROR(cmd); } p = cmd->argv[2]; c = cmd->argv[2][4]; cmd->argv[2][4] = '\0'; year = atoi(p); cmd->argv[2][4] = c; p = &(cmd->argv[2][4]); c = cmd->argv[2][6]; cmd->argv[2][6] = '\0'; month = atoi(p); cmd->argv[2][6] = c; p = &(cmd->argv[2][6]); c = cmd->argv[2][8]; cmd->argv[2][8] = '\0'; day = atoi(p); cmd->argv[2][8] = c; p = &(cmd->argv[2][8]); c = cmd->argv[2][10]; cmd->argv[2][10] = '\0'; hour = atoi(p); cmd->argv[2][10] = c; p = &(cmd->argv[2][10]); min = atoi(p); tmbuf.actime = tmbuf.modtime = site_misc_mktime(year, month, day, hour, min); if (utime(path, &tmbuf) < 0) { pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno)); return ERROR(cmd); } pr_response_add(R_200, "SITE %s command successful", cmd->argv[1]); return HANDLED(cmd); } if (strcasecmp(cmd->argv[1], "HELP") == 0) pr_response_add(R_214, "UTIME <sp> YYYYMMDDhhmm <sp> path"); return DECLINED(cmd); }
int main(int ac, char **av) { struct stat stat_buf; /* struct buffer to hold file info. */ int lc; const char *msg; time_t modf_time, access_time; /* file modification/access time */ msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); /* set the expected errnos... */ TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; /* * Invoke utime(2) to set TEMP_FILE access and * modification times to that specified by * times argument. */ TEST(utime(TEMP_FILE, ×)); if (TEST_RETURN == -1) { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TFAIL, "utime(%s) Failed, errno=%d : %s", TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO)); } else { /* * Get the modification and access times of * temporary file using stat(2). */ if (stat(TEMP_FILE, &stat_buf) < 0) { tst_brkm(TFAIL, cleanup, "stat(2) of " "%s failed, error:%d", TEMP_FILE, TEST_ERRNO); } modf_time = stat_buf.st_mtime; access_time = stat_buf.st_atime; /* Now do the actual verification */ if ((modf_time != NEW_TIME) || (access_time != NEW_TIME)) { tst_resm(TFAIL, "%s access and " "modification times not set", TEMP_FILE); } else { tst_resm(TPASS, "Functionality of " "utime(%s, ×) successful", TEMP_FILE); } } tst_count++; /* incr TEST_LOOP counter */ } cleanup(); tst_exit(); }
int copy_file(const char *source, const char *dest, int flags) { struct stat source_stat; struct stat dest_stat; int dest_exists = 0; int status = 0; if ((!(flags & FILEUTILS_PRESERVE_SYMLINKS) && lstat(source, &source_stat) < 0) || ((flags & FILEUTILS_PRESERVE_SYMLINKS) && stat(source, &source_stat) < 0)) { perror_msg("%s", source); return -1; } if (lstat(dest, &dest_stat) < 0) { if (errno != ENOENT) { perror_msg("unable to stat `%s'", dest); return -1; } } else { if (source_stat.st_dev == dest_stat.st_dev && source_stat.st_ino == dest_stat.st_ino) { error_msg("`%s' and `%s' are the same file", source, dest); return -1; } dest_exists = 1; } if (S_ISDIR(source_stat.st_mode)) { DIR *dp; struct dirent *d; mode_t saved_umask = 0; if (!(flags & FILEUTILS_RECUR)) { error_msg("%s: omitting directory", source); return -1; } /* Create DEST. */ if (dest_exists) { if (!S_ISDIR(dest_stat.st_mode)) { error_msg("`%s' is not a directory", dest); return -1; } } else { mode_t mode; saved_umask = umask(0); mode = source_stat.st_mode; if (!(flags & FILEUTILS_PRESERVE_STATUS)) mode = source_stat.st_mode & ~saved_umask; mode |= S_IRWXU; if (mkdir(dest, mode) < 0) { umask(saved_umask); perror_msg("cannot create directory `%s'", dest); return -1; } umask(saved_umask); } /* Recursively copy files in SOURCE. */ if ((dp = opendir(source)) == NULL) { perror_msg("unable to open directory `%s'", source); status = -1; goto end; } while ((d = readdir(dp)) != NULL) { char *new_source, *new_dest; if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) continue; new_source = concat_path_file(source, d->d_name); new_dest = concat_path_file(dest, d->d_name); if (copy_file(new_source, new_dest, flags) < 0) status = -1; free(new_source); free(new_dest); } /* closedir have only EBADF error, but "dp" not changes */ closedir(dp); if (!dest_exists && chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { perror_msg("unable to change permissions of `%s'", dest); status = -1; } } else if (S_ISREG(source_stat.st_mode)) { FILE *sfp, *dfp=NULL; #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS char *link_name; if (!(flags & FILEUTILS_PRESERVE_SYMLINKS) && is_in_ino_dev_hashtable(&source_stat, &link_name)) { if (link(link_name, dest) < 0) { perror_msg("unable to link `%s'", dest); return -1; } return 0; } #endif if ((sfp = wfopen(source, "r")) == NULL) { return -1; } if (dest_exists) { if (flags & FILEUTILS_INTERACTIVE) { fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest); if (!ask_confirmation()) { fclose (sfp); return 0; } } if ((dfp = fopen(dest, "w")) == NULL) { if (!(flags & FILEUTILS_FORCE)) { perror_msg("unable to open `%s'", dest); fclose (sfp); return -1; } if (unlink(dest) < 0) { perror_msg("unable to remove `%s'", dest); fclose (sfp); return -1; } dest_exists = 0; } } if (!dest_exists) { int fd; if ((fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode)) < 0 || (dfp = fdopen(fd, "w")) == NULL) { if (fd >= 0) close(fd); perror_msg("unable to open `%s'", dest); fclose (sfp); return -1; } } if (copy_file_chunk(sfp, dfp, -1) < 0) status = -1; if (fclose(dfp) < 0) { perror_msg("unable to close `%s'", dest); status = -1; } if (fclose(sfp) < 0) { perror_msg("unable to close `%s'", source); status = -1; } } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || S_ISLNK(source_stat.st_mode)) { if (dest_exists && ((flags & FILEUTILS_FORCE) == 0 || unlink(dest) < 0)) { perror_msg("unable to remove `%s'", dest); return -1; } } else { error_msg("internal error: unrecognized file type"); return -1; } if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || S_ISSOCK(source_stat.st_mode)) { if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { perror_msg("unable to create `%s'", dest); return -1; } } else if (S_ISFIFO(source_stat.st_mode)) { if (mkfifo(dest, source_stat.st_mode) < 0) { perror_msg("cannot create fifo `%s'", dest); return -1; } } else if (S_ISLNK(source_stat.st_mode)) { char *lpath; lpath = xreadlink(source); if (symlink(lpath, dest) < 0) { perror_msg("cannot create symlink `%s'", dest); return -1; } free(lpath); #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) if (flags & FILEUTILS_PRESERVE_STATUS) if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) perror_msg("unable to preserve ownership of `%s'", dest); #endif #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS add_to_ino_dev_hashtable(&source_stat, dest); #endif return 0; } #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS add_to_ino_dev_hashtable(&source_stat, dest); #endif end: if (flags & FILEUTILS_PRESERVE_STATUS) { struct utimbuf times; times.actime = source_stat.st_atime; times.modtime = source_stat.st_mtime; if (utime(dest, ×) < 0) perror_msg("unable to preserve times of `%s'", dest); if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { source_stat.st_mode &= ~(S_ISUID | S_ISGID); perror_msg("unable to preserve ownership of `%s'", dest); } if (chmod(dest, source_stat.st_mode) < 0) perror_msg("unable to preserve permissions of `%s'", dest); } return status; }
/* Retrieve a file 'file' of size 'size' by reading the contents of it from the * socket 'sock' and write the file with the same name to directory 'directory'. * Update the last modified time of this file to 'timestamp' on the filesystem. * @Param: sock the socket to read from. * @Param: directory the directory to write the file to. * @Param: size the size of the file being retrieved. * @Param: timestamp the last modified time to set to. * @Return: void. */ void get_file(int sock, char* directory, char* file, int size, long int timestamp){ int readlength, readcount = 0, length; char buffer[CHUNKSIZE]; char fullpath[CHUNKSIZE]; FILE *fp; //Grab the full path to the file. strncpy(fullpath, directory, CHUNKSIZE); strcat(fullpath, "/"); strncat(fullpath, file, CHUNKSIZE-strlen(fullpath)); //Open the file. Overwite if it already exists. if((fp = fopen(fullpath, "w")) == NULL) { perror("fopen on get file: "); exit(1); } /* Length computes the size of the file to be read per read call. * if the length happens to be more than CHUNKSIZE (256) then read only * CHUNKSIZE at max for now. */ if((length = size) > CHUNKSIZE){ length = CHUNKSIZE; } while( readcount < size ){ /* Compute the reamining length to be read. If the reamining length happens * to be more than CHUNKSIZE (256) then read only CHUNKSIZE at max for now */ length = size - readcount; if (length > CHUNKSIZE){ length = CHUNKSIZE; } readlength = Readn(sock, &buffer, length); //Update how many bytes has been read yet. readcount += readlength; fwrite(buffer, readlength, 1, fp); //If there was an error with fwrite. if(ferror(fp)){ fprintf(stderr, "A write error occured.\n"); Close(sock); exit(1); } } if((fclose(fp))) { perror("fclose: "); exit(1); } struct stat sbuf; struct utimbuf new_times; if(stat(fullpath, &sbuf) != 0) { perror("stat"); exit(1); } //Update the last modified time to 'timestamp' for this file on the filesystem. new_times.actime = sbuf.st_atime; //Access time. new_times.modtime = (time_t)timestamp; if(utime(fullpath, &new_times) < 0) { perror("utime"); exit(1); } }
int File::write() { #if POSIX int fd; ssize_t numwritten; char *name; name = this->name->toChars(); fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd == -1) goto err; numwritten = ::write(fd, buffer, len); if (len != numwritten) goto err2; if (close(fd) == -1) goto err; if (touchtime) { struct utimbuf ubuf; ubuf.actime = ((struct stat *)touchtime)->st_atime; ubuf.modtime = ((struct stat *)touchtime)->st_mtime; if (utime(name, &ubuf)) goto err; } return 0; err2: close(fd); ::remove(name); err: return 1; #elif _WIN32 HANDLE h; DWORD numwritten; char *name; name = this->name->toChars(); h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); if (h == INVALID_HANDLE_VALUE) goto err; if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE) goto err2; if (len != numwritten) goto err2; if (touchtime) { SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime); } if (!CloseHandle(h)) goto err; return 0; err2: CloseHandle(h); DeleteFileA(name); err: return 1; #else assert(0); #endif }
static void proto_handle_get(conn_t* cn, const char* line) { struct stat st; // Reject filenames with just "." and ".." if(memcmp(line, ".\0", 2) == 0 || memcmp(line, "..\0", 3) == 0) { conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__); conn_abort(cn); return; } if(lstat(line,&st) == 0) { if(S_ISREG(st.st_mode)) { int fd; md5_state_t md5_state; md5_init(&md5_state); char buffer[PATH_MAX]; ssize_t size; char md5str[33]; char modestr[11]; #ifdef O_NOATIME if((fd = open(line,O_RDONLY|O_NOATIME))==-1) { #else if((fd = open(line,O_RDONLY))==-1) { #endif conn_perror(cn, "WARNING open()"); conn_printf(cn, "WARNING Can't open file: %s\n", line); return; } // Calcuate MD5 { unsigned char md5bin[16]; while((size = read(fd, buffer, sizeof buffer))) md5_append(&md5_state, (unsigned char*)buffer, size); md5_finish(&md5_state, (unsigned char*)md5bin); if(lseek(fd, SEEK_SET, 0)==-1) { conn_perror(cn, "ERROR lseek()"); conn_abort(cn); return; } md5bin2str(md5bin, md5str); } mode2str(st.st_mode, modestr); conn_printf(cn, "PUT %ld %s %s %ld %ld %ld %s\n", (long int)st.st_size, md5str, modestr, st.st_atime, st.st_ctime, st.st_mtime, line); while((size = read(fd, buffer, sizeof buffer))) conn_write(cn, buffer, size); close(fd); } else if(S_ISDIR(st.st_mode)) { char modestr[11]; mode2str(st.st_mode, modestr); conn_printf(cn, "MKDIR %s %ld %ld %ld %s\n", modestr, st.st_atime, st.st_ctime, st.st_mtime, line); } else if(S_ISLNK(st.st_mode)) { char buffer[PATH_MAX]; conn_printf(cn, "SLNK %s\n", line); ssize_t l; if((l=readlink(line, buffer, sizeof buffer))==-1) { conn_perror(cn, "WARNING readlink()"); return; } buffer[l] = '\0'; conn_printf(cn, "%s\n", buffer); } else { conn_printf(cn, "WARNING Ignored %s\n", line); } } } static void proto_handle_put(conn_t* cn, const char* line) { const char* delim = " "; char* saveptr = NULL; char* token; char* ptr = (char*)line; int c = 0; ssize_t size = 0; mode_t mode = 0; time_t mtime = 0; time_t ctime = 0; time_t atime = 0; char* name = NULL; char* md5 = NULL; while((token = strtok_r(ptr, delim, &saveptr))) { switch(c) { case 0: size = atol(token); break; case 1: md5 = token; break; case 2: mode = str2mode(token); break; case 3: atime = atol(token); break; case 4: ctime = atol(token); break; case 5: mtime = atol(token); break; case 6: name = token; break; } c++; ptr = NULL; } if(c != 7) { conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__); conn_abort(cn); return ; } int fd = creat(name, O_CREAT|O_TRUNC); if(fd == -1) { conn_perror(cn, "WARNING creat()"); return; } if(chmod(name,mode)==-1) { perror("WARNING chmod()"); } struct utimbuf t; t.actime = atime; t.modtime = mtime; if(utime(name,&t)==-1) { perror("WARNING utime"); } // CONTENT int bytes_left = size; int r; md5_state_t md5_state; unsigned char md5bin[16]; char md5str[33]; md5_init(&md5_state); while(!cn->abort && bytes_left) { if(cn->rbuf_len == 0) (void)conn_read(cn); r = MIN(bytes_left, cn->rbuf_len); if(r) { write(fd, cn->rbuf, r); md5_append(&md5_state, (unsigned char*)cn->rbuf, r); conn_shift(cn,r); bytes_left -= r; } assert(bytes_left >= 0); } close(fd); md5_finish(&md5_state, (unsigned char*)md5bin); md5bin2str(md5bin, md5str); // Check md5 if(strcmp(md5str,md5)!=0) { // Mismatch! conn_printf(cn, "WARNING %s md5-mismatch (%s <-> %s), removing file\n", name, md5str, md5); if(unlink(name)==-1) { perror("WARNING: unlink()"); } } else { struct utimbuf t; t.actime = atime; t.modtime = mtime; if(utime(name,&t)==-1) { perror("utime"); conn_printf(cn, "WARNING Can't timestamp on directory: %s\n", name); } // md5 is fine conn_printf(cn, "GET %s\n", name); } } static void proto_handle_slnk(conn_t* cn, const char* line) { char curdir[PATH_MAX]; // read next line to get target char target[PATH_MAX]; if(!conn_readline(cn, target, sizeof target)) return; getcwd(curdir, sizeof curdir); // Make sure it dosnt exist unlink(line); if(chdir(my_dirname(line))==-1) { conn_perror(cn, "WARNING chdir()"); return; } if(symlink(target, my_basename(line))==-1) { conn_perror(cn, "ERROR symlink()"); conn_abort(cn); return; } chdir(curdir); conn_printf(cn, "GET %s\n", line); }
int my_copy(const char *from, const char *to, myf MyFlags) { uint Count; int new_file_stat, create_flag; File from_file,to_file; char buff[IO_SIZE]; struct stat stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); from_file=to_file= -1; new_file_stat=0; if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */ new_file_stat=stat((char*) to, &new_stat_buff); if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0) { if (stat(from,&stat_buff)) { my_errno=errno; goto err; } if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) stat_buff=new_stat_buff; create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC; if ((to_file= my_create(to,(int) stat_buff.st_mode, O_WRONLY | create_flag | O_BINARY | O_SHARE, MyFlags)) < 0) goto err; while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0) if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ /* Copy modes if possible */ if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */ #if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__) VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */ #endif #if !defined(VMS) && !defined(__ZTC__) if (MyFlags & MY_COPYTIME) { struct utimbuf timep; timep.actime = stat_buff.st_atime; timep.modtime = stat_buff.st_mtime; VOID(utime((char*) to, &timep)); /* last accessed and modified times */ } #endif DBUG_RETURN(0); } err: if (from_file >= 0) VOID(my_close(from_file,MyFlags)); if (to_file >= 0) VOID(my_close(to_file,MyFlags)); DBUG_RETURN(-1); } /* my_copy */
static int wclique(int _n, int w[], unsigned char _a[], int sol[]) { struct dsa _dsa, *dsa = &_dsa; int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos; xlong_t timer; n = _n; wt = &w[1]; a = _a; record = 0; rec_level = 0; rec = &sol[1]; clique = xcalloc(n, sizeof(int)); set = xcalloc(n, sizeof(int)); used = xcalloc(n, sizeof(int)); nwt = xcalloc(n, sizeof(int)); pos = xcalloc(n, sizeof(int)); /* start timer */ timer = xtime(); /* order vertices */ for (i = 0; i < n; i++) { nwt[i] = 0; for (j = 0; j < n; j++) if (is_edge(dsa, i, j)) nwt[i] += wt[j]; } for (i = 0; i < n; i++) used[i] = 0; for (i = n-1; i >= 0; i--) { max_wt = -1; max_nwt = -1; for (j = 0; j < n; j++) { if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt && nwt[j] > max_nwt))) { max_wt = wt[j]; max_nwt = nwt[j]; p = j; } } pos[i] = p; used[p] = 1; for (j = 0; j < n; j++) if ((!used[j]) && (j != p) && (is_edge(dsa, p, j))) nwt[j] -= wt[p]; } /* main routine */ wth = 0; for (i = 0; i < n; i++) { wth += wt[pos[i]]; sub(dsa, i, pos, 0, 0, wth); clique[pos[i]] = record; #if 0 if (utime() >= timer + 5.0) #else if (xdifftime(xtime(), timer) >= 5.0 - 0.001) #endif { /* print current record and reset timer */ xprintf("level = %d (%d); best = %d\n", i+1, n, record); #if 0 timer = utime(); #else timer = xtime(); #endif } } xfree(clique); xfree(set); xfree(used); xfree(nwt); xfree(pos); /* return the solution found */ for (i = 1; i <= rec_level; i++) sol[i]++; return rec_level; }
static void * worker_thread_handler(void * x) { WorkerThread * wt = (WorkerThread *)x; for (;;) { AsyncReqInfo * req = wt->req; assert(req != NULL); req->error = 0; switch(req->type) { case AsyncReqTimer: #if defined(_WIN32) && !defined(__CYGWIN__) Sleep(EVENTS_TIMER_RESOLUTION); events_timer_ms = GetTickCount(); #else { struct timespec timenow; usleep(EVENTS_TIMER_RESOLUTION * 1000); if (clock_gettime(CLOCK_REALTIME, &timenow) == 0) { events_timer_ms = (uint32_t)(timenow.tv_nsec / 1000000 + timenow.tv_sec * 1000); } } #endif break; case AsyncReqRead: /* File read */ req->u.fio.rval = read(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqWrite: /* File write */ req->u.fio.rval = write(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqSeekRead: /* File read at offset */ req->u.fio.rval = pread(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqSeekWrite: /* File write at offset */ req->u.fio.rval = pwrite(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqRecv: /* Socket recv */ req->u.sio.rval = recv(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags); if (req->u.sio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqSend: /* Socket send */ req->u.sio.rval = send(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags); if (req->u.sio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqRecvFrom: /* Socket recvfrom */ req->u.sio.rval = recvfrom(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, &req->u.sio.addrlen); if (req->u.sio.rval == -1) { req->error = errno; trace(LOG_ASYNCREQ, "AsyncReqRecvFrom: req %p, type %d, error %d", req, req->type, req->error); assert(req->error); } break; case AsyncReqSendTo: /* Socket sendto */ req->u.sio.rval = sendto(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, req->u.sio.addrlen); if (req->u.sio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqAccept: /* Accept socket connections */ req->u.acc.rval = accept(req->u.acc.sock, req->u.acc.addr, req->u.acc.addr ? &req->u.acc.addrlen : NULL); if (req->u.acc.rval == -1) { req->error = errno; trace(LOG_ASYNCREQ, "AsyncReqAccept: req %p, type %d, error %d", req, req->type, req->error); assert(req->error); } break; case AsyncReqConnect: /* Connect to socket */ req->u.con.rval = connect(req->u.con.sock, req->u.con.addr, req->u.con.addrlen); if (req->u.con.rval == -1) { req->error = errno; trace(LOG_ASYNCREQ, "AsyncReqConnect: req %p, type %d, error %d", req, req->type, req->error); assert(req->error); } break; /* Platform dependant IO methods */ #if defined(_WIN32) || defined(__CYGWIN__) case AsyncReqConnectPipe: req->u.cnp.rval = ConnectNamedPipe(req->u.cnp.pipe, NULL); if (!req->u.cnp.rval) { req->error = set_win32_errno(GetLastError()); assert(req->error); } break; #elif defined(_WRS_KERNEL) #else case AsyncReqWaitpid: /* Wait for process change */ req->u.wpid.rval = waitpid(req->u.wpid.pid, &req->u.wpid.status, req->u.wpid.options); if (req->u.wpid.rval == -1) { req->error = errno; assert(req->error); } break; #endif case AsyncReqSelect: { struct timeval tv; tv.tv_sec = (long)req->u.select.timeout.tv_sec; tv.tv_usec = req->u.select.timeout.tv_nsec / 1000; req->u.select.rval = select(req->u.select.nfds, &req->u.select.readfds, &req->u.select.writefds, &req->u.select.errorfds, &tv); if (req->u.select.rval == -1) { req->error = errno; assert(req->error); } } break; case AsyncReqClose: req->u.fio.rval = close(req->u.fio.fd); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqCloseDir: req->u.dio.rval = closedir((DIR *)req->u.dio.dir); if (req->u.dio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqOpen: req->u.fio.rval = open(req->u.fio.file_name, req->u.fio.flags, req->u.fio.permission); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqOpenDir: req->u.dio.dir = opendir(req->u.dio.path); if (req->u.dio.dir == NULL) { req->error = errno; assert(req->error); } break; case AsyncReqFstat: memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf)); req->u.fio.rval = fstat(req->u.fio.fd, &req->u.fio.statbuf); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } #if defined(_WIN32) || defined(__CYGWIN__) req->u.fio.win32_attrs = req->error || !req->u.fio.file_name ? INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name); #endif break; case AsyncReqStat: memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf)); req->u.fio.rval = stat(req->u.fio.file_name, &req->u.fio.statbuf); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } #if defined(_WIN32) || defined(__CYGWIN__) req->u.fio.win32_attrs = req->error ? INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name); #endif break; case AsyncReqLstat: memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf)); req->u.fio.rval = lstat(req->u.fio.file_name, &req->u.fio.statbuf); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } #if defined(_WIN32) || defined(__CYGWIN__) req->u.fio.win32_attrs = req->error ? INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name); #endif break; case AsyncReqSetStat: { int err = 0; if (req->u.fio.set_stat_flags & AsyncReqSetSize) { if (truncate(req->u.fio.file_name, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno; } if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) { if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno; } #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL) # if defined(_WIN32) || defined(__CYGWIN__) if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) { if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0) err = set_win32_errno(GetLastError()); } # endif #else if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) { if (chown(req->u.fio.file_name, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno; } #endif if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) { struct utimbuf buf; buf.actime = req->u.fio.statbuf.st_atime; buf.modtime = req->u.fio.statbuf.st_mtime; if (utime(req->u.fio.file_name, &buf) < 0) err = errno; } req->error = err; } break; case AsyncReqFSetStat: { int err = 0; if (req->u.fio.set_stat_flags & AsyncReqSetSize) { if (ftruncate(req->u.fio.fd, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno; } #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL) if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) { if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno; } # if defined(_WIN32) || defined(__CYGWIN__) if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) { if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0) err = set_win32_errno(GetLastError()); } # endif #else if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) { if (fchown(req->u.fio.fd, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno; } if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) { if (fchmod(req->u.fio.fd, req->u.fio.statbuf.st_mode) < 0) err = errno; } #endif if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) { struct utimbuf buf; buf.actime = req->u.fio.statbuf.st_atime; buf.modtime = req->u.fio.statbuf.st_mtime; #if defined(_WIN32) && !defined(__MINGW32__) if (futime(req->u.fio.fd, &buf) < 0) err = errno; #else if (utime(req->u.fio.file_name, &buf) < 0) err = errno; #endif } req->error = err; } break; case AsyncReqRemove: req->u.fio.rval = remove(req->u.fio.file_name); if (req->u.fio.rval == -1) { req->error = errno; assert(req->error); } break; case AsyncReqReadDir: { int cnt = 0; while (cnt < req->u.dio.max_files) { char path[FILE_PATH_SIZE]; struct DirFileNode * file = req->u.dio.files + cnt; struct dirent * e; struct stat st; errno = 0; e = readdir((DIR *)req->u.dio.dir); if (e == NULL) { req->error = errno; if (req->error == 0) req->u.dio.eof = 1; break; } if (strcmp(e->d_name, ".") == 0) continue; if (strcmp(e->d_name, "..") == 0) continue; file->path = loc_strdup(e->d_name); memset(&st, 0, sizeof(st)); snprintf(path, sizeof(path), "%s/%s", req->u.dio.path, e->d_name); if (stat(path, &st) == 0) { #if defined(_WIN32) || defined(__CYGWIN__) file->win32_attrs = GetFileAttributes(path); #endif file->statbuf = (struct stat *)loc_alloc(sizeof(struct stat)); memcpy(file->statbuf, &st, sizeof(struct stat)); } cnt++; } } break; case AsyncReqRoots: { struct stat st; struct RootDevNode * newDevNode = NULL; #if defined(_WIN32) || defined(__CYGWIN__) { struct RootDevNode * curDevNode = NULL; int disk = 0; DWORD disks = GetLogicalDrives(); for (disk = 0; disk <= 30; disk++) { if (disks & (1 << disk)) { char path[32]; newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode)); if (curDevNode == NULL) req->u.root.lst = newDevNode; else curDevNode->next = newDevNode; curDevNode = newDevNode; snprintf(path, sizeof(path), "%c:\\", 'A' + disk); newDevNode->devname = loc_strdup(path); if (disk >= 2) { ULARGE_INTEGER total_number_of_bytes; BOOL has_size = GetDiskFreeSpaceExA(path, NULL, &total_number_of_bytes, NULL); memset(&st, 0, sizeof(st)); #if defined(__CYGWIN__) snprintf(path, sizeof(path), "/cygdrive/%c", 'a' + disk); #endif if (has_size && stat(path, &st) == 0) { newDevNode->win32_attrs = GetFileAttributes(path); newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat)); memcpy(newDevNode->statbuf, &st, sizeof(struct stat)); } } } } } #elif defined(_WRS_KERNEL) { struct RootDevNode * curDevNode = NULL; extern DL_LIST iosDvList; DEV_HDR * dev; for (dev = (DEV_HDR *)DLL_FIRST(&iosDvList); dev != NULL; dev = (DEV_HDR *)DLL_NEXT(&dev->node)) { char path[FILE_PATH_SIZE]; if (strcmp(dev->name, "host:") == 0) { /* Windows host is special case */ int d; for (d = 'a'; d < 'z'; d++) { snprintf(path, sizeof(path), "%s%c:/", dev->name, d); if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) { newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode)); if (curDevNode == NULL) req->u.root.lst = newDevNode; else curDevNode->next = newDevNode; curDevNode = newDevNode; newDevNode->devname = loc_strdup(path); newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat)); memcpy(newDevNode->statbuf, &st, sizeof(struct stat)); } } } snprintf(path, sizeof(path), "%s/", dev->name); if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) { newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode)); if (curDevNode == NULL) req->u.root.lst = newDevNode; else curDevNode->next = newDevNode; curDevNode = newDevNode; newDevNode->devname = loc_strdup(path); newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat)); memcpy(newDevNode->statbuf, &st, sizeof(struct stat)); } } } #else req->u.root.lst = newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode)); newDevNode->devname = loc_strdup("/"); if (stat("/", &st) == 0) { newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat)); memcpy(newDevNode->statbuf, &st, sizeof(struct stat)); } #endif } break; case AsyncReqUser: /* User defined request */ req->u.user.rval = req->u.user.func(req->u.user.data); if (req->u.user.rval == -1) { req->error = errno; assert(req->error); } break; default: req->error = ENOSYS; break; } if (req->type == AsyncReqTimer) { if (async_shutdown.state == SHUTDOWN_STATE_PENDING) break; continue; } trace(LOG_ASYNCREQ, "async_req_complete: req %p, type %d, error %d", req, req->type, req->error); check_error(pthread_mutex_lock(&wtlock)); /* Post event inside lock to make sure a new worker thread is not created unnecessarily */ post_event(req->done, req); wt->req = NULL; if (wtlist_size >= MAX_WORKER_THREADS || async_shutdown.state == SHUTDOWN_STATE_PENDING) { check_error(pthread_mutex_unlock(&wtlock)); break; } list_add_last(&wt->wtlink, &wtlist); wtlist_size++; for (;;) { check_error(pthread_cond_wait(&wt->cond, &wtlock)); if (wt->req != NULL) break; } check_error(pthread_mutex_unlock(&wtlock)); if (wt->req == &shutdown_req) break; } post_event(worker_thread_exit, wt); return NULL; }
static void copyfile( char *name, char *toname, mode_t mode, char *group, char *owner, int dotimes, uid_t uid, gid_t gid ) { int fromfd, tofd, cc, wc, exists; char buf[BUFSIZ], *bp; struct stat sb, tosb; struct utimbuf utb; exists = (lstat(toname, &tosb) == 0); fromfd = open(name, O_RDONLY); if (fromfd < 0 || fstat(fromfd, &sb) < 0) fail("cannot access %s", name); if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); tofd = open(toname, O_CREAT | O_WRONLY, 0666); if (tofd < 0) fail("cannot create %s", toname); bp = buf; while ((cc = read(fromfd, bp, sizeof buf)) > 0) { while ((wc = write(tofd, bp, (unsigned int)cc)) > 0) { if ((cc -= wc) == 0) break; bp += wc; } if (wc < 0) fail("cannot write to %s", toname); } if (cc < 0) fail("cannot read from %s", name); if (ftruncate(tofd, sb.st_size) < 0) fail("cannot truncate %s", toname); #if !defined(VMS) if (dotimes) { utb.actime = sb.st_atime; utb.modtime = sb.st_mtime; if (utime(toname, &utb) < 0) fail("cannot set times of %s", toname); } #ifdef HAVE_FCHMOD if (fchmod(tofd, mode) < 0) #else if (chmod(toname, mode) < 0) #endif fail("cannot change mode of %s", toname); #endif if ((owner || group) && fchown(tofd, uid, gid) < 0) fail("cannot change owner of %s", toname); /* Must check for delayed (NFS) write errors on close. */ if (close(tofd) < 0) fail("cannot write to %s", toname); close(fromfd); #if defined(VMS) if (chmod(toname, (mode & (S_IREAD | S_IWRITE))) < 0) fail("cannot change mode of %s", toname); if (dotimes) { utb.actime = sb.st_atime; utb.modtime = sb.st_mtime; if (utime(toname, &utb) < 0) fail("cannot set times of %s", toname); } #endif }
/* * incremental: incremental update * * i) dbpath dbpath directory * i) root root directory of source tree * r) 0: not updated, 1: updated */ int incremental(const char *dbpath, const char *root) { STATISTICS_TIME *tim; struct stat statp; STRBUF *addlist = strbuf_open(0); STRBUF *deletelist = strbuf_open(0); STRBUF *addlist_other = strbuf_open(0); IDSET *deleteset, *findset; int updated = 0; const char *path; unsigned int id, limit; tim = statistics_time_start("Time of inspecting %s and %s.", dbname(GTAGS), dbname(GRTAGS)); if (vflag) { fprintf(stderr, " Tag found in '%s'.\n", dbpath); fprintf(stderr, " Incremental updating.\n"); } /* * get modified time of GTAGS. */ path = makepath(dbpath, dbname(GTAGS), NULL); if (gpath_open(dbpath, 0) < 0) die("GPATH not found."); /* * deleteset: * The list of the path name which should be deleted from GPATH. * findset: * The list of the path name which exists in the current project. * A project is limited by the --file option. */ deleteset = idset_open(gpath_nextkey()); findset = idset_open(gpath_nextkey()); total = 0; /* * Make add list and delete list for update. */ if (single_update) { int type; const char *fid = gpath_path2fid(single_update, &type); /* * The --single-update=file supports only updating. * If it is new file, this option is ignored, and the processing is * automatically switched to the normal procedure. */ if (fid == NULL) { if (vflag) fprintf(stderr, " --single-update option ignored, because '%s' is new file.\n", single_update); goto normal_update; } /* * If type != GPATH_SOURCE then we have nothing to do, and you will see * a message 'Global databases are up to date.'. */ if (type == GPATH_SOURCE) { strbuf_puts0(addlist, single_update); idset_add(deleteset, atoi(fid)); total++; } } else { normal_update: if (file_list) find_open_filelist(file_list, root); else find_open(NULL); while ((path = find_read()) != NULL) { const char *fid; int n_fid = 0; int other = 0; /* a blank at the head of path means 'NOT SOURCE'. */ if (*path == ' ') { if (test("b", ++path)) continue; other = 1; } if (stat(path, &statp) < 0) die("stat failed '%s'.", path); fid = gpath_path2fid(path, NULL); if (fid) { n_fid = atoi(fid); idset_add(findset, n_fid); } if (other) { if (fid == NULL) strbuf_puts0(addlist_other, path); } else { if (fid == NULL) { strbuf_puts0(addlist, path); total++; } else if (gpath_mtime(NULL, fid) < statp.st_mtime) { if (uflag) { printf("%s\n", path); } else { strbuf_puts0(addlist, path); total++; idset_add(deleteset, n_fid); } } } } find_close(); /* * make delete list. */ if (remove_lost) { limit = gpath_nextkey(); } else { limit = 0; } for (id = 1; id < limit; id++) { char fid[MAXFIDLEN]; int type; snprintf(fid, sizeof(fid), "%d", id); /* * This is a hole of GPATH. The hole increases if the deletion * and the addition are repeated. */ if ((path = gpath_fid2path(fid, &type)) == NULL) continue; /* * The file which does not exist in the findset is treated * assuming that it does not exist in the file system. */ if (type == GPATH_OTHER) { if (!idset_contains(findset, id) || !test("f", path) || test("b", path)) strbuf_puts0(deletelist, path); } else { if (!idset_contains(findset, id) || !test("f", path)) { strbuf_puts0(deletelist, path); idset_add(deleteset, id); } } } } gpath_close(); statistics_time_end(tim); /* * execute updating. */ if ((!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) || (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0)) { int db; updated = 1; tim = statistics_time_start("Time of updating %s and %s.", dbname(GTAGS), dbname(GRTAGS)); if (!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) updatetags(dbpath, root, deleteset, addlist); if (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0) { const char *start, *end, *p; if (vflag) fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(GPATH)); gpath_open(dbpath, 2); if (strbuf_getlen(deletelist) > 0) { start = strbuf_value(deletelist); end = start + strbuf_getlen(deletelist); for (p = start; p < end; p += strlen(p) + 1) gpath_delete(p); } if (strbuf_getlen(addlist_other) > 0) { start = strbuf_value(addlist_other); end = start + strbuf_getlen(addlist_other); for (p = start; p < end; p += strlen(p) + 1) gpath_put(p, GPATH_OTHER); } gpath_close(); } /* * Update modification time of tag files * because they may have no definitions. */ for (db = GTAGS; db < GTAGLIM; db++) utime(makepath(dbpath, dbname(db), NULL), NULL); statistics_time_end(tim); } if (vflag) { if (updated) fprintf(stderr, " Global databases have been modified.\n"); else fprintf(stderr, " Global databases are up to date.\n"); fprintf(stderr, "[%s] Done.\n", now()); } strbuf_close(addlist); strbuf_close(deletelist); strbuf_close(addlist_other); idset_close(deleteset); idset_close(findset); return updated; }
int cppath(int a_ctrl, char *a_srcPath, char *a_dstPath, mode_t a_mode) { char *linknam = (char *)NULL; int dstFd; int len; int srcFd; long status; struct stat srcStatbuf; struct utimbuf times; /* entry debugging info */ echoDebug(DBG_CPPATH_ENTRY, a_ctrl, a_mode, a_srcPath, a_dstPath); /* open source file for reading */ srcFd = open(a_srcPath, O_RDONLY); if (srcFd < 0) { progerr(ERR_OPEN_READ, a_srcPath, errno, strerror(errno)); return (1); } /* obtain file status of source file */ if (fstat(srcFd, &srcStatbuf) != 0) { progerr(ERR_FSTAT, srcFd, a_srcPath, errno, strerror(errno)); (void) close(srcFd); return (1); } /* * Determine the permissions mode for the destination: * - if MODE_SET is specified: * --> use a_mode (do not mask off any portion) * --> If a_mode is unknown (? in the pkgmap), then the file gets * --> installed with the default 0644 mode * - if MODE_SRC is specified: * --> use the mode of the source (srcStatbuf.st_mode) but mask off all * --> non-access mode bits (remove SET?UID bits) * - otherwise: * --> use 0666 */ if (a_ctrl & MODE_SET) { mode_t usemode; usemode = (a_mode ^ BADMODE) ? a_mode : 0644; if (a_mode != usemode && usemode == 0644) { logerr(WRN_DEF_MODE, a_dstPath); a_mode = usemode; } } else if (a_ctrl & MODE_SRC) { a_mode = (srcStatbuf.st_mode & S_IAMB); } else { a_mode = 0666; } /* * Get fd of newly created destination file or, if this * is an overwrite, a temporary file (linknam). */ dstFd = write_file(&linknam, a_ctrl, a_mode, a_dstPath); if (dstFd < 0) { (void) close(srcFd); return (1); } /* * source and target files are open: copy data */ status = copyFile(srcFd, dstFd, a_srcPath, a_dstPath, &srcStatbuf, 0); (void) close(srcFd); (void) close(dstFd); if (status != 0) { progerr(ERR_INPUT, a_srcPath, errno, strerror(errno)); if (linknam) { (void) remove(linknam); } return (1); } /* * If this is an overwrite, rename temp over original */ if ((linknam != (char *)NULL) && (rename(linknam, a_dstPath) != 0)) { FILE *logfp = (FILE *)NULL; char busylog[PATH_MAX]; /* output log message if busy else program error */ if (errno == ETXTBSY) { logerr(MSG_PROCMV, linknam); } else { progerr(ERR_OUTPUT_WRITING, a_dstPath, errno, strerror(errno)); } (void) remove(linknam); /* open the log file and append log entry */ len = snprintf(busylog, sizeof (busylog), "%s/textbusy", get_PKGADM()); if (len > sizeof (busylog)) { progerr(ERR_CREATE_PATH_2, get_PKGADM(), "textbusy"); } else { logfp = fopen(busylog, "a"); if (logfp == NULL) { progerr(ERR_LOG, busylog, errno, strerror(errno)); } else { (void) fprintf(logfp, "%s\n", linknam); (void) fclose(logfp); } } } /* set access/modification times for target */ times.actime = srcStatbuf.st_atime; times.modtime = srcStatbuf.st_mtime; if (utime(a_dstPath, ×) != 0) { progerr(ERR_MODTIM, a_dstPath, errno, strerror(errno)); return (1); } /* success! */ return (0); }
int sim_make_ROM_include(const char *rom_filename, int expected_size, unsigned int expected_checksum, const char *include_filename, const char *rom_array_name, const char *Comments) { FILE *rFile; FILE *iFile; time_t now; int bytes_written = 0; int include_bytes; int c; struct stat statb; const char *load_filename; unsigned char *ROMData = NULL; unsigned char *include_ROMData = NULL; char *include_array_name = NULL; unsigned int checksum = 0; unsigned int include_checksum; int defines_found; if (NULL == (rFile = fopen (rom_filename, "rb"))) { printf ("Error Opening ROM binary file '%s' for input: %s\n", rom_filename, strerror(errno)); if (0 != sim_read_ROM_include(include_filename, &include_bytes, &include_ROMData, &include_checksum, &include_array_name, &defines_found)) return -1; c = ((include_checksum == expected_checksum) && (include_bytes == expected_size) && (0 == strcmp(include_array_name, rom_array_name)) && defines_found); free(include_ROMData); free(include_array_name); if (!c) printf ("Existing ROM include file: %s has unexpected content\n", include_filename); else printf ("Existing ROM include file: %s looks good\n", include_filename); return (c ? 0 : -1); } if (stat (rom_filename, &statb)) { printf ("Error stating '%s': %s\n", rom_filename, strerror(errno)); fclose (rFile); return -1; } if (statb.st_size != expected_size) { printf ("Error: ROM file '%s' has an unexpected size: %d vs %d\n", rom_filename, (int)statb.st_size, expected_size); printf ("This can happen if the file was transferred or unpacked incorrectly\n"); printf ("and in the process tried to convert line endings rather than passing\n"); printf ("the file's contents unmodified\n"); fclose (rFile); return -1; } ROMData = (unsigned char *)malloc (statb.st_size); if ((size_t)(statb.st_size) != fread (ROMData, sizeof(*ROMData), statb.st_size, rFile)) { printf ("Error reading '%s': %s\n", rom_filename, strerror(errno)); fclose (rFile); free (ROMData); return -1; } fclose (rFile); for (c=0; c<statb.st_size; ++c) checksum += ROMData[c]; checksum = ~checksum; if ((expected_checksum != 0) && (checksum != expected_checksum)) { printf ("Error: ROM file '%s' has an unexpected checksum: 0x%08X vs 0x%08X\n", rom_filename, checksum, expected_checksum); printf ("This can happen if the file was transferred or unpacked incorrectly\n"); printf ("and in the process tried to convert line endings rather than passing\n"); printf ("the file's contents unmodified\n"); free (ROMData); return -1; } /* * If the target include file already exists, determine if it contains the exact * data in the base ROM image. If so, then we are already done */ if (0 == sim_read_ROM_include(include_filename, &include_bytes, &include_ROMData, &include_checksum, &include_array_name, &defines_found)) { c = ((include_checksum == expected_checksum) && (include_bytes == expected_size) && (0 == strcmp (include_array_name, rom_array_name)) && (0 == memcmp (include_ROMData, ROMData, include_bytes)) && defines_found); free(include_ROMData); free(include_array_name); if (c) { free (ROMData); return 0; } } if (NULL == (iFile = fopen (include_filename, "w"))) { printf ("Error Opening '%s' for output: %s\n", include_filename, strerror(errno)); free (ROMData); return -1; } load_filename = strrchr (rom_filename, '/'); if (load_filename) ++load_filename; else load_filename = rom_filename; time (&now); fprintf (iFile, "#ifndef ROM_%s_H\n", rom_array_name); fprintf (iFile, "#define ROM_%s_H 0\n", rom_array_name); fprintf (iFile, "/*\n"); fprintf (iFile, " %s produced at %s", include_filename, ctime(&now)); fprintf (iFile, " from %s which was last modified at %s", rom_filename, ctime(&statb.st_mtime)); fprintf (iFile, " file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum); fprintf (iFile, " This file is a generated file and should NOT be edited or changed by hand.\n"); if (Comments) fprintf (iFile, "\n %s\n\n", Comments); fprintf (iFile, "*/\n"); fprintf (iFile, "#define BOOT_CODE_SIZE 0x%X\n", (int)statb.st_size); fprintf (iFile, "#define BOOT_CODE_FILENAME \"%s\"\n", load_filename); fprintf (iFile, "#define BOOT_CODE_ARRAY %s\n", rom_array_name); fprintf (iFile, "unsigned char %s[] = {", rom_array_name); for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) { c = ROMData[bytes_written]; if (0 == bytes_written%16) fprintf (iFile,"\n"); fprintf (iFile,"0x%02X,", c&0xFF); } free (ROMData); fprintf (iFile,"};\n"); fprintf (iFile, "#endif /* ROM_%s_H */\n", rom_array_name); fclose (iFile); if (1) { /* Set Modification Time on the include file to be the modification time of the ROM file */ struct utimbuf times; times.modtime = statb.st_mtime; times.actime = statb.st_atime; utime (include_filename, ×); } return 0; }
int my_copy(const char *from, const char *to, myf MyFlags) { size_t Count; my_bool new_file_stat= 0; /* 1 if we could stat "to" */ int create_flag; File from_file,to_file; uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); from_file=to_file= -1; DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */ if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */ new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0))); if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0) { if (!my_stat(from, &stat_buff, MyFlags)) { my_errno=errno; goto err; } if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat) stat_buff=new_stat_buff; create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC; if ((to_file= my_create(to,(int) stat_buff.st_mode, O_WRONLY | create_flag | O_BINARY | O_SHARE, MyFlags)) < 0) goto err; while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0) { if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; } /* sync the destination file */ if (MyFlags & MY_SYNC) { if (my_sync(to_file, MyFlags)) goto err; } if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ /* Copy modes if possible */ if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ /* Copy modes */ if (chmod(to, stat_buff.st_mode & 07777)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno, my_strerror(errbuf, sizeof(errbuf), errno)); } goto err; } #if !defined(__WIN__) /* Copy ownership */ if (chown(to, stat_buff.st_uid, stat_buff.st_gid)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno, my_strerror(errbuf, sizeof(errbuf), errno)); } goto err; } #endif if (MyFlags & MY_COPYTIME) { struct utimbuf timep; timep.actime = stat_buff.st_atime; timep.modtime = stat_buff.st_mtime; (void) utime((char*) to, &timep); /* last accessed and modified times */ } DBUG_RETURN(0); } err: if (from_file >= 0) (void) my_close(from_file,MyFlags); if (to_file >= 0) { (void) my_close(to_file, MyFlags); /* attempt to delete the to-file we've partially written */ (void) my_delete(to, MyFlags); } DBUG_RETURN(-1); } /* my_copy */
int main(int ac, char **av) { struct stat stat_buf; /* struct buffer to hold file info. */ int lc; long type; time_t modf_time, access_time; time_t pres_time; /* file modification/access/present time */ tst_parse_opts(ac, av, NULL, NULL); setup(); switch ((type = tst_fs_type(cleanup, "."))) { case TST_NFS_MAGIC: if (tst_kvercmp(2, 6, 18) < 0) tst_brkm(TCONF, cleanup, "Cannot do utime on a file" " on %s filesystem before 2.6.18", tst_fs_type_name(type)); break; case TST_V9FS_MAGIC: tst_brkm(TCONF, cleanup, "Cannot do utime on a file on %s filesystem", tst_fs_type_name(type)); break; } for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; /* * Invoke utime(2) to set TEMP_FILE access and * modification times to the current time. */ TEST(utime(TEMP_FILE, NULL)); if (TEST_RETURN == -1) { tst_resm(TFAIL, "utime(%s) Failed, errno=%d : %s", TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO)); } else { /* * Sleep for a second so that mod time and * access times will be different from the * current time */ sleep(2); /* * Get the current time now, after calling * utime(2) */ if ((pres_time = time(&tloc)) < 0) { tst_brkm(TFAIL, cleanup, "time() " "failed to get present time " "after utime, error=%d", errno); } /* * Get the modification and access times of * temporary file using stat(2). */ if (stat(TEMP_FILE, &stat_buf) < 0) { tst_brkm(TFAIL, cleanup, "stat(2) of " "%s failed, error:%d", TEMP_FILE, TEST_ERRNO); } modf_time = stat_buf.st_mtime; access_time = stat_buf.st_atime; /* Now do the actual verification */ if (modf_time <= curr_time || modf_time >= pres_time || access_time <= curr_time || access_time >= pres_time) { tst_resm(TFAIL, "%s access and " "modification times not set", TEMP_FILE); } else { tst_resm(TPASS, "Functionality of " "utime(%s, NULL) successful", TEMP_FILE); } } tst_count++; } cleanup(); tst_exit(); }
int main(int argc, char **argv) { int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc; mode_t mode = 0755; char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ]; uid_t uid; gid_t gid; struct stat sb, tosb; struct utimbuf utb; program = argv[0]; cwd = linkname = linkprefix = owner = group = 0; onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0; while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) { switch (opt) { case 'C': cwd = optarg; break; case 'D': onlydir = 1; break; case 'd': dodir = 1; break; case 'l': dolink = 1; break; case 'L': linkprefix = optarg; lplen = strlen(linkprefix); dolink = 1; break; case 'R': dolink = dorelsymlink = 1; break; case 'm': mode = strtoul(optarg, &cp, 8); if (mode == 0 && cp == optarg) usage(); break; case 'o': owner = optarg; break; case 'g': group = optarg; break; case 't': dotimes = 1; break; default: usage(); } } argc -= optind; argv += optind; if (argc < 2 - onlydir) usage(); todir = argv[argc-1]; if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) && mkdirs(todir, 0777) < 0) { fail("cannot make directory %s", todir); } if (onlydir) return 0; if (!cwd) { #ifdef GETCWD_CAN_MALLOC cwd = getcwd(0, PATH_MAX); #else cwd = malloc(PATH_MAX + 1); cwd = getcwd(cwd, PATH_MAX); #endif } xchdir(todir); #ifdef GETCWD_CAN_MALLOC todir = getcwd(0, PATH_MAX); #else todir = malloc(PATH_MAX + 1); todir = getcwd(todir, PATH_MAX); #endif tdlen = strlen(todir); xchdir(cwd); tdlen = strlen(todir); uid = owner ? touid(owner) : -1; gid = group ? togid(group) : -1; while (--argc > 0) { name = *argv++; len = strlen(name); base = xbasename(name); bnlen = strlen(base); toname = (char*)xmalloc(tdlen + 1 + bnlen + 1); sprintf(toname, "%s/%s", todir, base); exists = (lstat(toname, &tosb) == 0); if (dodir) { /* -d means create a directory, always */ if (exists && !S_ISDIR(tosb.st_mode)) { (void) unlink(toname); exists = 0; } if (!exists && mkdir(toname, mode) < 0) fail("cannot make directory %s", toname); if ((owner || group) && chown(toname, uid, gid) < 0) fail("cannot change owner of %s", toname); } else if (dolink) { if (*name == '/') { /* source is absolute pathname, link to it directly */ linkname = 0; } else { if (linkprefix) { /* -L implies -l and prefixes names with a $cwd arg. */ len += lplen + 1; linkname = (char*)xmalloc(len + 1); sprintf(linkname, "%s/%s", linkprefix, name); } else if (dorelsymlink) { /* Symlink the relative path from todir to source name. */ linkname = (char*)xmalloc(PATH_MAX); if (*todir == '/') { /* todir is absolute: skip over common prefix. */ lplen = relatepaths(todir, cwd, linkname); strcpy(linkname + lplen, name); } else { /* todir is named by a relative path: reverse it. */ reversepath(todir, name, len, linkname); xchdir(cwd); } len = strlen(linkname); } name = linkname; } /* Check for a pre-existing symlink with identical content. */ if (exists && (!S_ISLNK(tosb.st_mode) || readlink(toname, buf, sizeof buf) != len || strncmp(buf, name, len) != 0)) { (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); exists = 0; } if (!exists && symlink(name, toname) < 0) fail("cannot make symbolic link %s", toname); #ifdef HAVE_LCHOWN if ((owner || group) && lchown(toname, uid, gid) < 0) fail("cannot change owner of %s", toname); #endif if (linkname) { free(linkname); linkname = 0; } } else { /* Copy from name to toname, which might be the same file. */ fromfd = open(name, O_RDONLY); if (fromfd < 0 || fstat(fromfd, &sb) < 0) fail("cannot access %s", name); if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); tofd = open(toname, O_CREAT | O_WRONLY, 0666); if (tofd < 0) fail("cannot create %s", toname); bp = buf; while ((cc = read(fromfd, bp, sizeof buf)) > 0) { while ((wc = write(tofd, bp, cc)) > 0) { if ((cc -= wc) == 0) break; bp += wc; } if (wc < 0) fail("cannot write to %s", toname); } if (cc < 0) fail("cannot read from %s", name); if (ftruncate(tofd, sb.st_size) < 0) fail("cannot truncate %s", toname); if (dotimes) { utb.actime = sb.st_atime; utb.modtime = sb.st_mtime; if (utime(toname, &utb) < 0) fail("cannot set times of %s", toname); } #ifdef HAVE_FCHMOD if (fchmod(tofd, mode) < 0) #else if (chmod(toname, mode) < 0) #endif fail("cannot change mode of %s", toname); if ((owner || group) && fchown(tofd, uid, gid) < 0) fail("cannot change owner of %s", toname); /* Must check for delayed (NFS) write errors on close. */ if (close(tofd) < 0) fail("cannot write to %s", toname); close(fromfd); } free(toname); } free(cwd); free(todir); return 0; }
static ssize_t uv__fs_utime(uv_fs_t* req) { struct utimbuf buf; buf.actime = req->atime; buf.modtime = req->mtime; return utime(req->path, &buf); /* TODO use utimes() where available */ }
int dexopt(const char *apk_path, uid_t uid, int is_public) { struct utimbuf ut; struct stat apk_stat, dex_stat; char out_path[PKG_PATH_MAX]; char dexopt_flags[PROPERTY_VALUE_MAX]; char persist_sys_dalvik_vm_lib[PROPERTY_VALUE_MAX]; char *end; int res, zip_fd=-1, out_fd=-1; if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) { return -1; } /* platform-specific flags affecting optimization and verification */ property_get("dalvik.vm.dexopt-flags", dexopt_flags, ""); ALOGV("dalvik.vm.dexopt_flags=%s\n", dexopt_flags); /* The command to run depend ones the value of persist.sys.dalvik.vm.lib */ property_get("persist.sys.dalvik.vm.lib", persist_sys_dalvik_vm_lib, "libdvm.so"); /* Before anything else: is there a .odex file? If so, we have * precompiled the apk and there is nothing to do here. */ sprintf(out_path, "%s%s", apk_path, ".odex"); if (stat(out_path, &dex_stat) == 0) { return 0; } if (create_cache_path(out_path, apk_path)) { return -1; } memset(&apk_stat, 0, sizeof(apk_stat)); stat(apk_path, &apk_stat); zip_fd = open(apk_path, O_RDONLY, 0); if (zip_fd < 0) { ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path); return -1; } unlink(out_path); out_fd = open(out_path, O_RDWR | O_CREAT | O_EXCL, 0644); if (out_fd < 0) { ALOGE("installd cannot open '%s' for output during dexopt\n", out_path); goto fail; } if (fchmod(out_fd, S_IRUSR|S_IWUSR|S_IRGRP | (is_public ? S_IROTH : 0)) < 0) { ALOGE("installd cannot chmod '%s' during dexopt\n", out_path); goto fail; } if (fchown(out_fd, AID_SYSTEM, uid) < 0) { ALOGE("installd cannot chown '%s' during dexopt\n", out_path); goto fail; } ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path); pid_t pid; pid = fork(); if (pid == 0) { /* child -- drop privileges before continuing */ if (setgid(uid) != 0) { ALOGE("setgid(%d) failed in installd during dexopt\n", uid); exit(64); } if (setuid(uid) != 0) { ALOGE("setuid(%d) failed in installd during dexopt\n", uid); exit(65); } // drop capabilities struct __user_cap_header_struct capheader; struct __user_cap_data_struct capdata[2]; memset(&capheader, 0, sizeof(capheader)); memset(&capdata, 0, sizeof(capdata)); capheader.version = _LINUX_CAPABILITY_VERSION_3; if (capset(&capheader, &capdata[0]) < 0) { ALOGE("capset failed: %s\n", strerror(errno)); exit(66); } if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) { ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno)); exit(67); } if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) { run_dexopt(zip_fd, out_fd, apk_path, out_path, dexopt_flags); } else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) { run_dex2oat(zip_fd, out_fd, apk_path, out_path, dexopt_flags); } else { exit(69); /* Unexpected persist.sys.dalvik.vm.lib value */ } exit(68); /* only get here on exec failure */ } else { res = wait_dexopt(pid, apk_path); if (res != 0) { ALOGE("dexopt in='%s' out='%s' res=%d\n", apk_path, out_path, res); goto fail; } } ut.actime = apk_stat.st_atime; ut.modtime = apk_stat.st_mtime; utime(out_path, &ut); close(out_fd); close(zip_fd); return 0; fail: if (out_fd >= 0) { close(out_fd); unlink(out_path); } if (zip_fd >= 0) { close(zip_fd); } return -1; }
int main(int ac, char **av) { struct stat stat_buf; /* struct buffer to hold file info. */ int lc; long type; const char *msg; time_t modf_time, access_time; time_t pres_time; /* file modification/access/present time */ pid_t pid; msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); switch ((type = tst_fs_type(cleanup, "."))) { case TST_NFS_MAGIC: case TST_V9FS_MAGIC: tst_brkm(TCONF, cleanup, "Cannot do utime on a file on %s filesystem", tst_fs_type_name(type)); break; } /* set the expected errnos... */ TEST_EXP_ENOS(exp_enos); pid = FORK_OR_VFORK(); if (pid == -1) { tst_brkm(TBROK, cleanup, "fork() failed"); } else if (pid == 0) { if ((ltpuser = getpwnam(LTPUSER1)) == NULL) { tst_brkm(TBROK, cleanup, "%s not found in /etc/passwd", LTPUSER1); } /* get uid/gid of user accordingly */ user_uid = ltpuser->pw_uid; seteuid(user_uid); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; /* * Invoke utime(2) to set TEMP_FILE access and * modification times to the current time. */ TEST(utime(TEMP_FILE, NULL)); if (TEST_RETURN == -1) { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TFAIL, "utime(%s) Failed, errno=%d : %s", TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO)); } else { /* * Sleep for a second so that mod time * and access times will be different * from the current time. */ sleep(2); /* * Get the current time now, after * calling utime(2) */ if ((pres_time = time(&tloc)) < 0) { tst_brkm(TFAIL, cleanup, "time() failed to get " "present time after " "utime, error=%d", errno); } /* * Get the modification and access * times of temporary file using * stat(2). */ if (stat(TEMP_FILE, &stat_buf) < 0) { tst_brkm(TFAIL, cleanup, "stat(2) of %s failed, " "error:%d", TEMP_FILE, TEST_ERRNO); } modf_time = stat_buf.st_mtime; access_time = stat_buf.st_atime; /* Now do the actual verification */ if (modf_time <= curr_time || modf_time >= pres_time || access_time <= curr_time || access_time >= pres_time) { tst_resm(TFAIL, "%s access and " "modification times " "not set", TEMP_FILE); } else { tst_resm(TPASS, "Functionality " "of utime(%s, NULL) " "successful", TEMP_FILE); } } tst_count++; /* incr. TEST_LOOP counter */ } } else { waitpid(pid, &status, 0); _exit(0); /* * Exit here and let the child clean up. * This allows the errno information set * by the TEST_ERROR_LOG macro and the * PASS/FAIL status to be preserved for * use during cleanup. */ } cleanup(); tst_exit(); }
int main(int argc, char **argv) { int lock_retries = 10; int lock_interval = 3; int lock_fcntl_timeout = 0; int lock_flock_timeout = 0; int i, j, len; int fd = -1; int hd = -1; int md = -1; int yield = 0; int now = time(NULL); BOOL use_lockfile = FALSE; BOOL use_fcntl = FALSE; BOOL use_flock = FALSE; BOOL use_mbx = FALSE; BOOL verbose = FALSE; BOOL quiet = FALSE; BOOL restore_times = FALSE; char *filename; char *lockname = NULL, *hitchname = NULL; char *primary_hostname; const char *command; struct utsname s; char buffer[256]; char tempname[256]; /* Decode options */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (*arg != '-') break; if (strcmp(arg, "-fcntl") == 0) use_fcntl = TRUE; else if (strcmp(arg, "-flock") == 0) use_flock = TRUE; else if (strcmp(arg, "-lockfile") == 0) use_lockfile = TRUE; else if (strcmp(arg, "-mbx") == 0) use_mbx = TRUE; else if (strcmp(arg, "-v") == 0) verbose = TRUE; else if (strcmp(arg, "-q") == 0) quiet = TRUE; else if (strcmp(arg, "-restore-times") == 0) restore_times = TRUE; else if (++i < argc) { int value = atoi(argv[i]); if (strcmp(arg, "-retries") == 0) lock_retries = value; else if (strcmp(arg, "-interval") == 0) lock_interval = value; else if (strcmp(arg, "-timeout") == 0) lock_fcntl_timeout = lock_flock_timeout = value; else usage(); } else usage(); } if (quiet) verbose = 0; /* Can't use flock() if the OS doesn't provide it */ #ifdef NO_FLOCK if (use_flock) { printf("exim_lock: can't use flock() because it was not available in the\n" " operating system when exim_lock was compiled\n"); exit(1); } #endif /* Default is to use lockfiles and fcntl(). */ if (!use_lockfile && !use_fcntl && !use_flock && !use_mbx) use_lockfile = use_fcntl = TRUE; /* Default fcntl() for use with mbx */ if (use_mbx && !use_fcntl && !use_flock) use_fcntl = TRUE; /* Unset unused timeouts */ if (!use_fcntl) lock_fcntl_timeout = 0; if (!use_flock) lock_flock_timeout = 0; /* A file name is required */ if (i >= argc) usage(); filename = argv[i++]; /* Expand file names starting with ~ */ if (*filename == '~') { struct passwd *pw; if (*(++filename) == '/') pw = getpwuid(getuid()); else { char *s = buffer; while (*filename != 0 && *filename != '/') *s++ = *filename++; *s = 0; pw = getpwnam(buffer); } if (pw == NULL) { printf("exim_lock: unable to expand file name %s\n", argv[i-1]); exit(1); } if ((int)strlen(pw->pw_dir) + (int)strlen(filename) + 1 > sizeof(buffer)) { printf("exim_lock: expanded file name %s%s is too long", pw->pw_dir, filename); exit(1); } strcpy(buffer, pw->pw_dir); strcat(buffer, filename); filename = buffer; } /* If using a lock file, prepare by creating the lock file name and the hitching post name. */ if (use_lockfile) { if (uname(&s) < 0) { printf("exim_lock: failed to find host name using uname()\n"); exit(1); } primary_hostname = s.nodename; len = (int)strlen(filename); lockname = malloc(len + 8); sprintf(lockname, "%s.lock", filename); hitchname = malloc(len + 32 + (int)strlen(primary_hostname)); sprintf(hitchname, "%s.%s.%08x.%08x", lockname, primary_hostname, now, (int)getpid()); if (verbose) printf("exim_lock: lockname = %s\n hitchname = %s\n", lockname, hitchname); } /* Locking retry loop */ for (j = 0; j < lock_retries; j++) { int sleep_before_retry = TRUE; struct stat statbuf, ostatbuf, lstatbuf, statbuf2; int mbx_tmp_oflags; /* Try to build a lock file if so configured */ if (use_lockfile) { int rc; if (verbose) printf("exim_lock: creating lock file\n"); hd = open(hitchname, O_WRONLY | O_CREAT | O_EXCL, 0440); if (hd < 0) { printf("exim_lock: failed to create hitching post %s: %s\n", hitchname, strerror(errno)); exit(1); } /* Apply hitching post algorithm. */ if ((rc = link(hitchname, lockname)) != 0) fstat(hd, &statbuf); (void)close(hd); unlink(hitchname); if (rc != 0 && statbuf.st_nlink != 2) { printf("exim_lock: failed to link hitching post to lock file\n"); hd = -1; goto RETRY; } if (!quiet) printf("exim_lock: lock file successfully created\n"); } /* We are done if no other locking required. */ if (!use_fcntl && !use_flock && !use_mbx) break; /* Open the file for writing. */ fd = open(filename, O_RDWR + O_APPEND); if (fd < 0) { printf("exim_lock: failed to open %s for writing: %s\n", filename, strerror(errno)); yield = 1; goto CLEAN_UP; } /* If there is a timeout, implying blocked locking, we don't want to sleep before any retries after this. */ if (lock_fcntl_timeout > 0 || lock_flock_timeout > 0) sleep_before_retry = FALSE; /* Lock using fcntl. There are pros and cons to using a blocking call vs a non-blocking call and retries. Exim is non-blocking by default, but setting a timeout changes it to blocking. */ if (!use_mbx && (use_fcntl || use_flock)) { if (apply_lock(fd, F_WRLCK, use_fcntl, lock_fcntl_timeout, use_flock, lock_flock_timeout) >= 0) { if (!quiet) { if (use_fcntl) printf("exim_lock: fcntl() lock successfully applied\n"); if (use_flock) printf("exim_lock: flock() lock successfully applied\n"); } break; } else goto RETRY; /* Message already output */ } /* Lock using MBX rules. This is complicated and is documented with the source of the c-client library that goes with Pine and IMAP. What has to be done to interwork correctly is to take out a shared lock on the mailbox, and an exclusive lock on a /tmp file. */ else { if (apply_lock(fd, F_RDLCK, use_fcntl, lock_fcntl_timeout, use_flock, lock_flock_timeout) >= 0) { if (!quiet) { if (use_fcntl) printf("exim_lock: fcntl() read lock successfully applied\n"); if (use_flock) printf("exim_lock: fcntl() read lock successfully applied\n"); } } else goto RETRY; /* Message already output */ if (fstat(fd, &statbuf) < 0) { printf("exim_lock: fstat() of %s failed: %s\n", filename, strerror(errno)); yield = 1; goto CLEAN_UP; } /* Set up file in /tmp and check its state if already existing. */ sprintf(tempname, "/tmp/.%lx.%lx", (long)statbuf.st_dev, (long)statbuf.st_ino); if (lstat(tempname, &statbuf) >= 0) { if ((statbuf.st_mode & S_IFMT) == S_IFLNK) { printf("exim_lock: symbolic link on lock name %s\n", tempname); yield = 1; goto CLEAN_UP; } if (statbuf.st_nlink > 1) { printf("exim_lock: hard link to lock name %s\n", tempname); yield = 1; goto CLEAN_UP; } } mbx_tmp_oflags = O_RDWR | O_CREAT; #ifdef O_NOFOLLOW mbx_tmp_oflags |= O_NOFOLLOW; #endif md = open(tempname, mbx_tmp_oflags, 0600); if (md < 0) { printf("exim_lock: failed to create mbx lock file %s: %s\n", tempname, strerror(errno)); goto CLEAN_UP; } /* security fixes from 2010-05 */ if (lstat(tempname, &lstatbuf) < 0) { printf("exim_lock: failed to lstat(%s) after opening it: %s\n", tempname, strerror(errno)); goto CLEAN_UP; } if (fstat(md, &statbuf2) < 0) { printf("exim_lock: failed to fstat() open fd of \"%s\": %s\n", tempname, strerror(errno)); goto CLEAN_UP; } if ((statbuf2.st_nlink > 1) || (lstatbuf.st_nlink > 1) || (!S_ISREG(lstatbuf.st_mode)) || (lstatbuf.st_dev != statbuf2.st_dev) || (lstatbuf.st_ino != statbuf2.st_ino)) { printf("exim_lock: race condition exploited against us when " "locking \"%s\"\n", tempname); goto CLEAN_UP; } (void)chmod(tempname, 0600); if (apply_lock(md, F_WRLCK, use_fcntl, lock_fcntl_timeout, use_flock, lock_flock_timeout) >= 0) { if (!quiet) { if (use_fcntl) printf("exim_lock: fcntl() lock successfully applied to mbx " "lock file %s\n", tempname); if (use_flock) printf("exim_lock: flock() lock successfully applied to mbx " "lock file %s\n", tempname); } /* This test checks for a race condition */ if (lstat(tempname, &statbuf) != 0 || fstat(md, &ostatbuf) != 0 || statbuf.st_dev != ostatbuf.st_dev || statbuf.st_ino != ostatbuf.st_ino) { if (!quiet) printf("exim_lock: mbx lock file %s changed between " "creation and locking\n", tempname); goto RETRY; } else break; } else goto RETRY; /* Message already output */ } /* Clean up before retrying */ RETRY: if (md >= 0) { if (close(md) < 0) printf("exim_lock: close %s failed: %s\n", tempname, strerror(errno)); else if (!quiet) printf("exim_lock: %s closed\n", tempname); md = -1; } if (fd >= 0) { if (close(fd) < 0) printf("exim_lock: close failed: %s\n", strerror(errno)); else if (!quiet) printf("exim_lock: file closed\n"); fd = -1; } if (hd >= 0) { if (unlink(lockname) < 0) printf("exim_lock: unlink of %s failed: %s\n", lockname, strerror(errno)); else if (!quiet) printf("exim_lock: lock file removed\n"); hd = -1; } /* If a blocking call timed out, break the retry loop if the total time so far is not less than than retries * interval. */ if (sigalrm_seen && (j + 1) * ((lock_fcntl_timeout > lock_flock_timeout)? lock_fcntl_timeout : lock_flock_timeout) >= lock_retries * lock_interval) j = lock_retries; /* Wait a bit before retrying, except when it was a blocked fcntl() that caused the problem. */ if (j < lock_retries && sleep_before_retry) { printf(" ... waiting\n"); sleep(lock_interval); } } if (j >= lock_retries) { printf("exim_lock: locking failed too many times\n"); yield = 1; goto CLEAN_UP; } if (!quiet) printf("exim_lock: locking %s succeeded: ", filename); /* If there are no further arguments, run the user's shell; otherwise the next argument is a command to run. */ if (i >= argc) { command = getenv("SHELL"); if (command == NULL || *command == 0) command = "/bin/sh"; if (!quiet) printf("running %s ...\n", command); } else { command = argv[i]; if (!quiet) printf("running the command ...\n"); } /* Run the command, saving and restoring the times if required. */ if (restore_times) { struct stat strestore; struct utimbuf ut; stat(filename, &strestore); (void)system(command); ut.actime = strestore.st_atime; ut.modtime = strestore.st_mtime; utime(filename, &ut); } else (void)system(command); /* Remove the locks and exit. Unlink the /tmp file if we can get an exclusive lock on the mailbox. This should be a non-blocking lock call, as there is no point in waiting. */ CLEAN_UP: if (md >= 0) { if (apply_lock(fd, F_WRLCK, use_fcntl, 0, use_flock, 0) >= 0) { if (!quiet) printf("exim_lock: %s unlinked - no sharers\n", tempname); unlink(tempname); } else if (!quiet) printf("exim_lock: %s not unlinked - unable to get exclusive mailbox lock\n", tempname); if (close(md) < 0) printf("exim_lock: close %s failed: %s\n", tempname, strerror(errno)); else if (!quiet) printf("exim_lock: %s closed\n", tempname); } if (fd >= 0) { if (close(fd) < 0) printf("exim_lock: close %s failed: %s\n", filename, strerror(errno)); else if (!quiet) printf("exim_lock: %s closed\n", filename); } if (hd >= 0) { if (unlink(lockname) < 0) printf("exim_lock: unlink %s failed: %s\n", lockname, strerror(errno)); else if (!quiet) printf("exim_lock: lock file removed\n"); } return yield; }
int move_file(struct flist * file, off_t wsize) { char *from, *to, *buf; off_t size; FILE *input, *output; int ret, dir_id; struct utimbuf ftime = {0}; struct statvfs svf; fsblkcnt_t space; struct stat st; mhdd_debug(MHDD_MSG, "move_file: %s\n", file->real_name); /* TODO: it would be nice to contrive something alter */ flist_wrlock_locked(); from=file->real_name; /* We need to check if already moved */ if (statvfs(from, &svf) != 0) return -errno; space = svf.f_bsize; space *= svf.f_bavail; /* get file size */ if (fstat(file->fh, &st) != 0) { mhdd_debug(MHDD_MSG, "move_file: error stat %s: %s\n", from, strerror(errno)); return -errno; } /* Hard link support is limited to a single device, and files with >1 hardlinks cannot be moved between devices since this would (a) result in partial files on the source device (b) not free the space from the source device during unlink. */ if (st.st_nlink > 1) { mhdd_debug(MHDD_MSG, "move_file: cannot move " "files with >1 hardlinks\n"); return -ENOTSUP; } size = st.st_size; if (size < wsize) size=wsize; if (space > size) { mhdd_debug(MHDD_MSG, "move_file: we have enough space\n"); return 0; } if ((dir_id=find_free_space(size)) == -1) { mhdd_debug(MHDD_MSG, "move_file: can not find space\n"); return -1; } if (!(input = fopen(from, "r"))) return -errno; create_parent_dirs(dir_id, file->name); to = create_path(mhdd.dirs[dir_id], file->name); if (!(output = fopen(to, "w+"))) { ret = -errno; mhdd_debug(MHDD_MSG, "move_file: error create %s: %s\n", to, strerror(errno)); free(to); fclose(input); return(ret); } mhdd_debug(MHDD_MSG, "move_file: move %s to %s\n", from, to); // move data buf=(char *)calloc(sizeof(char), MOVE_BLOCK_SIZE); while((size = fread(buf, sizeof(char), MOVE_BLOCK_SIZE, input))) { if (size != fwrite(buf, sizeof(char), size, output)) { mhdd_debug(MHDD_MSG, "move_file: error move data to %s: %s\n", to, strerror(errno)); fclose(output); fclose(input); free(buf); unlink(to); free(to); return -1; } } free(buf); mhdd_debug(MHDD_MSG, "move_file: done move data\n"); fclose(input); // owner/group/permissions fchmod(fileno(output), st.st_mode); fchown(fileno(output), st.st_uid, st.st_gid); fclose(output); // time ftime.actime = st.st_atime; ftime.modtime = st.st_mtime; utime(to, &ftime); #ifndef WITHOUT_XATTR // extended attributes if (copy_xattrs(from, to) == -1) mhdd_debug(MHDD_MSG, "copy_xattrs: error copying xattrs from %s to %s\n", from, to); #endif from = strdup(from); if ((ret = reopen_files(file, to)) == 0) unlink(from); else unlink(to); mhdd_debug(MHDD_MSG, "move_file: %s -> %s: done, code=%d\n", from, to, ret); free(to); free(from); return ret; }
int sim_make_ROM_include(const char *rom_filename, int expected_size, int expected_checksum, const char *include_filename, const char *rom_array_name) { FILE *rFile; FILE *iFile; time_t now; int bytes_written = 0; int c; struct stat statb; unsigned char *ROMData = NULL; unsigned int checksum = 0; if (NULL == (rFile = fopen (rom_filename, "rb"))) { printf ("Error Opening '%s' for input: %s\n", rom_filename, strerror(errno)); return -1; } if (stat (rom_filename, &statb)) { printf ("Error stating '%s': %s\n", rom_filename, strerror(errno)); fclose (rFile); return -1; } if (statb.st_size != expected_size) { printf ("Error: ROM file '%s' has an unexpected size: %d vs %d\n", rom_filename, (int)statb.st_size, expected_size); printf ("This can happen if the file was transferred or unpacked incorrectly\n"); printf ("and in the process tried to convert line endings rather than passing\n"); printf ("the file's contents unmodified\n"); fclose (rFile); return -1; } ROMData = malloc (statb.st_size); if (statb.st_size != fread (ROMData, sizeof(*ROMData), statb.st_size, rFile)) { printf ("Error reading '%s': %s\n", rom_filename, strerror(errno)); fclose (rFile); free (ROMData); return -1; } fclose (rFile); for (c=0; c<statb.st_size; ++c) checksum += ROMData[c]; checksum = ~checksum; if ((expected_checksum != 0) && (checksum != expected_checksum)) { printf ("Error: ROM file '%s' has an unexpected checksum: 0x%08X vs 0x%08X\n", rom_filename, checksum, expected_checksum); printf ("This can happen if the file was transferred or unpacked incorrectly\n"); printf ("and in the process tried to convert line endings rather than passing\n"); printf ("the file's contents unmodified\n"); fclose (rFile); return -1; } /* * If the target include file already exists, determine if it contains the exact * data in the base ROM image. If so, then we are already done */ if (iFile = fopen (include_filename, "r")) { unsigned char *IncludeData = NULL; char line[256]; int Difference = 0; IncludeData = malloc (statb.st_size); while (fgets (line, sizeof(line), iFile)) { int byte; char *c; if (memcmp ("0x",line,2)) continue; c = line; while (1 == sscanf (c, "0x%2Xd,", &byte)) { if (bytes_written >= statb.st_size) Difference = 1; else IncludeData[bytes_written++] = byte; c += 5; } if ((strchr (line,'}')) || Difference) break; } fclose (iFile); if (!Difference) Difference = memcmp (IncludeData, ROMData, statb.st_size); free (IncludeData); if (!Difference) { free (ROMData); return 0; } } if (NULL == (iFile = fopen (include_filename, "w"))) { printf ("Error Opening '%s' for output: %s\n", include_filename, strerror(errno)); return -1; } time (&now); fprintf (iFile, "#ifndef ROM_%s_H\n", rom_array_name); fprintf (iFile, "#define ROM_%s_H 0\n", rom_array_name); fprintf (iFile, "/*\n"); fprintf (iFile, " %s produced at %s", include_filename, ctime(&now)); fprintf (iFile, " from %s which was last modified at %s", rom_filename, ctime(&statb.st_mtime)); fprintf (iFile, " file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum); fprintf (iFile, "*/\n"); fprintf (iFile, "unsigned char %s[] = {", rom_array_name); for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) { c = ROMData[bytes_written]; if (0 == bytes_written%16) fprintf (iFile,"\n"); fprintf (iFile,"0x%02X,", c&0xFF); } free (ROMData); fprintf (iFile,"};\n"); fprintf (iFile, "#endif /* ROM_%s_H */\n", rom_array_name); fclose (iFile); if (1) { /* Set Modification Time on the include file to be the modification time of the ROM file */ struct utimbuf times; times.modtime = statb.st_mtime; times.actime = statb.st_atime; utime (include_filename, ×); } return 0; }
/* Parse the input file and update the global symbol table and macro table, * output the stripped file contents to devices if OUTFILE is not nil. * * Returns a pointer to the error messages on failure, or nil on success. */ bool Parser::DoFile(InternalTables *intab, size_t num_preprocessors, File *infile, ParserContext *ctx) { bool ignored; FILE *out_fp; bool retval = false; CC_STRING bak_fname, out_fname; struct stat stb; struct utimbuf utb; if(ctx) { ignored = ctx->check_ignore(infile->name); if( ignored && ! has_dep_file() ) return true; } else ignored = false; if( stat(infile->name, &stb) == 0 ) { utb.actime = stb.st_atime; utb.modtime = stb.st_mtime; } if( ! infile->Open() ) { errmsg.Format("Cannot open \"%s\" for reading\n"); return false; } out_fp = NULL; if(ctx != NULL && ctx->outfile != ParserContext::OF_NULL ) { if( ctx->outfile == ParserContext::OF_STDOUT ) out_fp = stdout; else { #if SANITY_CHECK assert( ! ctx->baksuffix.isnull() ); #endif if( ctx->baksuffix[0] != ParserContext::MAGIC_CHAR ) bak_fname = infile->name + ctx->baksuffix; else out_fname = infile->name; int fd; char tmp_outfile[32]; strcpy(tmp_outfile, "@cl@-XXXXXX"); fd = mkstemp(tmp_outfile); if( fd < 0 ) { errmsg.Format("Cannot open \"%s\" for writing\n", tmp_outfile); infile->Close(); return false; } out_fp = fdopen(fd, "wb"); out_fname = tmp_outfile; } } if(ctx == NULL) memset(writers, 0, sizeof(writers)); else { writers[VCH_CL] = NULL; if(!ctx->of_array[VCH_DEP].isnull()) writers[VCH_DEP] = gvar_file_writers[VCH_DEP]; if(!ctx->of_array[VCH_CV].isnull()) writers[VCH_CV] = gvar_file_writers[VCH_CV]; } if( num_preprocessors >= COUNT_OF(Parser::preprocessors) ) num_preprocessors = COUNT_OF(Parser::preprocessors); Reset(intab, num_preprocessors, ctx); if(has_dep_file()) AddDependency("", infile->name); PushIncludedFile(infile, out_fp, COUNT_OF(Parser::preprocessors), false, conditionals.size()); if(ctx != NULL) { GetCmdLineIncludeFiles(ctx->imacro_files, 2); GetCmdLineIncludeFiles(ctx->include_files, COUNT_OF(preprocessors)); } if( ! RunEngine(0) ) goto error; SaveDepInfo(deptext); if( conditionals.size() != 0 ) errmsg = "Unmatched #if"; else retval = true; error: if(!retval) { if(included_files.size() > 0) { CC_STRING tmp; tmp.Format("%s:%u: %s\n%s\n", GetCurrentFileName().c_str(), GetCurrentLineNumber(), pline.from.c_str(), GetError()); errmsg = tmp; } #if 0 IncludedFile *ilevel; while(included_files.size() > 0) { ilevel = PopIncludedFile(); if(infile != ilevel->ifile) delete ilevel; } #endif } if(out_fp != NULL && out_fp != stdout) fclose(out_fp); if( retval && ctx != NULL && ! ignored ) { CC_STRING semname; sem_t *sem; semname = MakeSemaName(infile->name); sem = sem_open(semname.c_str(), O_CREAT, 0666, 1); sem_wait(sem); if( ! bak_fname.isnull() ) rename(infile->name, bak_fname); if( ! out_fname.isnull() ) { rename(out_fname, infile->name); utime(infile->name.c_str(), &utb); } sem_post(sem); sem_unlink(semname.c_str()); } else if( ! out_fname.isnull() ) unlink(out_fname.c_str()); return retval; }
void do_one_file(const char *iname, char *oname) { int r; struct stat st; memset(&st, 0, sizeof(st)); #if (HAVE_LSTAT) r = lstat(iname, &st); #else r = stat(iname, &st); #endif if (r != 0) { if (errno == ENOENT) throw FileNotFoundException(iname, errno); else throwIOException(iname, errno); } if (!(S_ISREG(st.st_mode))) throwIOException("not a regular file -- skipped"); #if defined(__unix__) // no special bits may be set if ((st.st_mode & (S_ISUID | S_ISGID | S_ISVTX)) != 0) throwIOException("file has special permissions -- skipped"); #endif if (st.st_size <= 0) throwIOException("empty file -- skipped"); if (st.st_size < 512) throwIOException("file is too small -- skipped"); if (!mem_size_valid_bytes(st.st_size)) throwIOException("file is too large -- skipped"); if ((st.st_mode & S_IWUSR) == 0) { bool skip = true; if (opt->output_name) skip = false; else if (opt->to_stdout) skip = false; else if (opt->backup) skip = false; if (skip) throwIOException("file is write protected -- skipped"); } InputFile fi; fi.st = st; fi.sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR); #if (USE_FTIME) struct ftime fi_ftime; memset(&fi_ftime, 0, sizeof(fi_ftime)); if (opt->preserve_timestamp) { if (getftime(fi.getFd(), &fi_ftime) != 0) throwIOException("cannot determine file timestamp"); } #endif // open output file OutputFile fo; if (opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS) { if (opt->to_stdout) { if (!fo.openStdout(1, opt->force ? true : false)) throwIOException("data not written to a terminal; Use '-f' to force."); } else { char tname[ACC_FN_PATH_MAX+1]; if (opt->output_name) strcpy(tname,opt->output_name); else { if (!maketempname(tname, sizeof(tname), iname, ".upx")) throwIOException("could not create a temporary file name"); } if (opt->force >= 2) { #if (HAVE_CHMOD) r = chmod(tname, 0777); IGNORE_ERROR(r); #endif r = unlink(tname); IGNORE_ERROR(r); } int flags = O_CREAT | O_WRONLY | O_BINARY; if (opt->force) flags |= O_TRUNC; else flags |= O_EXCL; int shmode = SH_DENYWR; #if defined(__MINT__) flags |= O_TRUNC; shmode = O_DENYRW; #endif // cannot rely on open() because of umask //int omode = st.st_mode | 0600; int omode = 0600; if (!opt->preserve_mode) omode = 0666; fo.sopen(tname,flags,shmode,omode); // open succeeded - now set oname[] strcpy(oname,tname); } } // handle command PackMaster pm(&fi, opt); if (opt->cmd == CMD_COMPRESS) pm.pack(&fo); else if (opt->cmd == CMD_DECOMPRESS) pm.unpack(&fo); else if (opt->cmd == CMD_TEST) pm.test(); else if (opt->cmd == CMD_LIST) pm.list(); else if (opt->cmd == CMD_FILEINFO) pm.fileInfo(); else throwInternalError("invalid command"); // copy time stamp if (opt->preserve_timestamp && oname[0] && fo.isOpen()) { #if (USE_FTIME) r = setftime(fo.getFd(), &fi_ftime); IGNORE_ERROR(r); #elif (USE__FUTIME) struct _utimbuf u; u.actime = st.st_atime; u.modtime = st.st_mtime; r = _futime(fo.getFd(), &u); IGNORE_ERROR(r); #endif } // close files fo.closex(); fi.closex(); // rename or delete files if (oname[0] && !opt->output_name) { // FIXME: .exe or .cof etc. if (!opt->backup) { #if (HAVE_CHMOD) r = chmod(iname, 0777); IGNORE_ERROR(r); #endif File::unlink(iname); } else { // make backup char bakname[ACC_FN_PATH_MAX+1]; if (!makebakname(bakname, sizeof(bakname), iname)) throwIOException("could not create a backup file name"); File::rename(iname,bakname); } File::rename(oname,iname); } // copy file attributes if (oname[0]) { oname[0] = 0; const char *name = opt->output_name ? opt->output_name : iname; UNUSED(name); #if (USE_UTIME) // copy time stamp if (opt->preserve_timestamp) { struct utimbuf u; u.actime = st.st_atime; u.modtime = st.st_mtime; r = utime(name, &u); IGNORE_ERROR(r); } #endif #if (HAVE_CHMOD) // copy permissions if (opt->preserve_mode) { r = chmod(name, st.st_mode); IGNORE_ERROR(r); } #endif #if (HAVE_CHOWN) // copy the ownership if (opt->preserve_ownership) { r = chown(name, st.st_uid, st.st_gid); IGNORE_ERROR(r); } #endif } UiPacker::uiConfirmUpdate(); }
void test_file(void) { int fd, i, len, ret; uint8_t buf[FILE_BUF_SIZE]; uint8_t buf2[FILE_BUF_SIZE]; uint8_t buf3[FILE_BUF_SIZE]; char cur_dir[1024]; struct stat st; struct utimbuf tbuf; struct iovec vecs[2]; DIR *dir; struct dirent *de; /* clean up, just in case */ unlink(TESTPATH "/file1"); unlink(TESTPATH "/file2"); unlink(TESTPATH "/file3"); rmdir(TESTPATH); if (getcwd(cur_dir, sizeof(cur_dir)) == NULL) error("getcwd"); chk_error(mkdir(TESTPATH, 0755)); chk_error(chdir(TESTPATH)); /* open/read/write/close/readv/writev/lseek */ fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644)); for(i=0; i < FILE_BUF_SIZE; i++) buf[i] = i; len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2)); if (len != (FILE_BUF_SIZE / 2)) error("write"); vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2); vecs[0].iov_len = 16; vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16; vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16; len = chk_error(writev(fd, vecs, 2)); if (len != (FILE_BUF_SIZE / 2)) error("writev"); chk_error(close(fd)); chk_error(rename("file1", "file2")); fd = chk_error(open("file2", O_RDONLY)); len = chk_error(read(fd, buf2, FILE_BUF_SIZE)); if (len != FILE_BUF_SIZE) error("read"); if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0) error("memcmp"); #define FOFFSET 16 ret = chk_error(lseek(fd, FOFFSET, SEEK_SET)); if (ret != 16) error("lseek"); vecs[0].iov_base = buf3; vecs[0].iov_len = 32; vecs[1].iov_base = buf3 + 32; vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32; len = chk_error(readv(fd, vecs, 2)); if (len != FILE_BUF_SIZE - FOFFSET) error("readv"); if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0) error("memcmp"); chk_error(close(fd)); /* access */ chk_error(access("file2", R_OK)); /* stat/chmod/utime/truncate */ chk_error(chmod("file2", 0600)); tbuf.actime = 1001; tbuf.modtime = 1000; chk_error(truncate("file2", 100)); chk_error(utime("file2", &tbuf)); chk_error(stat("file2", &st)); if (st.st_size != 100) error("stat size"); if (!S_ISREG(st.st_mode)) error("stat mode"); if ((st.st_mode & 0777) != 0600) error("stat mode2"); if (st.st_atime != 1001 || st.st_mtime != 1000) error("stat time"); chk_error(stat(TESTPATH, &st)); if (!S_ISDIR(st.st_mode)) error("stat mode"); /* fstat */ fd = chk_error(open("file2", O_RDWR)); chk_error(ftruncate(fd, 50)); chk_error(fstat(fd, &st)); chk_error(close(fd)); if (st.st_size != 50) error("stat size"); if (!S_ISREG(st.st_mode)) error("stat mode"); /* symlink/lstat */ chk_error(symlink("file2", "file3")); chk_error(lstat("file3", &st)); if (!S_ISLNK(st.st_mode)) error("stat mode"); /* getdents */ dir = opendir(TESTPATH); if (!dir) error("opendir"); len = 0; for(;;) { de = readdir(dir); if (!de) break; if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0 && strcmp(de->d_name, "file2") != 0 && strcmp(de->d_name, "file3") != 0) error("readdir"); len++; } closedir(dir); if (len != 4) error("readdir"); chk_error(unlink("file3")); chk_error(unlink("file2")); chk_error(chdir(cur_dir)); chk_error(rmdir(TESTPATH)); }
int copy_file(const char *source, const char *dest, int flags) { struct stat source_stat; struct stat dest_stat; int dest_exists = 0; int status = 0; if ((!(flags & FILEUTILS_DEREFERENCE) && lstat(source, &source_stat) < 0) || ((flags & FILEUTILS_DEREFERENCE) && stat(source, &source_stat) < 0)) { bb_perror_msg("%s", source); return -1; } if (lstat(dest, &dest_stat) < 0) { if (errno != ENOENT) { bb_perror_msg("unable to stat `%s'", dest); return -1; } } else { if (source_stat.st_dev == dest_stat.st_dev && source_stat.st_ino == dest_stat.st_ino) { bb_error_msg("`%s' and `%s' are the same file", source, dest); return -1; } dest_exists = 1; } if (S_ISDIR(source_stat.st_mode)) { DIR *dp; struct dirent *d; mode_t saved_umask = 0; if (!(flags & FILEUTILS_RECUR)) { bb_error_msg("%s: omitting directory", source); return -1; } /* Create DEST. */ if (dest_exists) { if (!S_ISDIR(dest_stat.st_mode)) { bb_error_msg("`%s' is not a directory", dest); return -1; } } else { mode_t mode; saved_umask = umask(0); mode = source_stat.st_mode; if (!(flags & FILEUTILS_PRESERVE_STATUS)) mode = source_stat.st_mode & ~saved_umask; mode |= S_IRWXU; if (mkdir(dest, mode) < 0) { umask(saved_umask); bb_perror_msg("cannot create directory `%s'", dest); return -1; } umask(saved_umask); } /* Recursively copy files in SOURCE. */ if ((dp = bb_opendir(source)) == NULL) { status = -1; goto preserve_status; } while ((d = readdir(dp)) != NULL) { char *new_source, *new_dest; new_source = concat_subpath_file(source, d->d_name); if(new_source == NULL) continue; new_dest = concat_path_file(dest, d->d_name); if (copy_file(new_source, new_dest, flags) < 0) status = -1; free(new_source); free(new_dest); } /* closedir have only EBADF error, but "dp" not changes */ closedir(dp); if (!dest_exists && chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { bb_perror_msg("unable to change permissions of `%s'", dest); status = -1; } } else if (S_ISREG(source_stat.st_mode) || (S_ISLNK(source_stat.st_mode) && (flags & FILEUTILS_DEREFERENCE))) { int src_fd; int dst_fd; if (ENABLE_FEATURE_PRESERVE_HARDLINKS) { char *link_name; if (!(flags & FILEUTILS_DEREFERENCE) && is_in_ino_dev_hashtable(&source_stat, &link_name)) { if (link(link_name, dest) < 0) { bb_perror_msg("unable to link `%s'", dest); return -1; } return 0; } add_to_ino_dev_hashtable(&source_stat, dest); } src_fd = open(source, O_RDONLY); if (src_fd == -1) { bb_perror_msg("unable to open `%s'", source); return(-1); } if (dest_exists) { if (flags & FILEUTILS_INTERACTIVE) { fprintf(stderr, "%s: overwrite `%s'? ", bb_applet_name, dest); if (!bb_ask_confirmation()) { close (src_fd); return 0; } } dst_fd = open(dest, O_WRONLY|O_TRUNC); if (dst_fd == -1) { if (!(flags & FILEUTILS_FORCE)) { bb_perror_msg("unable to open `%s'", dest); close(src_fd); return -1; } if (unlink(dest) < 0) { bb_perror_msg("unable to remove `%s'", dest); close(src_fd); return -1; } goto dest_removed; } } else { dest_removed: dst_fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode); if (dst_fd == -1) { bb_perror_msg("unable to open `%s'", dest); close(src_fd); return(-1); } } if (bb_copyfd_eof(src_fd, dst_fd) == -1) status = -1; if (close(dst_fd) < 0) { bb_perror_msg("unable to close `%s'", dest); status = -1; } if (close(src_fd) < 0) { bb_perror_msg("unable to close `%s'", source); status = -1; } } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || S_ISLNK(source_stat.st_mode)) { if (dest_exists) { if((flags & FILEUTILS_FORCE) == 0) { fprintf(stderr, "`%s' exists\n", dest); return -1; } if(unlink(dest) < 0) { bb_perror_msg("unable to remove `%s'", dest); return -1; } } if (S_ISFIFO(source_stat.st_mode)) { if (mkfifo(dest, source_stat.st_mode) < 0) { bb_perror_msg("cannot create fifo `%s'", dest); return -1; } } else if (S_ISLNK(source_stat.st_mode)) { char *lpath; lpath = xreadlink(source); if (symlink(lpath, dest) < 0) { bb_perror_msg("cannot create symlink `%s'", dest); return -1; } free(lpath); if (flags & FILEUTILS_PRESERVE_STATUS) if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) bb_perror_msg("unable to preserve ownership of `%s'", dest); return 0; } else { if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { bb_perror_msg("unable to create `%s'", dest); return -1; } } } else { bb_error_msg("internal error: unrecognized file type"); return -1; } preserve_status: if (flags & FILEUTILS_PRESERVE_STATUS) { struct utimbuf times; char *msg="unable to preserve %s of `%s'"; times.actime = source_stat.st_atime; times.modtime = source_stat.st_mtime; if (utime(dest, ×) < 0) bb_perror_msg(msg, "times", dest); if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { source_stat.st_mode &= ~(S_ISUID | S_ISGID); bb_perror_msg(msg, "ownership", dest); } if (chmod(dest, source_stat.st_mode) < 0) bb_perror_msg(msg, "permissions", dest); } return status; }
/* * Return values: * 0 - Success * 1 - Some error * 2 - Orphaned tic */ int ProcessTic(fa_list **sbl, orphans **opl) { int First, Listed = FALSE, DownLinks = 0, MustRearc = FALSE; int UnPacked = FALSE, IsArchive = FALSE, rc, i, j, k; char *Temp, *unarc = NULL, *cmd = NULL; char temp1[PATH_MAX], temp2[PATH_MAX], sbe[24], TDesc[1024]; unsigned int crc, crc2, Kb; sysconnect Link; FILE *fp; struct utimbuf ut; int BBS_Imp = FALSE, DidBanner = FALSE; faddr *p_from; qualify *qal = NULL, *tmpq; orphans *topl; if (TIC.TicIn.PathError) { WriteError("Our Aka is in the path"); tic_bad++; return 1; } Temp = calloc(PATH_MAX, sizeof(char)); if (!do_quiet) { mbse_colour(LIGHTGREEN, BLACK); printf("Checking \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } if (TIC.Orphaned) { fill_orphans(opl, TIC.TicName, TIC.TicIn.Area, TIC.TicIn.File, TRUE, FALSE); Syslog('+', "File not in inbound: %s", TIC.TicIn.File); free(Temp); return 2; } snprintf(Temp, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File); crc = file_crc(Temp, CFG.slow_util && do_quiet); TIC.FileSize = file_size(Temp); TIC.FileDate = file_time(Temp); if (TIC.TicIn.Size) { if (TIC.TicIn.Size != TIC.FileSize) WriteError("Size is %ld, expected %ld", TIC.FileSize, TIC.TicIn.Size); } else { /* * No filesize in TIC file, add filesize. */ TIC.TicIn.Size = TIC.FileSize; } if (TIC.Crc_Int) { if (crc != TIC.Crc_Int) { Syslog('!', "CRC: expected %08lX, the file is %08lX", TIC.Crc_Int, crc); fill_orphans(opl, TIC.TicName, TIC.TicIn.Area, TIC.TicIn.File, FALSE, TRUE); if (check_crc) { Syslog('+', "Bad CRC, will check this ticfile later"); free(Temp); return 1; } else { Syslog('!', "CRC: error, recalculating crc"); ReCalcCrc(Temp); } } } else { Syslog('+', "CRC: missing, calculating CRC"); ReCalcCrc(Temp); } /* * Load and check the .TIC area. */ if (!SearchTic(TIC.TicIn.Area)) { UpdateNode(); Syslog('f', "Unknown file area %s", TIC.TicIn.Area); p_from = fido2faddr(TIC.Aka); if (!create_ticarea(TIC.TicIn.Area, p_from)) { Bad((char *)"Unknown file area %s", TIC.TicIn.Area); free(Temp); tidy_faddr(p_from); return 1; } tidy_faddr(p_from); /* * Try to load the .TIC area again. */ if (!SearchTic(TIC.TicIn.Area)) { Bad((char *)"Reload of new created file area %s failed", TIC.TicIn.Area); free(Temp); return 1; } } if ((tic.Secure) && (!TIC.TicIn.Hatch)) { First = TRUE; while (GetTicSystem(&Link, First)) { First = FALSE; if (Link.aka.zone) { if ((Link.aka.zone == TIC.Aka.zone) && (Link.aka.net == TIC.Aka.net) && (Link.aka.node == TIC.Aka.node) && (Link.aka.point== TIC.Aka.point) && (Link.receivefrom)) Listed = TRUE; } } if (!Listed) { Bad((char *)"%s NOT connected to %s", aka2str(TIC.Aka), TIC.TicIn.Area); free(Temp); return 1; } } if ((!SearchNode(TIC.Aka)) && (!TIC.TicIn.Hatch)) { Bad((char *)"%s NOT known", aka2str(TIC.Aka)); free(Temp); return 1; } if (!TIC.TicIn.Hatch) { if (strcasecmp(TIC.TicIn.Pw, nodes.Fpasswd)) { Bad((char *)"Pwd error, got %s, expected %s", TIC.TicIn.Pw, nodes.Fpasswd); free(Temp); return 1; } } else { if (strcasecmp(TIC.TicIn.Pw, CFG.hatchpasswd)) { Bad((char *)"Password error in local Hatch"); WriteError("WARNING: it might be a Trojan in your inbound"); free(Temp); return 1; } } if (Magic_DeleteFile()) { snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicName); file_rm(temp1); Syslog('+', "Deleted file %s", temp1); file_rm(Temp); free(Temp); return 0; } if (Magic_MoveFile()) { if (!SearchTic(TIC.TicIn.Area)) { Bad((char *)"Unknown Area: %s", TIC.TicIn.Area); free(Temp); return 1; } } strncpy(T_File.Echo, tic.Name, 20); strncpy(T_File.Group, tic.Group, 12); TIC.KeepNum = tic.KeepLatest; Magic_Keepnum(); if (!tic.FileArea) { Syslog('+', "Passthru TIC area!"); strcpy(TIC.BBSpath, CFG.ticout); strcpy(TIC.BBSdesc, tic.Comment); } else { snprintf(Temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT")); if ((fp = fopen(Temp, "r")) == NULL) { WriteError("Can't access fareas.data area: %ld", tic.FileArea); free(Temp); return 1; } fread(&areahdr, sizeof(areahdr), 1, fp); if (fseek(fp, ((tic.FileArea -1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET)) { fclose(fp); WriteError("Can't seek area %ld in fareas.data", tic.FileArea); free(Temp); return 1; } if (fread(&area, areahdr.recsize, 1, fp) != 1) { fclose(fp); WriteError("Can't read area %ld in fareas.data", tic.FileArea); free(Temp); return 1; } fclose(fp); strcpy(TIC.BBSpath, area.Path); strcpy(TIC.BBSdesc, area.Name); /* * If the File area has a special announce group, change * the group to that name. */ if (strlen(area.NewGroup)) strncpy(T_File.Group, area.NewGroup, 12); } strncpy(T_File.Comment, tic.Comment, 55); /* * Check if the destination area really exists, it may be that * the area is not linked to an existing BBS area. */ if (tic.FileArea && access(TIC.BBSpath, W_OK)) { WriteError("No write access to \"%s\"", TIC.BBSpath); Bad((char *)"Dest directory not available"); free(Temp); return 1; } if ((tic.DupCheck) && (check_dupe)) { snprintf(Temp, PATH_MAX, "%s%s", TIC.TicIn.Area, TIC.TicIn.Crc); crc2 = 0xffffffff; crc2 = upd_crc32(Temp, crc2, strlen(Temp)); if (CheckDupe(crc2, D_FILEECHO, CFG.tic_dupes)) { Bad((char *)"Duplicate file"); tic_dup++; free(Temp); return 1; } } /* * Count the actual downlinks for this area and build the list of * systems qualified to receive this file. */ First = TRUE; while (GetTicSystem(&Link, First)) { First = FALSE; if ((Link.aka.zone) && (Link.sendto) && (!Link.pause)) { DownLinks++; p_from = fido2faddr(Link.aka); if (TIC.TicIn.Hatch) { fill_qualify(&qal, Link.aka, FALSE, in_list(p_from, sbl, TRUE)); } else { fill_qualify(&qal, Link.aka, ((TIC.Aka.zone == Link.aka.zone) && (TIC.Aka.net == Link.aka.net) && (TIC.Aka.node == Link.aka.node) && (TIC.Aka.point == Link.aka.point)), in_list(p_from, sbl, TRUE)); } tidy_faddr(p_from); } } T_File.Size = TIC.FileSize; T_File.SizeKb = TIC.FileSize / 1024; /* * Update the uplink's counters. */ Kb = TIC.FileSize / 1024; if (SearchNode(TIC.Aka)) { StatAdd(&nodes.FilesRcvd, 1L); StatAdd(&nodes.F_KbRcvd, Kb); UpdateNode(); SearchNode(TIC.Aka); } /* * Update the fileecho and group counters. */ StatAdd(&fgroup.Files, 1L); StatAdd(&fgroup.KBytes, Kb); fgroup.LastDate = time(NULL); StatAdd(&tic.Files, 1L); StatAdd(&tic.KBytes, Kb); tic.LastAction = time(NULL); UpdateTic(); if (!do_quiet) { printf("Unpacking \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } /* * Check if this is an archive, and if so, which compression method * is used for this file. */ if (strlen(tic.Convert) || tic.FileId || tic.ConvertAll || strlen(tic.Banner)) { /* * Create tmp workdir */ if (create_tmpwork()) { free(Temp); tidy_qualify(&qal); return 1; } if ((unarc = unpacker(TIC.TicIn.File)) == NULL) Syslog('+', "Unknown archive format %s", TIC.TicIn.File); else { IsArchive = TRUE; if ((strlen(tic.Convert) && (strcmp(unarc, tic.Convert) == 0)) || (tic.ConvertAll)) MustRearc = TRUE; } } /* * Copy the file if there are downlinks and we send the * original file, but want to rearc it for ourself, or if * it's a passthru area. */ if (((tic.SendOrg) && (MustRearc || strlen(tic.Banner))) || (!tic.FileArea)) { snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File); snprintf(temp2, PATH_MAX, "%s/%s", CFG.ticout, TIC.TicIn.File); if ((rc = file_cp(temp1, temp2) == 0)) { TIC.SendOrg = TRUE; } else { WriteError("Copy %s to %s failed: %s", temp1, temp2, strerror(rc)); } } if (MustRearc && IsArchive) { snprintf(temp2, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid()); if (!checkspace(temp2, TIC.TicIn.File, UNPACK_FACTOR)) { Bad((char *)"Not enough free diskspace left"); free(Temp); tidy_qualify(&qal); clean_tmpwork(); return 1; } if (chdir(temp2) != 0) { WriteError("$Can't change to %s", temp2); free(Temp); tidy_qualify(&qal); clean_tmpwork(); return 1; } if (!getarchiver(unarc)) { WriteError("Can't get archiver for %s", unarc); chdir(TIC.Inbound); free(Temp); tidy_qualify(&qal); clean_tmpwork(); return 1; } if (strlen(archiver.funarc) == 0) { Syslog('!', "No unarc command available"); } else { cmd = xstrcpy(archiver.funarc); snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File); if (execute_str(cmd, temp1, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) { UnPacked = TRUE; } else { chdir(TIC.Inbound); Bad((char *)"Archive maybe corrupt"); free(Temp); clean_tmpwork(); return 1; } free(cmd); } } /* * Scan file for viri. */ if (tic.VirScan) { snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File); if (!do_quiet) { printf("Virscan \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } if (VirScanFile(temp1)) { chdir(TIC.Inbound); Bad((char *)"Possible virus found!"); free(Temp); tidy_qualify(&qal); clean_tmpwork(); return 1; } if (!do_quiet) { printf("Checking \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } } if (tic.FileId && tic.FileArea && IsArchive) { if (UnPacked) { snprintf(temp1, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid()); snprintf(Temp, PATH_MAX, "FILE_ID.DIZ"); if (getfilecase(temp1, Temp)) { Syslog('f', "Found %s", Temp); snprintf(temp1, PATH_MAX, "%s/tmp/arc%d/%s", getenv("MBSE_ROOT"), (int)getpid(), Temp); snprintf(temp2, PATH_MAX, "%s/tmp/FILE_ID.DIZ", getenv("MBSE_ROOT")); } else { Syslog('f', "Didn't find a FILE_ID.DIZ"); } } else { if (!getarchiver(unarc)) { chdir(TIC.Inbound); } else { cmd = xstrcpy(archiver.iunarc); if (cmd == NULL) { WriteError("No unarc command available"); } else { snprintf(temp1, PATH_MAX, "%s/tmp", getenv("MBSE_ROOT")); chdir(temp1); snprintf(temp1, PATH_MAX, "%s/%s FILE_ID.DIZ", TIC.Inbound, TIC.TicIn.File); if (execute_str(cmd, temp1, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")) { snprintf(temp1, PATH_MAX, "%s/%s file_id.diz", TIC.Inbound, TIC.TicIn.File); execute_str(cmd, temp1, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null"); } free(cmd); } } /* if getarchiver */ } /* if not unpacked */ } /* if need FILE_ID.DIZ and not passthru */ /* * Create internal file description, priority is FILE_ID.DIZ, * 2nd LDesc, and finally the standard description. */ if (!Get_File_Id()) { if (TIC.TicIn.TotLDesc > 2) { for (i = 0; i < TIC.TicIn.TotLDesc; i++) { strncpy(TIC.File_Id[i], TIC.TicIn.LDesc[i], 48); } TIC.File_Id_Ct = TIC.TicIn.TotLDesc; } else { /* * Format the description line (max 255 chars) in parts of 48 characters. */ if (strlen(TIC.TicIn.Desc) <= 48) { strcpy(TIC.File_Id[0], TIC.TicIn.Desc); TIC.File_Id_Ct++; } else { memset(&TDesc, 0, sizeof(TDesc)); strcpy(TDesc, TIC.TicIn.Desc); while (strlen(TDesc) > 48) { j = 48; while ((TDesc[j] != ' ') && (j > 0)) j--; if (j == 0) { Syslog('f', "Panic, no spaces"); j = 47; } strncpy(TIC.File_Id[TIC.File_Id_Ct], TDesc, j); Syslog('f', "%2d/%2d: \"%s\"", TIC.File_Id_Ct, j, TIC.File_Id[TIC.File_Id_Ct]); TIC.File_Id_Ct++; k = strlen(TDesc); j++; /* Correct space */ for (i = 0; i <= k; i++, j++) TDesc[i] = TDesc[j]; if (TIC.File_Id_Ct == 23) break; } strncpy(TIC.File_Id[TIC.File_Id_Ct], TDesc, 48); Syslog('f', "%2d/%2d: \"%s\"", TIC.File_Id_Ct, strlen(TIC.File_Id[TIC.File_Id_Ct]), TIC.File_Id[TIC.File_Id_Ct]); TIC.File_Id_Ct++; } } } /* not get FILE_ID.DIZ */ /* * Now check if other (older) ticfiles point to this file, * if found mark it to purge later. */ for (topl = *opl; topl; topl = topl->next) { if ((strcmp(topl->Area, TIC.TicIn.Area) == 0) && (strcmp(topl->FileName, TIC.TicIn.File) == 0)) { topl->Purged = TRUE; } } /* * Rearc file if it is an unpacked archive. */ if ((MustRearc) && (UnPacked) && (tic.FileArea)) { if (Rearc(tic.Convert)) { /* * Get new filesize for import and announce */ snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile); TIC.FileSize = file_size(temp1); T_File.Size = TIC.FileSize; T_File.SizeKb = TIC.FileSize / 1024; /* * Calculate the CRC if we must send the new archived file. */ if (!TIC.SendOrg) { ReCalcCrc(temp1); } } else { WriteError("Rearc failed"); } /* if Rearc() */ } /* * Change banner if needed. */ if ((strlen(tic.Banner)) && IsArchive) { cmd = xstrcpy(archiver.barc); if ((cmd == NULL) || (!strlen(cmd))) { Syslog('+', "No banner command for %s", archiver.name); } else { snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile); snprintf(Temp, PATH_MAX, "%s/etc/%s", getenv("MBSE_ROOT"), tic.Banner); if (execute_str(cmd, temp1, (char *)NULL, Temp, (char *)"/dev/null", (char *)"/dev/null")) { WriteError("Changing the banner failed"); } else { Syslog('+', "New banner %s", tic.Banner); TIC.FileSize = file_size(temp1); T_File.Size = TIC.FileSize; T_File.SizeKb = TIC.FileSize / 1024; ReCalcCrc(temp1); DidBanner = TRUE; } } } clean_tmpwork(); chdir(TIC.Inbound); /* * If the file is converted, we set the date of the original * received file as the file creation date. */ snprintf(Temp, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile); if ((MustRearc || DidBanner) && CFG.ct_KeepDate) { if ((tic.Touch) && (tic.FileArea)) { ut.actime = mktime(localtime(&TIC.FileDate)); ut.modtime = mktime(localtime(&TIC.FileDate)); utime(Temp, &ut); Syslog('-', "Restamp filedate %s to %s", Temp, rfcdate(ut.modtime)); } } /* * Now make sure the file timestamp is updated. The file may be restamped, * altered by banners etc. */ TIC.FileDate = file_time(Temp); /* * If not passthru, import in the BBS. */ if (tic.FileArea) { Syslog('+', "Import: %s (%s) Area: %s", TIC.NewFile, TIC.NewFullName, TIC.TicIn.Area); BBS_Imp = Add_BBS(&qal); if (!BBS_Imp) { Bad((char *)"File Import Error"); free(Temp); tidy_qualify(&qal); clean_tmpwork(); return 1; } } chdir(TIC.Inbound); /* * Create file announce record */ if (tic.FileArea) { if (strlen(TIC.TicIn.Magic)) magic_update(TIC.TicIn.Magic, TIC.NewFile); else Magic_UpDateAlias(); for (i = 0; i < TIC.File_Id_Ct; i++) strncpy(T_File.LDesc[i], TIC.File_Id[i], 48); T_File.TotLdesc = TIC.File_Id_Ct; T_File.Announce = tic.Announce; strncpy(T_File.Name, TIC.NewFile, 12); strncpy(T_File.LName, TIC.NewFullName, 80); T_File.Fdate = TIC.FileDate; Add_ToBeRep(T_File); } if (TIC.SendOrg && !tic.FileArea) { /* * If it's a passthru area we don't need the * file in the inbound anymore so it can be * deleted. */ snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File); if (file_rm(temp1) == 0) Syslog('f', "Deleted %s", temp1); } if (DownLinks) { First = TRUE; /* * Add all our system aka's to the seenby lines in the same zone, * omit aka's already in the seenby list. */ for (i = 0; i < 39; i++) { if (CFG.akavalid[i] && (tic.Aka.zone == CFG.aka[i].zone)) { p_from = fido2faddr(CFG.aka[i]); if (! in_list(p_from, sbl, TRUE)) { if (CFG.aka[i].point) snprintf(sbe, 24, "%u:%u/%u.%u", CFG.aka[i].zone, CFG.aka[i].net, CFG.aka[i].node, CFG.aka[i].point); else snprintf(sbe, 24, "%u:%u/%u", CFG.aka[i].zone, CFG.aka[i].net, CFG.aka[i].node); fill_list(sbl, sbe, NULL); } tidy_faddr(p_from); } } /* * Add seen-by lines for all systems that will receive this file. */ for (tmpq = qal; tmpq; tmpq = tmpq->next) { if (tmpq->send) { if (CFG.aka[i].point) snprintf(sbe, 24, "%u:%u/%u.%u", tmpq->aka.zone, tmpq->aka.net, tmpq->aka.node, tmpq->aka.point); else snprintf(sbe, 24, "%u:%u/%u", tmpq->aka.zone, tmpq->aka.net, tmpq->aka.node); fill_list(sbl, sbe, NULL); } } uniq_list(sbl); sort_list(sbl); /* * Now forward this file to the qualified downlinks. */ for (tmpq = qal; tmpq; tmpq = tmpq->next) { if (tmpq->send) { ForwardFile(tmpq->aka, *sbl); tic_out++; } } } Magic_ExecCommand(); Magic_CopyFile(); Magic_UnpackFile(); Magic_AdoptFile(); snprintf(Temp, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicName); if (unlink(Temp)) { WriteError("$Can't delete %s", Temp); } free(Temp); tidy_qualify(&qal); return 0; }
int msgq::tmpscan() { int found=0; time(¤t_time); DIR *tmpdir=opendir(TMPDIR); if (!tmpdir) clog_msg_errno(); struct dirent *de; std::string subdir; std::string ctlfile, datfile, newctlfile, newdatfile; struct stat stat_buf; std::string qdir, qname; while ((de=readdir(tmpdir)) != 0) { const char *p; for (p=de->d_name; *p; p++) if (!isdigit((int)(unsigned char)*p)) break; if (*p) continue; // Subdirs must be named all digits subdir=TMPDIR "/"; subdir += de->d_name; DIR *subde=opendir(subdir.c_str()); while ((de=readdir(subde)) != 0 && found < 100) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; ctlfile=subdir; ctlfile += '/'; ctlfile += de->d_name; int i=-1; if (stat(ctlfile.c_str(), &stat_buf)) continue; size_t j=ctlfile.size(); while (j) { if (ctlfile[--j] == '/') break; if (ctlfile[j] == '.') { i=j; break; } } ino_t inum=stat_buf.st_ino; // Cleanup timeout. Should always be sufficiently longer than // the submit timeout set in submit.C via alarm_timeout. if (stat_buf.st_mtime < current_time - 48 * 60 * 60) { if (de->d_name[0] == 'D') { datfile=subdir + "/C" + (de->d_name+1); if (stat(datfile.c_str(), &stat_buf) == 0) continue; // Wait until the C file is // purged // Be carefull with Cnnnn.x files, because // Cnnnn.1 is used to hold submission of all // of them. A race condition can leave // Cnnnn.1 in a submittable state, so if it // is removed, other copies of this message // can become submittable, during a very small // window. } else if (de->d_name[0] == 'C' && i >= 0) { // This race condition is handled simply // by not removing Cxxxxx.n if Cxxxxx.n+1 // exists. char nbuf[NUMBUFSIZE]; datfile=ctlfile.substr(0, i); size_t n=atoi( ctlfile.c_str()+i+1); ++n; datfile += '.'; datfile += libmail_str_size_t(n, nbuf); if (stat(datfile.c_str(), &stat_buf) == 0) continue; // Wait until the C.1 file is // purged unlink(ctlfile.c_str()); ctlfile=subdir + "/D" + (de->d_name+1); /* FALLTHRU */ } unlink(ctlfile.c_str()); continue; } if (de->d_name[0] != 'C') continue; if (i >= 0) { datfile=ctlfile.substr(0, i); datfile += ".1"; if (ctlfile == datfile || stat(datfile.c_str(), &stat_buf) == 0) continue; } datfile=subdir + "/D" + (de->d_name+1); newdatfile=qmsgsdatname(inum); newctlfile=qmsgsctlname(inum); struct ctlfile ctf; if ((access(datfile.c_str(), 0) == 0 && access(newdatfile.c_str(), 0) == 0) || access(newctlfile.c_str(), 0) == 0 || ctlfile_openfn(ctlfile.c_str(), &ctf, 0, 0)) { clog_msg_start_err(); clog_msg_str("QUEUE FILE CORRUPTION: inode "); clog_msg_uint(inum); clog_msg_send(); utime(ctlfile.c_str(), 0); // Keep it around continue; } time_t nextattempt=current_time+delaytime; if ((i=ctlfile_searchfirst(&ctf, COMCTLFILE_SUBMITDELAY)) >= 0) nextattempt=current_time+ atoi(ctf.lines[i]+1); qname=qmsgqname(inum, nextattempt); ctlfile_nextattempt(&ctf, nextattempt); if (link(ctlfile.c_str(), qname.c_str())) { mkdir(qmsgqdir(current_time),0755); if (link(ctlfile.c_str(), qname.c_str()) && errno != EEXIST) clog_msg_errno(); } if (rename(datfile.c_str(), newdatfile.c_str())) { mkdir(qmsgsdir(inum), 0755); // We may need to create this dir rename(datfile.c_str(), newdatfile.c_str()); } if (rename(ctlfile.c_str(), newctlfile.c_str())) clog_msg_errno(); for (i=qname.size(); i; ) { if (qname[--i] == '/') break; } qdir=qname.substr(0, i); qname=qname.substr(i+1); ++found; ctlfile_close(&ctf); queuescan3(qdir, qname, de->d_name); } closedir(subde); if (stat(subdir.c_str(), &stat_buf) == 0 && stat_buf.st_mtime < current_time - 2 * 60 * 60) rmdir(subdir.c_str()); // Just give it a try } closedir(tmpdir); return (found); }