Beispiel #1
0
void 
showusers(int n, int mode, char *ucomp, char raw)
{
	char		status    [20];
	char		online    [20];
	char           *filename = 0;
	char		realfile  [512];
	char		bar       [20];
	struct timeval	tstop;
	double		mb_xfered = 0;
	double		speed  , pct = 0;
	double		my_filesize = 0;
	int		mask;
	int		noshow;
	char		maskchar;
	int		i         , x, m;
	unsigned	hours;
	unsigned char	minutes;
	unsigned	seconds;

	gettimeofday(&tstop, (struct timezone *)0);

	if (!strncasecmp(count_hidden, "false", 5))
		chidden = 0;

	for (x = 0; x < n; x++) {
		if (!user[x].procid)
			continue;

		maskchar = ' ';
		mask = noshow = 0;

		if (strcomp(husers, user[x].username) || strcomp(hgroups, get_g_name(user[x].groupid))) {
			if (showall)
				maskchar = '*';
			else
				noshow++;
		}
		if (noshow == 0 && strlen(mpaths)) {
			if (maskchar == ' ' && matchpath(mpaths, user[x].currentdir)) {
				if (showall)
					maskchar = '*';
				else
					mask++;
			}
		}
		if (strplen(user[x].status) > 5)
			filename = malloc(strplen(user[x].status) - 5 + 1);
		else
			filename = malloc(1);

		if ((!strncasecmp(user[x].status, "STOR ", 5) ||
		     !strncasecmp(user[x].status, "APPE ", 5)) &&
		    user[x].bytes_xfer) {

			speed = user[x].bytes_xfer / 1024. /
				((tstop.tv_sec - user[x].tstart.tv_sec) * 1. + (tstop.tv_usec - user[x].tstart.tv_usec) / 1000000.);

			if (debug) {
				printf("DEBUG SPEED INFO: username   = %s\nDEBUG SPEED INFO: time spent = %.2f seconds\nDEBUG SPEED INFO: transfered = %.0f KB\nDEBUG SPEED INFO: speed      = %.2f KB/s\n", user[x].username, ((tstop.tv_sec - user[x].tstart.tv_sec) * 1. + (tstop.tv_usec - user[x].tstart.tv_usec) / 1000000.), (double)(user[x].bytes_xfer / 1024.), speed);
				}
			if ((!noshow && !mask && !(maskchar == '*')) || chidden) {
				total_up_speed += speed;
				uploads++;
			}
			if (!mask) {
				pct = -1;
				m = strplen(user[x].status) - 5;
				if (m < 15 || raw)
					sprintf(filename, "%.*s", m, user[x].status + 5);
				else
					sprintf(filename, "%.15s", user[x].status + m - 10);

				strcpy(bar, "?->");
				if (!raw)
					if (speed > threshold) {
						speed = (speed / 1024.0);
						sprintf(status, "Up: %7.2fMB/s", speed);
					} else {
						sprintf(status, "Up: %7.0fKB/s", speed);
					}
				else if (raw == 1)
					sprintf(status, "\"UP\" \"%.0f\"", speed);
				else
					sprintf(status, "upld|%.0f", speed);

				mb_xfered = user[x].bytes_xfer * 1.0 / 1024 / 1024;
			}
		} else if ((!strncasecmp(user[x].status, "RETR ", 5) && user[x].bytes_xfer)) {
			mb_xfered = 0;

			sprintf(realfile, "%s", user[x].currentdir);

			/*
			 * Dirty way to get around the fact that the buffered
			 * reading will change user[x].currentdir to not
			 * include filename once it's done reading the entire
			 * file "to memory". This means user[x].currentdir in
			 * fact will be _currentdir_ and this cannot tell us
			 * a true filesize since it's calculated from
			 * filesize(/site/incoming/path) - w/o filename :(
			 */
			my_filesize = filesize(realfile);
			if (my_filesize < user[x].bytes_xfer) {
				my_filesize = user[x].bytes_xfer;
			}
			pct = (user[x].bytes_xfer * 1. / my_filesize) * 100;
			i = 15 * user[x].bytes_xfer * 1. / my_filesize;
			i = (i > 15 ? 15 : i);

			bar[i] = 0;

			for (m = 0; m < i; m++)
				bar[m] = 'x';
			speed = user[x].bytes_xfer / 1024. /
				((tstop.tv_sec - user[x].tstart.tv_sec) * 1. +
				(tstop.tv_usec - user[x].tstart.tv_usec) / 1000000.);

			if (debug) {
				printf("DEBUG SPEED INFO: username   = %s\nDEBUG SPEED INFO: time spent = %.2f seconds\nDEBUG SPEED INFO: transfered = %.0f KB\nDEBUG SPEED INFO: speed      = %.2f KB/s\n", user[x].username, ((tstop.tv_sec - user[x].tstart.tv_sec) * 1. + (tstop.tv_usec - user[x].tstart.tv_usec) / 1000000.), (double)(user[x].bytes_xfer / 1024.), speed);
				}

			if ((!noshow && !mask && !(maskchar == '*')) || chidden) {
				total_dn_speed += speed;
				downloads++;
			}
			m = strplen(user[x].status) - 5;
			if (!mask) {
				if (m < 15 || raw)
					sprintf(filename, "%.*s", m, user[x].status + 5);
				else
					sprintf(filename, "%.15s", user[x].status + m - 10);

				if (!raw)
					if (speed > threshold) {
						speed = (speed / 1024.0);
						sprintf(status, "Dn: %7.2fMB/s", speed);
					} else {
						sprintf(status, "Dn: %7.0fKB/s", speed);
					}
				else if (raw == 1)
					sprintf(status, "\"DN\" \"%.1f\"", speed);
				else
					sprintf(status, "dnld|%.1f", speed);
			}
		} else {
			pct = *bar = *filename = hours = minutes = mb_xfered = 0;
			seconds = tstop.tv_sec - user[x].tstart.tv_sec;
			while (seconds >= 3600) {
				hours++;
				seconds -= 3600;
			}
			while (seconds >= 60) {
				minutes++;
				seconds -= 60;
			}
			if ((!noshow && !mask && !(maskchar == '*')) || chidden) {
				if ((int)seconds > idle_barrier)
					idlers++;
				else
					browsers++;
			}
			if (!raw)
				sprintf(status, "Idle: %02d:%02d:%02d", hours, minutes, seconds);
			else if (raw == 1)
				sprintf(status, "\"ID\" \"%d\"", (hours * 60 * 60) + (minutes * 60) + seconds);
			else
				sprintf(status, "idle|%02d:%02d:%02d", hours, minutes, seconds);
		}

		hours = minutes = 0;
		seconds = tstop.tv_sec - user[x].login_time;
		while (seconds >= 3600) {
			hours++;
			seconds -= 3600;
		}
		while (seconds >= 60) {
			minutes++;
			seconds -= 60;
		}
		sprintf(online, "%02d:%02d:%02d", hours, minutes, seconds);

		if (mode == 0 && raw != 3 ) {
			if (!raw && (showall || (!noshow && !mask && !(maskchar == '*')))) {
				if (mb_xfered)
					printf("|%1c%-16.16s/%-10.10s | %-15s | XFER: %13.1fMB |\n", maskchar, user[x].username, get_g_name(user[x].groupid), status, mb_xfered);
				else
					printf("|%1c%-16.16s/%-10.10s | %-15s | %3.0f%%: %-15.15s |\n", maskchar, user[x].username, get_g_name(user[x].groupid), status, pct, bar);

				printf("| %-27.27s | since %8.8s  | file: %-15.15s |\n", user[x].tagline, online, filename);
				printf("+-----------------------------------------------------------------------+\n");
			} else if (raw == 1 && (showall || (!noshow && !mask && !(maskchar == '*')))) {
				/*
				 * Maskeduser / Username / GroupName / Status
				 * / TagLine / Online / Filename / Part
				 * up/down-loaded / Current dir / PID
				 */
				printf("\"USER\" \"%1c\" \"%s\" \"%s\" %s \"%s\" \"%s\" \"%s\" \"%.1f%s\" \"%s\" \"%d\"\n", maskchar, user[x].username, get_g_name(user[x].groupid), status, user[x].tagline, online, filename, (pct >= 0 ? pct : mb_xfered), (pct >= 0 ? "%" : "MB"), user[x].currentdir, user[x].procid);
			} else if (showall || (!noshow && !mask && !(maskchar == '*'))) {
				printf("%s|%s|%s|%s|%s\n", user[x].username, get_g_name(user[x].groupid), user[x].tagline, status, filename);
			}
			if ((!noshow && !mask && !(maskchar == '*')) || chidden) {
				onlineusers++;
			}
		} else if (raw == 3) {
			if ((!noshow && !mask && !(maskchar == '*')) || chidden) {
				onlineusers++;
			}
		} else if (user[x].username && !strcmp(ucomp, user[x].username)) {
#ifdef _WITH_ALTWHO
			if (!raw && (showall || (!noshow && !mask && !(maskchar == '*')))) {
				if (mb_xfered)
					printf("%s : %1c%s/%s has xfered %.1fMB of %s and has been online for %8.8s.\n", status, maskchar, user[x].username, get_g_name(user[x].groupid), mb_xfered, filename, online);
				else if (strcmp(filename, ""))
					printf("%s : %1c%s/%s has xfered %.0f%% of %s and has been online for %8.8s.\n", status, maskchar, user[x].username, get_g_name(user[x].groupid), pct, filename, online);
				else
					printf("%s : %1c%s/%s has been online for %8.8s.\n", status, maskchar, user[x].username, get_g_name(user[x].groupid), online);
			} else if (raw == 1 && (showall || (!noshow && !mask && !(maskchar == '*')))) {
				printf("\"USER\" \"%1c\" \"%s\" \"%s\" %s \"%s\" \"%s\" \"%s\" \"%.1f%s\" \"%s\" \"%d\"\n", maskchar, user[x].username, get_g_name(user[x].groupid), status, user[x].tagline, online, filename, (pct >= 0 ? pct : mb_xfered), (pct >= 0 ? "%" : "MB"), user[x].currentdir, user[x].procid);
			} else if (showall || (!noshow && !mask && !(maskchar == '*'))) {
				printf("%s|%s|%s|%s|%s\n", user[x].username, get_g_name(user[x].groupid), user[x].tagline, status, filename);
			}
#else
			if (!onlineusers) {
				if (!raw && (showall || (!noshow && !mask && !(maskchar == '*'))))
					printf("\002%s\002 - %s", user[x].username, status);
				else if (raw == 1 && (showall || (!noshow && !mask && !(maskchar == '*'))))
					printf("\"USER\" \"%s\" %s", user[x].username, status);
				else if (showall || (!noshow && !mask && !(maskchar == '*')))
					printf("\002%s\002 - %s", user[x].username, status);
			} else {
				if (!raw && (showall || (!noshow && !mask && !(maskchar == '*'))))
					printf(" - %s", status);
				else if (raw == 1 && (showall || (!noshow && !mask && !(maskchar == '*'))))
					printf("\"USER\" \"\" %s", status);
				else if (showall || (!noshow && !mask && !(maskchar == '*')))
					printf(" - %s", status);
			}
#endif
			if (!noshow && !mask && !(maskchar == '*'))
				onlineusers++;
			else if (chidden)
				onlineusers++;

		}
		free(filename);
	}
}
Beispiel #2
0
int 
main(int argc, char *argv[])
{
	int		n, l, complete_type = 0, not_allowed = 0, argv_mode = 0;

#ifdef USING_GLFTPD
        int             gnum = 0, unum = 0;
	char		myflags[20];
#endif

	char           *ext, exec[4096], *complete_bar = 0, *inc_point[2];
	unsigned int	crc;
	struct stat	fileinfo;

	uid_t		f_uid;
	gid_t		f_gid;
	double		temp_time = 0;

	DIR		*dir, *parent;
	struct dirent	*dp;
	long		loc;
	time_t		timenow;
#if (test_for_password || extract_nfo || zip_clean)
	off_t		tempstream;
#endif

	short		rescan_quick = rescan_default_to_quick;
	char		one_name[NAME_MAX];
	char		*temp_p = NULL;
	int		chdir_allowed = 0, argnum = 0;
	GLOBAL		g;
#if (enable_rescan_script)
	char		target[PATH_MAX+NAME_MAX];
#endif

#if ( program_uid > 0 )
	setegid(program_gid);
	seteuid(program_uid);
#endif

	umask(0666 & 000);

	d_log("rescan: PZS-NG (rescan v2) %s debug log.\n", ng_version);
	d_log("rescan: Rescan executed by: (uid/gid) %d/%d\n", geteuid(), getegid());

#ifdef _ALT_MAX
	d_log("rescan: PATH_MAX not found - using predefined settings! Please report to the devs!\n");
#endif

	d_log("rescan: Allocating memory for variables\n");
	g.ui = ng_realloc2(g.ui, sizeof(*g.ui) * 30, 1, 1, 1);
	g.gi = ng_realloc2(g.gi, sizeof(*g.gi) * 30, 1, 1, 1);

	bzero(one_name, NAME_MAX);

#ifdef USING_GLFTPD
	if (getenv("FLAGS")) {
		strlcpy(myflags, getenv("FLAGS"), sizeof(myflags));
		n = strlen(myflags);
		while (n > 0) {
			--n;
			l = strlen(rescan_chdir_flags);
			while(l > 0) {
				--l;
				if (myflags[n] == rescan_chdir_flags[l])
					chdir_allowed = 1;
			}
		}
	}
	if (!geteuid())
		chdir_allowed = 1;
#endif

	/* With glftpd we can use env vars, rest of the world: commandline. */
#ifndef USING_GLFTPD
	if (argc < 7) {
		print_syntax(chdir_allowed);
		ng_free(g.ui);
		ng_free(g.gi);
		return 0;
	}
	argnum = 6;

	if (chdir(argv[5]) != 0) {
		printf("Could not chdir to <cwd = '%s'>, ftpd agnostic mode: %s\n", argv[5], strerror(errno));
		d_log("rescan: Could not chdir to <cwd = '%s'>, ftpd agnostic mode: %s\n", argv[5], strerror(errno));
		ng_free(g.ui);
		ng_free(g.gi);
		return 1;
        }
#else
	argnum = 1;
#endif

	while ((argnum < argc) && argc > 1) {
		if (!strncasecmp(argv[argnum], "--quick", 7))
			rescan_quick = TRUE;
		else if (!strncasecmp(argv[argnum], "--normal", 8))
			rescan_quick = FALSE;
		else if (!strncasecmp(argv[argnum], "--dir=", 6) && (strlen(argv[argnum]) > 7) && chdir_allowed) {
			temp_p = argv[argnum] + 6;
			if ((!matchpath(nocheck_dirs, temp_p)) && (matchpath(zip_dirs, temp_p) || matchpath(sfv_dirs, temp_p)) && !matchpath(group_dirs, temp_p)) {
				if (chdir(temp_p)) {
					d_log("rescan: Failed to chdir() to %s : %s\n", temp_p, strerror(errno));
					not_allowed = 1;
				}
			} else {
				printf("Not allowed to chdir() to %s\n", temp_p);
				ng_free(g.ui);
				ng_free(g.gi);
				return 1;
			}
			printf("PZS-NG Rescan %s: Rescanning %s\n", ng_version, temp_p);
			argv_mode = 1;

		} else if (!strncasecmp(argv[argnum], "--chroot=", 9) && (strlen(argv[argnum]) > 10) && chdir_allowed) {
			if (temp_p == NULL) {
				temp_p = argv[argnum] + 9;
				if (chroot(temp_p) == -1) {
					d_log("rescan: Failed to chroot() to %s : %s\n", temp_p, strerror(errno));
					not_allowed = 1;
				}
			} else {
				temp_p = argv[argnum] + 9;
				printf("Not allowed to chroot() to %s\n", temp_p);
				ng_free(g.ui);
				ng_free(g.gi);
				return 1;
			}
			printf("PZS-NG Rescan %s: Chroot'ing to %s\n", ng_version, temp_p);
			argv_mode = 1;

		} else if (!strncasecmp(argv[argnum], "--help", 6) || !strncasecmp(argv[argnum], "/?", 2) || !strncasecmp(argv[argnum], "--?", 3)) {
                        print_syntax(chdir_allowed);
			ng_free(g.ui);
			ng_free(g.gi);
                        return 0;
		} else {
			strlcpy(one_name, argv[argnum], sizeof(one_name));
			rescan_quick = FALSE;
			printf("PZS-NG Rescan %s: Rescanning in FILE mode\n", ng_version);
			if (one_name[strlen(one_name) - 1] == '*') {
				one_name[strlen(one_name) - 1] = '\0';
			} else if (!fileexists(one_name)) {
				d_log("PZS-NG Rescan: No file named '%s' exists.\n", one_name);
				one_name[0] = '\0';
				not_allowed = 1;
			}
			argv_mode = 1;
		}
		argnum++;
	}
	if (one_name[0] == '\0') {
		if (rescan_quick == TRUE) {
			printf("PZS-NG Rescan %s: Rescanning in QUICK mode.\n", ng_version);
		} else {
			printf("PZS-NG Rescan %s: Rescanning in NORMAL mode.\n", ng_version);
		}
	}
	printf("PZS-NG Rescan %s: Use --help for options.\n\n", ng_version);

	if (not_allowed) {
		ng_free(g.ui);
		ng_free(g.gi);
		return 1;
	}

	if (!getcwd(g.l.path, PATH_MAX)) {
		d_log("rescan: getcwd() failed: %s\n", strerror(errno));
	}
	if (subcomp(g.l.path, g.l.basepath) && (g.l.basepath[0] == '\0'))
		strlcpy(g.l.basepath, g.l.path, sizeof(g.l.basepath));
	if (strncmp(g.l.path, g.l.basepath, PATH_MAX))
		d_log("rescan: We are in subdir of %s\n", g.l.basepath);
        strlcpy(g.v.misc.current_path, g.l.path, sizeof(g.v.misc.current_path));
        strlcpy(g.v.misc.basepath, g.l.basepath, sizeof(g.v.misc.basepath));

	if ((matchpath(nocheck_dirs, g.l.path) && !rescan_nocheck_dirs_allowed) || (matchpath(group_dirs, g.l.path) && argv_mode) || (!matchpath(nocheck_dirs, g.l.path) && !matchpath(zip_dirs, g.l.path) && !matchpath(sfv_dirs, g.l.path) && !matchpath(group_dirs, g.l.path)) || insampledir(g.l.path)) {
		d_log("rescan: Dir matched with nocheck_dirs/sample_list, or is not in the zip/sfv/group-dirs.\n");
		d_log("rescan: Freeing memory, and exiting.\n");
		printf("Notice: Unable to rescan this dir - check config.\n\n");
		ng_free(g.ui);
		ng_free(g.gi);
		return 0;
	}
	g.v.misc.slowest_user[0] = ULONG_MAX;

	bzero(&g.v.total, sizeof(struct race_total));
	g.v.misc.fastest_user[0] = 0;
	g.v.misc.release_type = RTYPE_NULL;
	g.v.misc.write_log = 0;

#ifdef USING_GLFTPD
	if (getenv("SECTION") == NULL) {
		sprintf(g.v.sectionname, "DEFAULT");
	} else {
		snprintf(g.v.sectionname, sizeof(g.v.sectionname), "%s", getenv("SECTION"));
	}
#else
        snprintf(g.v.sectionname, sizeof(g.v.sectionname), argv[4]);
#endif

	g.l.length_path = (int)strlen(g.l.path);
	g.l.length_zipdatadir = sizeof(storage);
	n = g.l.length_path + g.l.length_zipdatadir + 11;
	g.l.race = ng_realloc2(g.l.race, n, 1, 1, 1);
	g.l.sfv = ng_realloc2(g.l.sfv, n - 1, 1, 1, 1);
	g.l.sfvbackup = ng_realloc2(g.l.sfvbackup, n + 1, 1, 1, 1);
	g.l.leader = ng_realloc2(g.l.leader, n - 2, 1, 1, 1);
	g.l.sfv_incomplete = 0;

	getrelname(&g);

#ifdef USING_GLFTPD
	gnum = buffer_groups(GROUPFILE, 0);
	unum = buffer_users(PASSWDFILE, 0);
#endif

	sprintf(g.l.sfv, storage "/%s/sfvdata", g.l.path);
	sprintf(g.l.sfvbackup, storage "/%s/sfvbackup", g.l.path);
	sprintf(g.l.leader, storage "/%s/leader", g.l.path);
	sprintf(g.l.race, storage "/%s/racedata", g.l.path);
	d_log("rescan: Creating directory to store racedata in\n");
 	maketempdir(g.l.path);

	d_log("rescan: Locking release\n");
	while (1) {
		if ((l = create_lock(&g.v, g.l.path, PROGTYPE_RESCAN, 3, 0))) {
			d_log("rescan: Failed to lock release.\n");
			if (l == 1) {
				d_log("rescan: version mismatch. Exiting.\n");
				printf("Error. You need to rm -fR ftp-data/pzs-ng/* before rescan will work.\n"); /* */
				ng_free(g.ui);
				ng_free(g.gi);
				ng_free(g.l.sfv);
				ng_free(g.l.sfvbackup);
				ng_free(g.l.leader);
				ng_free(g.l.race);
#ifdef USING_GLFTPD
				buffer_groups(GROUPFILE, gnum);
				buffer_users(PASSWDFILE, unum);
#endif
				exit(EXIT_FAILURE);
			}
			if (l == PROGTYPE_POSTDEL) {
				n = (signed int)g.v.data_incrementor;
				d_log("rescan: Detected postdel running - sleeping for one second.\n");
				if (!create_lock(&g.v, g.l.path, PROGTYPE_RESCAN, 0, g.v.data_queue))
					break;
				usleep(1000000);
				if (!create_lock(&g.v, g.l.path, PROGTYPE_RESCAN, 0, g.v.data_queue))
					break;
				if ( n == (signed int)g.v.data_incrementor) {
					d_log("rescan: Failed to get lock. Forcing unlock.\n");
					if (create_lock(&g.v, g.l.path, PROGTYPE_RESCAN, 2, g.v.data_queue)) {
						d_log("rescan: Failed to force a lock.\n");
						d_log("rescan: Exiting with error.\n");
						ng_free(g.ui);
						ng_free(g.gi);
						ng_free(g.l.sfv);
						ng_free(g.l.sfvbackup);
						ng_free(g.l.leader);
						ng_free(g.l.race);
#ifdef USING_GLFTPD
						buffer_groups(GROUPFILE, gnum);
						buffer_users(PASSWDFILE, unum);
#endif
						exit(EXIT_FAILURE);
					}
					break;
				}
			} else {
				for (l = 0; l <= max_seconds_wait_for_lock * 10; ++l) {
					d_log("rescan: sleeping for .1 second before trying to get a lock (queue: %d).\n", g.v.data_queue);
					usleep(100000);
					if (!create_lock(&g.v, g.l.path, PROGTYPE_RESCAN, 0, g.v.data_queue))
						break;
				}
				if (l >= max_seconds_wait_for_lock * 10) {
					d_log("rescan: Failed to get lock. Will not force unlock.\n");
					ng_free(g.ui);
					ng_free(g.gi);
					ng_free(g.l.sfv);
					ng_free(g.l.sfvbackup);
					ng_free(g.l.leader);
					ng_free(g.l.race);
#ifdef USING_GLFTPD
					buffer_groups(GROUPFILE, gnum);
					buffer_users(PASSWDFILE, unum);
#endif
					exit(EXIT_FAILURE);
				}
			}
		}
		usleep(10000);
		if (update_lock(&g.v, 1, 0) != -1)
			break;
	}

	move_progress_bar(1, &g.v, g.ui, g.gi);
	if (g.l.incomplete)
		unlink(g.l.incomplete);
	if (del_completebar)
		removecomplete();

	dir = opendir(".");
	parent = opendir("..");

	if (!((rescan_quick && findfileext(dir, ".sfv")) || *one_name)) {
		if (g.l.sfv)
			unlink(g.l.sfv);
		if (g.l.race)
			unlink(g.l.race);
	}
	printf("Rescanning files...\n");

	if (findfileext(dir, ".zip")) {
		if (!fileexists(unzip_bin)) {
			printf("rescan: ERROR! Not able to check zip-files - %s does not exist!\n", unzip_bin);
			closedir(dir);
			closedir(parent);
			ng_free(g.ui);
			ng_free(g.gi);
			ng_free(g.l.sfv);
			ng_free(g.l.sfvbackup);
			ng_free(g.l.leader);
			ng_free(g.l.race);
#ifdef USING_GLFTPD
			buffer_groups(GROUPFILE, gnum);
			buffer_users(PASSWDFILE, unum);
#endif
			remove_lock(&g.v);
			exit(EXIT_FAILURE);
		} else {
			crc = 0;
			rewinddir(dir);
			timenow = time(NULL);
			while ((dp = readdir(dir))) {
				ext = find_last_of(dp->d_name, ".");
				if (*ext == '.')
					ext++;
				if (!strcasecmp(ext, "zip")) {
					stat(dp->d_name, &fileinfo);
					f_uid = fileinfo.st_uid;
					f_gid = fileinfo.st_gid;
					if ((timenow == fileinfo.st_ctime) && (fileinfo.st_mode & 0111)) {
						d_log("rescan.c: Seems this file (%s) is in the process of being uploaded. Ignoring for now.\n", dp->d_name);
						continue;
					}
#ifdef USING_GLFTPD
					strlcpy(g.v.user.name, get_u_name(f_uid), sizeof(g.v.user.name));
					strlcpy(g.v.user.group, get_g_name(f_gid), sizeof(g.v.user.group));
#else
					strlcpy(g.v.user.name, argv[1], sizeof(g.v.user.name));
					strlcpy(g.v.user.group, argv[2], sizeof(g.v.user.group));
#endif
					strlcpy(g.v.file.name, dp->d_name, sizeof(g.v.file.name));
					g.v.file.speed = 2005 * 1024;
					g.v.file.size = fileinfo.st_size;
					g.v.total.start_time = 0;
#if (test_for_password || extract_nfo)
					tempstream = telldir(dir);
					if ((!findfileextcount(dir, ".nfo") || findfileextcount(dir, ".zip")) && !mkdir(".unzipped", 0777))
						snprintf(exec, sizeof(exec), "%s -qqjo \"%s\" -d .unzipped 2>.delme", unzip_bin, g.v.file.name);
					else
						snprintf(exec, sizeof(exec), "%s -qqt \"%s\" 2>.delme", unzip_bin, g.v.file.name);
					seekdir(dir, tempstream);
#else
					snprintf(exec, sizeof(exec), "%s -qqt \"%s\" 2>.delme", unzip_bin, g.v.file.name);
#endif
					if (system(exec) == 0 || (allow_error2_in_unzip == TRUE && errno < 3 )) {
						writerace(g.l.race, &g.v, crc, F_CHECKED);
					} else {
						writerace(g.l.race, &g.v, crc, F_BAD);
						if (g.v.file.name)
							unlink(g.v.file.name);
						removedir(".unzipped");
						continue;
					}
#if (test_for_password || extract_nfo || zip_clean)
					tempstream = telldir(dir);
                        	        if ((!findfileextcount(dir, ".nfo") || findfileextcount(dir, ".zip")) && check_zipfile(".unzipped", g.v.file.name, findfileextcount(dir, ".nfo"))) {
                                	        d_log("rescan: File %s is password protected.\n", g.v.file.name);
						writerace(g.l.race, &g.v, crc, F_BAD);
						if (g.v.file.name)
							unlink(g.v.file.name);
						seekdir(dir, tempstream);
						continue;
	                                }
					seekdir(dir, tempstream);
#endif
					if (!fileexists("file_id.diz")) {
						snprintf(exec, sizeof(exec), "%s -qqjnCLL \"%s\" file_id.diz 2>.delme", unzip_bin, g.v.file.name);
						if (execute(exec) != 0) {
							d_log("rescan: No file_id.diz found (#%d): %s\n", errno, strerror(errno));
						} else {
							if (fileexists("file_id.diz.bad")) {
								loc = findfile(dir, "file_id.diz.bad");
								seekdir(dir, loc);
								dp = readdir(dir);
								unlink(dp->d_name);
							}
							if (chmod("file_id.diz", 0666))
								d_log("rescan: Failed to chmod %s: %s\n", "file_id.diz", strerror(errno));
						}
					}
				}
			}

			if (fileexists(".delme"))
				unlink(".delme");

			g.v.total.files = read_diz();
			if (!g.v.total.files) {
				g.v.total.files = 1;
				unlink("file_id.diz");
			}
			g.v.total.files_missing = g.v.total.files;
			readrace(g.l.race, &g.v, g.ui, g.gi);
			sortstats(&g.v, g.ui, g.gi);
			if (g.v.total.files_missing < 0) {
				g.v.total.files -= g.v.total.files_missing;
				g.v.total.files_missing = 0;
			}
			buffer_progress_bar(&g.v);
			if (g.v.total.files_missing == 0) {
				complete(&g, complete_type);
				createstatusbar(convert(&g.v, g.ui, g.gi, zip_completebar));
#if (chmod_completebar)
				if (!matchpath(group_dirs, g.l.path)) {
					if (chmod_each(convert(&g.v, g.ui, g.gi, zip_completebar), 0222))
						d_log("rescan: Failed to chmod a statusbar: %s\n", strerror(errno));
				}
#endif

			} else {
				if (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs) {
					if (create_incomplete()) {
						d_log("rescan: create_incomplete() returned something\n");
					}
				}
				move_progress_bar(0, &g.v, g.ui, g.gi);
			}
			if (g.l.nfo_incomplete) {
				if (findfileext(dir, ".nfo")) {
					d_log("rescan: Removing missing-nfo indicator (if any)\n");
					remove_nfo_indicator(&g);
				} else if (matchpath(check_for_missing_nfo_dirs, g.l.path) && (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs)) {
					if (!g.l.in_cd_dir) {
						d_log("rescan: Creating missing-nfo indicator %s.\n", g.l.nfo_incomplete);
						if (create_incomplete_nfo()) {
							d_log("rescan: create_incomplete_nfo() returned something\n");
						}
					} else {
						if (findfileextparent(parent, ".nfo")) {
							d_log("rescan: Removing missing-nfo indicator (if any)\n");
							remove_nfo_indicator(&g);
						} else {
							d_log("rescan: Creating missing-nfo indicator (base) %s.\n", g.l.nfo_incomplete);
							if (create_incomplete_nfo()) {
								d_log("rescan: create_incomplete_nfo() returned something\n");
							}
						}
					}
				}
			}
		}
	} else if ((temp_p = findfileext(dir, ".sfv")) || (create_missing_sfv && file_count(dir))) {
		if (!temp_p && create_missing_sfv && file_count(dir)) {
			d_log("rescan: No sfv found - creating one.\n");
			make_sfv(g.l.path);
			if (!(temp_p = findfileext(dir, ".sfv"))) {
				d_log("rescan: Freeing memory, removing lock and exiting.\n");
				unlink(g.l.sfv);
				if (fileexists(g.l.sfvbackup))
				unlink(g.l.sfvbackup);
				unlink(g.l.race);
				closedir(dir);
				closedir(parent);
				ng_free(g.ui);
				ng_free(g.gi);
				ng_free(g.l.sfv);
				ng_free(g.l.sfvbackup);
				ng_free(g.l.leader);
				ng_free(g.l.race);
#ifdef USING_GLFTPD
				buffer_groups(GROUPFILE, gnum);
				buffer_users(PASSWDFILE, unum);
#endif
				remove_lock(&g.v);
				return 0;
			}
		}
#if ( create_missing_sfv_link == TRUE )
		d_log("rescan: Removing missing-sfv indicator (if any)\n");
		unlink(g.l.sfv_incomplete);
#endif
		strlcpy(g.v.file.name, temp_p, sizeof(g.v.file.name));

		maketempdir(g.l.path);
		stat(g.v.file.name, &fileinfo);

		if (copysfv(g.v.file.name, g.l.sfv, &g.v)) {
			printf("Found invalid entries in SFV - Exiting.\n");

			while ((dp = readdir(dir))) {
				ext = find_last_of(dp->d_name, "-");
				if (!strcasecmp(ext, "-missing"))
					unlink(dp->d_name);
			}

			d_log("rescan: Freeing memory, removing lock and exiting\n");
			unlink(g.l.sfv);
			if (fileexists(g.l.sfvbackup))
			unlink(g.l.sfvbackup);
			unlink(g.l.race);
			closedir(dir);
			closedir(parent);
			ng_free(g.ui);
			ng_free(g.gi);
			ng_free(g.l.sfv);
			ng_free(g.l.sfvbackup);
			ng_free(g.l.leader);
			ng_free(g.l.race);
#ifdef USING_GLFTPD
			buffer_groups(GROUPFILE, gnum);
			buffer_users(PASSWDFILE, unum);
#endif
			remove_lock(&g.v);

			return 0;
		}
		g.v.total.start_time = 0;
		rewinddir(dir);
		while ((dp = readdir(dir))) {
			if (*one_name && strncasecmp(one_name, dp->d_name, strlen(one_name)))
				continue;

			l = (int)strlen(dp->d_name);

			ext = find_last_of(dp->d_name, ".-");
			if (*ext == '.')
				ext++;

			if (!update_lock(&g.v, 1, 0)) {
				d_log("rescan: Another process wants the lock - will comply and remove lock, then exit.\n");
				closedir(dir);
				closedir(parent);
				ng_free(g.ui);
				ng_free(g.gi);
				ng_free(g.l.sfv);
				ng_free(g.l.sfvbackup);
				ng_free(g.l.leader);
				ng_free(g.l.race);
#ifdef USING_GLFTPD
				buffer_groups(GROUPFILE, gnum);
				buffer_users(PASSWDFILE, unum);
#endif
				remove_lock(&g.v);
				exit(EXIT_FAILURE);
			}

			if (
				!strcomp(ignored_types, ext) &&
				(!(strcomp(allowed_types, ext) && !matchpath(allowed_types_exemption_dirs, g.l.path))) &&
				strcasecmp("sfv", ext) &&
				strcasecmp("nfo", ext) &&
				strcasecmp("bad", ext) &&
				strcasecmp("-missing", ext) &&
				strncmp(dp->d_name, ".", 1)
				) {

				stat(dp->d_name, &fileinfo);

				if (S_ISDIR(fileinfo.st_mode))
					continue;
				if (ignore_zero_sized_on_rescan && !fileinfo.st_size)
					continue;

				f_uid = fileinfo.st_uid;
				f_gid = fileinfo.st_gid;

#ifdef USING_GLFTPD
				strlcpy(g.v.user.name, get_u_name(f_uid), sizeof(g.v.user.name));
				strlcpy(g.v.user.group, get_g_name(f_gid), sizeof(g.v.user.group));
#else
				strlcpy(g.v.user.name, argv[1], sizeof(g.v.user.name));
				strlcpy(g.v.user.group, argv[2], sizeof(g.v.user.group));
#endif

				strlcpy(g.v.file.name, dp->d_name, sizeof(g.v.file.name));
				g.v.file.speed = 2005 * 1024;
				g.v.file.size = fileinfo.st_size;

				temp_time = fileinfo.st_mtime;

				if (g.v.total.start_time == 0)
					g.v.total.start_time = temp_time;
				else
					g.v.total.start_time = (g.v.total.start_time < temp_time ? g.v.total.start_time : temp_time);

				g.v.total.stop_time = (temp_time > g.v.total.stop_time ? temp_time : g.v.total.stop_time);

				/* Hide users in group_dirs */
				if (matchpath(group_dirs, g.l.path) && (hide_group_uploaders == TRUE)) {
					d_log("rescan: Hiding user in group-dir:\n");
					if ((int)strlen(hide_gname) > 0) {
						snprintf(g.v.user.group, sizeof(g.v.user.group), "%s", hide_gname);
						d_log("rescan:    Changing groupname\n");
					}
					if ((int)strlen(hide_uname) > 0) {
						snprintf(g.v.user.name, sizeof(g.v.user.name), "%s", hide_uname);
						d_log("rescan:    Changing username\n");
					}
#if (show_users_in_group_dirs == FALSE)
					if ((int)strlen(hide_uname) == 0) {
						d_log("rescan:    Making username = groupname\n");
						snprintf(g.v.user.name, sizeof(g.v.user.name), "%s", g.v.user.group);
					}
#endif
				}

				if (!rescan_quick || (g.l.race && !match_file(g.l.race, dp->d_name)))
					crc = calc_crc32(dp->d_name);
				else
 					crc = 1;

				if (!S_ISDIR(fileinfo.st_mode)) {
					if (g.v.file.name)
						unlink_missing(g.v.file.name);
					if (l > 44) {
						if (crc == 1)
							printf("\nFile: %s CHECKED", dp->d_name + l - 44);
						else
							printf("\nFile: %s %.8x", dp->d_name + l - 44, crc);
					} else {
						if (crc == 1)
							printf("\nFile: %-44s CHECKED", dp->d_name);
						else
							printf("\nFile: %-44s %.8x", dp->d_name, crc);
					}
				}
				if(fflush(stdout))
					d_log("rescan: ERROR: %s\n", strerror(errno));
				if (!rescan_quick || (g.l.race && !match_file(g.l.race,	dp->d_name)) || !fileexists(dp->d_name))
					writerace(g.l.race, &g.v, crc, F_NOTCHECKED);
			}
		}
		printf("\n");
		testfiles(&g.l, &g.v, 1);
		printf("\n");
		readsfv(g.l.sfv, &g.v, 0);
		readrace(g.l.race, &g.v, g.ui, g.gi);
		sortstats(&g.v, g.ui, g.gi);
		buffer_progress_bar(&g.v);

		if (g.l.nfo_incomplete) {
			if (findfileext(dir, ".nfo")) {
				d_log("rescan: Removing missing-nfo indicator (if any)\n");
				remove_nfo_indicator(&g);
			} else if (matchpath(check_for_missing_nfo_dirs, g.l.path) && (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs)) {
				if (!g.l.in_cd_dir) {
					d_log("rescan: Creating missing-nfo indicator %s.\n", g.l.nfo_incomplete);
					if (create_incomplete_nfo()) {
						d_log("rescan: create_incomplete_nfo() returned something\n");
					}
				} else {
					if (findfileextparent(parent, ".nfo")) {
						d_log("rescan: Removing missing-nfo indicator (if any)\n");
						remove_nfo_indicator(&g);
					} else {
						d_log("rescan: Creating missing-nfo indicator (base) %s.\n", g.l.nfo_incomplete);

						/* This is not pretty, but should be functional. */
						if ((inc_point[0] = find_last_of(g.l.path, "/")) != g.l.path)
							*inc_point[0] = '\0';
						if ((inc_point[1] = find_last_of(g.v.misc.release_name, "/")) != g.v.misc.release_name)
							*inc_point[1] = '\0';
						if (create_incomplete_nfo()) {
							d_log("rescan: create_incomplete_nfo() returned something\n");
						}
						if (*inc_point[0] == '\0')
							*inc_point[0] = '/';
						if (*inc_point[1] == '\0')
							*inc_point[1] = '/';
					}
				}
			}
		}
#if (create_missing_sample_link)
		if (g.l.sample_incomplete) {
			if (findfileextsub(dir) || matchpartialdirname(missing_sample_check_ignore_list, g.v.misc.release_name, missing_sample_check_ignore_dividers)) {
				d_log("rescan: Removing missing-sample indicator (if any)\n");
				remove_sample_indicator(&g);
			} else if (matchpath(check_for_missing_sample_dirs, g.l.path) && (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs)) {
				if (!g.l.in_cd_dir) {
					d_log("rescan: Creating missing-sample indicator %s.\n", g.l.sample_incomplete);
					if (create_incomplete_sample()) {
						d_log("rescan: create_incomplete_sample() returned something\n");
					}
				} else {
					if (findfileextsubp(dir)) {
						d_log("rescan: Removing missing-sample indicator (if any)\n");
						remove_sample_indicator(&g);
					} else {
						d_log("rescan: Creating missing-sample indicator (base) %s.\n", g.l.sample_incomplete);

						/* This is not pretty, but should be functional. */
						if ((inc_point[0] = find_last_of(g.l.path, "/")) != g.l.path)
							*inc_point[0] = '\0';
						if ((inc_point[1] = find_last_of(g.v.misc.release_name, "/")) != g.v.misc.release_name)
							*inc_point[1] = '\0';
						if (create_incomplete_sample()) {
							d_log("rescan: create_incomplete_sample() returned something\n");
						}
						if (*inc_point[0] == '\0')
							*inc_point[0] = '/';
						if (*inc_point[1] == '\0')
							*inc_point[1] = '/';
					}
				}
			}
		}
#endif
		if (g.v.misc.release_type == RTYPE_AUDIO) {
			get_audio_info(findfileextfromlist(dir, audio_types), &g.v.audio);
			/* Sort if we're not in a group-dir/nosort-dir. */
			if (!matchpath(group_dirs, g.l.path) && !matchpath(audio_nosort_dirs, g.l.path)) {
				printf(" Resorting release.\n");
				audioSort(&g.v.audio, g.l.link_source, g.l.link_target);
			}
		}
		if ((g.v.total.files_missing == 0) && (g.v.total.files > 0)) {

			switch (g.v.misc.release_type) {
			case RTYPE_RAR:
				complete_bar = rar_completebar;
				break;
			case RTYPE_OTHER:
				complete_bar = other_completebar;
				break;
			case RTYPE_AUDIO:
				complete_bar = audio_completebar;
#if ( create_m3u == TRUE )
				n = snprintf(exec, sizeof(exec), "%s", findfileext(dir, ".sfv"));
				strcpy(exec + n - 3, "m3u");
				create_indexfile(g.l.race, &g.v, exec);
#endif
				break;
			case RTYPE_VIDEO:
				complete_bar = video_completebar;
				break;
			}
			complete(&g, complete_type);

			if (complete_bar) {
				createstatusbar(convert(&g.v, g.ui, g.gi, complete_bar));
#if (chmod_completebar)
				if (!matchpath(group_dirs, g.l.path)) {
                                        if (chmod_each(convert(&g.v, g.ui, g.gi, complete_bar), 0222))
                                                d_log("rescan: Failed to chmod a statusbar: %s\n", strerror(errno));
				}
#endif
			}
#if (enable_rescan_script)
			d_log("rescan: Executing rescan_script script\n");
			if (!fileexists(rescan_script)) {
				d_log("rescan: Warning - rescan_script (%s) - file does not exist!\n", rescan_script);
			} else {
				snprintf(target, sizeof(target), rescan_script " \"%s\"", g.v.file.name);
				if (execute(target) != 0)
					d_log("rescan: Failed to execute rescan_script: %s\n", strerror(errno));
			}
#endif
		} else {
			if (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs) {
				if (create_incomplete()) {
					d_log("rescan: create_incomplete() returned something\n");
				}
			}
				move_progress_bar(0, &g.v, g.ui, g.gi);
		}
	} else {
		int empty = 1;
#if (create_missing_sfv_link == TRUE)
		if ((!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs) && g.l.sfv_incomplete && !matchpath(nocheck_dirs, g.l.path) && !matchpath(allowed_types_exemption_dirs, g.l.path)) {
			rewinddir(dir);
			while ((dp = readdir(dir))) {
				stat(dp->d_name, &fileinfo);
				if (S_ISREG(fileinfo.st_mode)) {
					ext = find_last_of(dp->d_name, ".");
					if (*ext == '.')
						ext++;
					if (*ext && get_filetype(&g, ext) == 3) {
						d_log("rescan: Creating missing-sfv indicator %s.\n", g.l.sfv_incomplete);
						if (create_incomplete_sfv())
							d_log("rescan: create_incomplete_sfv() returned something.\n");
						empty = 0;
						break;
					}
				}
			}
		}
#endif
		if (empty && mark_empty_dirs_as_incomplete_on_rescan) {
			if (create_incomplete()) {
				d_log("rescan: create_incomplete() returned something\n");
			}
			printf(" Empty dir - marking as incomplete.\n");
		}
	}

	printf(" Passed : %i\n", (int)g.v.total.files - (int)g.v.total.files_missing);
	printf(" Failed : %i\n", (int)g.v.total.files_bad);
	printf(" Missing: %i\n", (int)g.v.total.files_missing);
	printf("  Total : %i\n", (int)g.v.total.files);

	if (g.v.total.files && !g.v.total.files_missing) {
		g.v.misc.data_completed = 1;
	} else {
		g.v.misc.data_completed = 0;
	}

	d_log("rescan: Freeing memory and removing lock.\n");
	closedir(dir);
	closedir(parent);
	ng_free(g.l.race);
	ng_free(g.l.sfv);
	ng_free(g.l.sfvbackup);
	ng_free(g.l.leader);

	remove_lock(&g.v);
	updatestats_free(&g);

#ifdef USING_GLFTPD
	buffer_groups(GROUPFILE, gnum);
	buffer_users(PASSWDFILE, unum);
#endif

	exit(0);
}
Beispiel #3
0
/*
 * Modified	: 01.20.2002 Author	: Dark0n3
 *
 * Description	: Parses file entries from sfv file and store them in a file.
 *
 * Todo		: Add dupefile remover.
 *
 * Totally rewritten by js on 08.02.2005
 */
int
copysfv(const char *source, const char *target, struct VARS *raceI)
{
	int		infd, outfd, i, retval = 0;
	short int	music, rars, video, others, type;

	char		*ptr, fbuf[2048];
	FILE		*insfv;

	DIR		*dir;

	SFVDATA		sd;

//#if ( sfv_dupecheck == TRUE )
	int		skip = 0;
	SFVDATA		tempsd;
//#endif

#if ( sfv_cleanup == TRUE )
	int		tmpfd;
	char		crctmp[16];

	if ((tmpfd = open(".tmpsfv", O_CREAT | O_TRUNC | O_RDWR, 0644)) == -1)
		d_log("copysfv: open(.tmpsfv): %s\n", strerror(errno));
#endif

	if ((infd = open(source, O_RDONLY)) == -1) {
		d_log("copysfv: open(%s): %s\n", source, strerror(errno));
		remove_lock(raceI);
		exit(EXIT_FAILURE);
	}

	if ((outfd = open(target, O_CREAT | O_TRUNC | O_RDWR, 0666)) == -1) {
		d_log("copysfv: open(%s): %s\n", target, strerror(errno));
		remove_lock(raceI);
		exit(EXIT_FAILURE);
	}

	video = music = rars = others = type = 0;

	dir = opendir(".");

	if (!update_lock(raceI, 1, 0)) {
		d_log("copysfv: Lock is suggested removed. Will comply and exit\n");
		remove_lock(raceI);
		exit(EXIT_FAILURE);
	}

	if ((insfv = fdopen(infd, "r")) == NULL) {
		d_log("copysfv: Unable to fdopen %s: %s\n", source, strerror(errno));
		remove_lock(raceI);
		exit(EXIT_FAILURE);
	}

	while ((fgets(fbuf, sizeof(fbuf), insfv))) {

		/* remove comment */
		if ((ptr = find_first_of(fbuf, ";")))
			*ptr = '\0';

		tailstrip_chars(fbuf, WHITESPACE_STR);
		ptr = prestrip_chars(fbuf, WHITESPACE_STR);
		if (ptr != fbuf)
			d_log("copysfv: prestripped whitespaces (%d chars)\n", ptr - fbuf);

		if (strlen(ptr) == 0)
			continue;

#if (sfv_cleanup_lowercase == TRUE)
		for (; *ptr; ptr++)
			*ptr = tolower(*ptr);
#endif
		sd.crc32 = 0;
		bzero(sd.fname, sizeof(sd.fname));
		if ((ptr = find_last_of(fbuf, " \t"))) {

			/* pass the " \t" */
			ptr++;

			/* what we have now is hopefully a crc */
			for (i = 0; isxdigit(*ptr) != 0; i++)
				ptr++;

			ptr -= i;
			if (i > 8 || i < 6) {
				/* we didn't get an 8 digit crc number */
#if (sfv_cleanup == TRUE)
				/* do stuff  */
				d_log("copysfv: We did not get a 8 digit crc number for %s - trying to continue anyway\n", sd.fname);
#else
				retval = 1;
				goto END;
#endif
			} else {
				sd.crc32 = hexstrtodec(ptr);

				/* cut off crc string */
				*ptr = '\0';

				/* nobody should be stupid enough to have spaces
				 * at the end of the file name */
				tailstrip_chars(fbuf, WHITESPACE_STR);
			}

		} else {
			/* we have a filename only. */
#if (sfv_cleanup == TRUE)
			/* do stuff  */
			d_log("copysfv: We did not find a crc number for %s - trying to continue anyway\n", sd.fname);
#else
			retval = 1;
			goto END;
#endif
		}

		/* we assume what's left is a filename */
		ptr = prestrip_chars(fbuf, WHITESPACE_STR);
		if (ptr != fbuf)
			d_log("copysfv: prestripped whitespaces (%d chars)\n", ptr - fbuf);

#if (allow_slash_in_sfv == TRUE)
		if (ptr != find_last_of(ptr, "/")) {
			ptr = find_last_of(ptr, "/") + 1;
			d_log("copysfv: found '/' in filename - adjusting.\n");
		}
		if (ptr != find_last_of(ptr, "\\")) {
			ptr = find_last_of(ptr, "\\") + 1;
			d_log("copysfv: found '\\' in filename - adjusting.\n");
		}
#endif
		if (strlen(ptr) > 0 && strlen(ptr) < NAME_MAX-9 ) {
			strlcpy(sd.fname, ptr, NAME_MAX-9);

			if (sd.fname != find_last_of(sd.fname, "\t") || sd.fname != find_last_of(sd.fname, "\\") || sd.fname != find_last_of(sd.fname, "/")) {
				d_log("copysfv: found '/', '\\' or <TAB> as part of filename in sfv - logging file as bad.\n");
				retval = 1;
				break;
			}

			if (sd.crc32 == 0) {
#if (sfv_calc_single_fname == TRUE || create_missing_sfv == TRUE)
				sd.crc32 = match_lenient(dir, sd.fname);
				d_log("copysfv: Got filename (%s) without crc, calculated to %X.\n", sd.fname, sd.crc32);
#else
				d_log("copysfv: Got filename (%s) without crc - ignoring file.\n", sd.fname);
				continue;
#endif
			}


			/* get file extension */
			ptr = find_last_of(fbuf, ".");
			if (*ptr == '.')
				ptr++;

			if (!strcomp(ignored_types, ptr) && !(strcomp(allowed_types, ptr) && !matchpath(allowed_types_exemption_dirs, raceI->misc.current_path)) && !strcomp("sfv", ptr) && !strcomp("nfo", ptr)) {

				skip = 0;
//#if ( sfv_dupecheck == TRUE )
				/* read from sfvdata - no parsing */
				lseek(outfd, 0L, SEEK_SET);
				while (read(outfd, &tempsd, sizeof(SFVDATA)))
//					if (!strcmp(sd.fname, tempsd.fname) || (sd.crc32 == tempsd.crc32 && sd.crc32))
					if (!strcmp(sd.fname, tempsd.fname))
						skip = 1;

				lseek(outfd, 0L, SEEK_END);

#if ( sfv_dupecheck == TRUE )
				if (skip)
					continue;
#endif

				d_log("copysfv:  File in sfv: '%s' (%x)\n", sd.fname, sd.crc32);

#if ( sfv_cleanup == TRUE )
				/* write good stuff to .tmpsfv */
				if (tmpfd != -1) {
					sprintf(crctmp, "%.8x", sd.crc32);
					if (write(tmpfd, sd.fname, strlen(sd.fname)) != (int)strlen(sd.fname))
						d_log("copysfv: write failed: %s\n", strerror(errno));
					if (write(tmpfd, " ", 1) != 1)
						d_log("copysfv: write failed: %s\n", strerror(errno));
					if (write(tmpfd, crctmp, 8) != 8)
						d_log("copysfv: write failed: %s\n", strerror(errno));
#if (sfv_cleanup_crlf == TRUE )
					if (write(tmpfd, "\r", 1) != 1)
						d_log("copysfv: write failed: %s\n", strerror(errno));
#endif
					if (write(tmpfd, "\n", 1) != 1)
						d_log("copysfv: write failed: %s\n", strerror(errno));
				}
#endif

				if (strcomp(audio_types, ptr))
					music++;
				else if (israr(ptr))
					rars++;
				else if (strcomp(video_types, ptr))
					video++;
				else
					others++;

#if ( create_missing_files == TRUE )
				if (!findfile(dir, sd.fname) && !(matchpath(allowed_types_exemption_dirs, raceI->misc.current_path) && strcomp(allowed_types, ptr)))
					create_missing(sd.fname, raceI);
#endif

				if (write(outfd, &sd, sizeof(SFVDATA)) != sizeof(SFVDATA))
					d_log("copysfv: write failed: %s\n", strerror(errno));
			}
		}
	}

	if (music > rars) {
		if (video > music)
			type = (video >= others ? 4 : 2);
		else
			type = (music >= others ? 3 : 2);
	} else {
		if (video > rars)
			type = (video >= others ? 4 : 2);
		else
			type = (rars >= others ? 1 : 2);
	}

#if ( sfv_cleanup == FALSE )
END:
#endif
	close(infd);
#if ( sfv_cleanup == TRUE )
	if (tmpfd != -1) {
		close(tmpfd);
		unlink(source);
		rename(".tmpsfv", source);
#ifdef USING_EBFTPD
                if (ebftpd_chown(source, raceI->user.uid, raceI->user.gid) < 0)
                        d_log("copysfv: ebftpd_chown(%s,%i,%i): %s\n", source, raceI->user.uid, raceI->user.gid, strerror(errno));

#endif
	}
#endif

	closedir(dir);
	close(outfd);
	if (!update_lock(raceI, 1, type)) {
		d_log("copysfv: Lock is suggested removed. Will comply and exit\n");
		remove_lock(raceI);
		exit(EXIT_FAILURE);
	}
	raceI->data_type = type;
	return retval;
}
Beispiel #4
0
int 
main(int argc, char **argv)
{
	char		fileext[4];
	char		*name_p = 0;
	char		*temp_p;
	char		*target = NULL;
	char		*fname;

#ifdef USING_GLFTPD
	char		*env_user, *env_group;
#else
        char            dirname[PATH_MAX];
#endif

	char	        *inc_point[2];
	int		n, m, ftype = 0;
	unsigned char	empty_dir = 0;
	unsigned char	_incomplete = 0;
	
	GLOBAL		g;
	
	DIR		*dir, *parent;

#ifdef USING_GLFTPD
	if (argc == 1) {
		d_log("postdel: no param specified\n");
		return 0;
	}

	if ((int)strlen(argv[1]) < 6 || strncmp(argv[1], "DELE ", 5)) {
		printf("pzs-ng postdel script.\n");
		printf(" - this is supposed to be run from glftpd.\n");
		printf(" - if you wish to run it yourself from chroot, \n");
		printf(" - use /bin/postdel \"DELE <filename>\"\n");
		printf(" - thank you. (remember the quotes!)\n");
		return 0;
	}

	fname = argv[1] + 5;	/* This way we simply skip the required
				 * 'DELE'-part of the argument (so we get
				 * filename) */
#else
	if (argc < 6) {
                printf("[running in ftpd-agnostic mode]\n");
                printf("Missing arguments! Syntax:\n");
                printf(" %s <user> <group> <tagline> <section> <filepath>\n", argv[0]);
		return 0;
	}

        fname = strrchr(argv[5], '/');
        if (fname == NULL)
        {
            fname = argv[5];
            strcpy(dirname, "./");
        }
        else
        {
            strlcpy(dirname, argv[5], fname - argv[5] + 1);
            fname++;
        }

        chdir(dirname);
        d_log("postdel: Got a 'DELE %s' in '%s'\n", fname, dirname);
#endif

	d_log("postdel: Project-ZS Next Generation (pzs-ng) %s debug log for postdel.\n", ng_version);
	d_log("postdel: Postdel executed by: (uid/gid) %d/%d\n", geteuid(), getegid());

#ifdef _ALT_MAX
	d_log("postdel: PATH_MAX not found - using predefined settings! Please report to the devs!\n");
#endif

#ifdef USING_GLFTPD
	d_log("postdel: Reading user name from env\n");
	if ((env_user = getenv("USER")) == NULL) {
		d_log("postdel: postdel: Could not find environment variable 'USER', setting value to 'Nobody'\n");
		env_user = "******";
	}
	d_log("postdel: Reading group name from env\n");
	if ((env_group = getenv("GROUP")) == NULL) {
		d_log("postdel: Could not find environment variable 'GROUP', setting value to 'NoGroup'\n");
		env_group = "NoGroup";
	}
#endif

#if ( program_uid > 0 )
	d_log("postdel: Trying to change effective gid\n");
	setegid(program_gid);
	d_log("postdel: Trying to change effective uid\n");
	seteuid(program_uid);
#endif

	if (!strcmp(fname, "debug"))
		d_log("postdel: Reading directory structure\n");

	dir = opendir(".");
	parent = opendir("..");

	if (fileexists(fname)) {
		d_log("postdel: File (%s) still exists\n", fname);
#if (remove_dot_debug_on_delete == TRUE)
		if (strcmp(fname, "debug"))
			unlink(fname);
#endif
		closedir(dir);
		closedir(parent);
		return 0;
	}
	umask(0666 & 000);

	d_log("postdel: Clearing arrays\n");
	bzero(&g.v.total, sizeof(struct race_total));
	g.v.misc.slowest_user[0] = ULONG_MAX;
	g.v.misc.fastest_user[0] = 0;

#ifdef USING_GLFTPD
	/* YARR; THE PAIN OF MAGIC NUMBERS! */
	d_log("postdel: Copying env/predefined username to g.v. (%s)\n", env_user);
	strlcpy(g.v.user.name, env_user, sizeof(g.v.user.name));
	
	d_log("postdel: Copying env/predefined groupname to g.v. (%s)\n", env_group);
	strlcpy(g.v.user.group, env_group, sizeof(g.v.user.group));
#else
	d_log("postdel: Copying argv[1] (username) to g.v. (%s)\n", argv[1]);
	strlcpy(g.v.user.name, argv[1], sizeof(g.v.user.name));
	d_log("postdel: Copying argv[2] (groupname) to g.v. (%s)\n", argv[2]);
	strlcpy(g.v.user.group, argv[2], sizeof(g.v.user.group));
#endif

	d_log("postdel: File to remove is: %s\n", fname);

	if (!*g.v.user.group)
		memcpy(g.v.user.group, "NoGroup", 8);

	d_log("postdel: Allocating memory for variables\n");

	g.ui = ng_realloc2(g.ui, sizeof(struct USERINFO *) * 30, 1, 1, 1);
	g.gi = ng_realloc2(g.gi,sizeof(struct GROUPINFO *) * 30, 1, 1, 1);

	if (!getcwd(g.l.path, PATH_MAX)) {
		d_log("postdel: Failed to getcwd(): %s\n", strerror(errno));
	}

	if (subcomp(g.l.path, g.l.basepath) && (g.l.basepath[0] == '\0'))
		strlcpy(g.l.basepath, g.l.path, PATH_MAX);
	if (strncmp(g.l.path, g.l.basepath, PATH_MAX))
		d_log("postdel: We are in subdir of %s\n", g.l.basepath);
	strncpy(g.v.misc.current_path, g.l.path, sizeof(g.v.misc.current_path));
	strncpy(g.v.misc.basepath, g.l.basepath, sizeof(g.v.misc.basepath));

	d_log("postdel: Creating directory to store racedata in\n");
	maketempdir(g.l.path);

	d_log("postdel: Locking release\n");
	while(1) {
		if ((m = create_lock(&g.v, g.l.path, PROGTYPE_POSTDEL, 3, 0))) {
			d_log("postdel: Failed to lock release.\n");
			if (m == 1) {
				d_log("postdel: version mismatch. Exiting.\n");
				exit(EXIT_FAILURE);
			}
			if (m == PROGTYPE_RESCAN) {
				d_log("postdel: Detected rescan running - will try to make it quit.\n");
				update_lock(&g.v, 0, 0);
			}
			if (m == PROGTYPE_POSTDEL) {
				n = (signed int)g.v.data_incrementor;
				d_log("postdel: Detected postdel running - sleeping for one second.\n");
				if (!create_lock(&g.v, g.l.path, PROGTYPE_POSTDEL, 0, g.v.data_queue))
					break;
				usleep(1000000);
				if (!create_lock(&g.v, g.l.path, PROGTYPE_POSTDEL, 0, g.v.data_queue))
					break;
				if ( n == (signed int)g.v.data_incrementor) {
					d_log("postdel: Failed to get lock. Forcing unlock.\n");
					if (create_lock(&g.v, g.l.path, PROGTYPE_POSTDEL, 2, g.v.data_queue)) {
						d_log("postdel: Failed to force a lock.\n");
						d_log("postdel: Exiting with error.\n");
						exit(EXIT_FAILURE);
					}
					break;
				}
			} else {
				for ( n = 0; n <= max_seconds_wait_for_lock * 10; n++) {
					d_log("postdel: sleeping for .1 second before trying to get a lock.\n");
					usleep(100000);
					if (!(m = create_lock(&g.v, g.l.path, PROGTYPE_POSTDEL, 0, g.v.data_queue)))
						break;

				}
				if (n >= max_seconds_wait_for_lock * 10) {
					if (m == PROGTYPE_RESCAN) {
						d_log("postdel: Failed to get lock. Forcing unlock.\n");
						if (create_lock(&g.v, g.l.path, PROGTYPE_POSTDEL, 2, g.v.data_queue))
						d_log("postdel: Failed to force a lock.\n");
					} else
						d_log("postdel: Failed to get a lock.\n");
					if (!g.v.data_in_use && !ignore_lock_timeout) {
						d_log("postdel: Exiting with error.\n");
						exit(EXIT_FAILURE);
					}
				}
			}
			rewinddir(dir);
			rewinddir(parent);
		}
		usleep(10000);
		if (update_lock(&g.v, 1, 0) != -1)
			break;
	}

	g.l.race = ng_realloc(g.l.race, n = (int)strlen(g.l.path) + 12 + sizeof(storage), 1, 1, &g.v, 1);
	g.l.sfv = ng_realloc(g.l.sfv, n, 1, 1, &g.v, 1);
	g.l.sfvbackup = ng_realloc(g.l.sfvbackup, n, 1, 1, &g.v, 1);
	g.l.leader = ng_realloc(g.l.leader, n, 1, 1, &g.v, 1);
	target = ng_realloc(target, 4096, 1, 1, &g.v, 1);

	if (getenv("SECTION") == NULL)
		sprintf(g.v.sectionname, "DEFAULT");
	else
		snprintf(g.v.sectionname, 127, "%s", getenv("SECTION"));

	d_log("postdel: Copying data &g.l into memory\n");
	strlcpy(g.v.file.name, fname, NAME_MAX);
	sprintf(g.l.sfv, storage "/%s/sfvdata", g.l.path);
	sprintf(g.l.sfvbackup, storage "/%s/sfvbackup", g.l.path);
	sprintf(g.l.leader, storage "/%s/leader", g.l.path);
	sprintf(g.l.race, storage "/%s/racedata", g.l.path);
	g.l.sfv_incomplete = 0;
	d_log("postdel: Caching release name\n");
	getrelname(&g);
	d_log("postdel: DEBUG 0: incomplete: '%s', path: '%s'\n", g.l.incomplete, g.l.path);

	if ((matchpath(nocheck_dirs, g.l.path) && rescan_nocheck_dirs_allowed == FALSE) || (!matchpath(zip_dirs, g.l.path) && !matchpath(sfv_dirs, g.l.path) && !matchpath(group_dirs, g.l.path))) {
		d_log("postdel: Dir matched with nocheck_dirs, or is not in the zip/sfv/group-dirs\n");
		d_log("postdel: Freeing memory, removing lock and exiting\n");
		ng_free(g.ui);
		ng_free(g.gi);
		if (fileexists(g.l.race))
			unlink(g.l.race);
		if (fileexists(g.l.sfv))
			unlink(g.l.sfv);
		if (fileexists(g.l.sfvbackup))
			unlink(g.l.sfvbackup);
		if (fileexists(g.l.leader))
			unlink(g.l.leader);
		ng_free(g.l.race);
		ng_free(g.l.sfv);
		ng_free(g.l.sfvbackup);
		ng_free(g.l.leader);

		if (remove_dot_debug_on_delete)
			unlink(".debug");

		remove_lock(&g.v);
		return 0;

	}


	d_log("postdel: Parsing file extension from filename...\n");

	temp_p = find_last_of(g.v.file.name, ".");

	if (*temp_p != '.') {
		d_log("postdel: Got: no extension\n");
		temp_p = name_p;
	} else {
		d_log("postdel: Got: %s\n", temp_p);
		temp_p++;
	}
	name_p++;

	if (temp_p) {
		while ((signed)strlen(temp_p) - 4 > 0)
			temp_p++;
		snprintf(fileext, 4, "%s", temp_p);
	} else
		*fileext = '\0';

	g.v.misc.release_type = read_headdata(&g.v);
	switch (get_filetype_postdel(&g, fileext)) {
	case 0:
		ftype = g.v.misc.release_type;
		d_log("postdel: File type is: ZIP\n");
		if (matchpath(zip_dirs, g.l.path)) {
			if (matchpath(group_dirs, g.l.path)) {
				g.v.misc.write_log = 0;
			} else {
				g.v.misc.write_log = 1;
			}
		} else if (matchpath(sfv_dirs, g.l.path) && strict_path_match) {
			if (matchpath(group_dirs, g.l.path)) {
				g.v.misc.write_log = 0;
			} else {
				d_log("postdel: Directory matched with sfv_dirs\n");
				break;
			}
		}

		if (!fileexists("file_id.diz")) {
			temp_p = findfileext(dir, ".zip");
			if (temp_p != NULL) {
				d_log("postdel: file_id.diz does not exist, trying to extract it from %s\n", temp_p);
				sprintf(target, "%s -qqjnCLL \"%s\" file_id.diz", unzip_bin, temp_p);
				execute(target);
				if (chmod("file_id.diz", 0666))
					d_log("postdel: Failed to chmod %s: %s\n", "file_id.diz", strerror(errno));
			}
		}
		d_log("postdel: Reading diskcount from diz\n");
//		g.v.total.files = read_diz("file_id.diz");
		g.v.total.files = read_diz();
		if (g.v.total.files == 0) {
			d_log("postdel: Could not get diskcount from diz\n");
			g.v.total.files = 1;
			
		}
		g.v.total.files_missing = g.v.total.files;

		d_log("postdel: Reading race data from file to memory\n");
		readrace(g.l.race, &g.v, g.ui, g.gi);

		d_log("postdel: Caching progress bar\n");
		buffer_progress_bar(&g.v);

		d_log("postdel: Removing old complete bar, if any\n");
		removecomplete(g.v.misc.release_type);

		if (g.v.total.files_missing < 0) {
			g.v.total.files -= g.v.total.files_missing;
			g.v.total.files_missing = 0;
		}
		if (!g.v.total.files_missing) {
			d_log("postdel: Creating complete bar\n");
			createstatusbar(convert(&g.v, g.ui, g.gi, zip_completebar));
		} else if (g.v.total.files_missing < g.v.total.files) {
			if (g.v.total.files_missing == 1) {
				d_log("postdel: Writing INCOMPLETE to %s\n", log);
				writelog(&g, convert(&g.v, g.ui, g.gi, incompletemsg), general_incomplete_type);
			}
			_incomplete = 1;
		} else {
			empty_dir = 1;
		}
		remove_from_race(g.l.race, g.v.file.name, &g.v);
		break;
	case 1: /* SFV */
		ftype = g.v.misc.release_type;
		d_log("postdel: Reading file count from sfvdata\n");
		readsfv(g.l.sfv, &g.v, 0);

		if (fileexists(g.l.race)) {
			d_log("postdel: Reading race data from file to memory\n");
			readrace(g.l.race, &g.v, g.ui, g.gi);
		}
		d_log("postdel: Caching progress bar\n");
		buffer_progress_bar(&g.v);

		if (g.v.total.files_missing == g.v.total.files) {
			empty_dir = 1;
		}
		d_log("postdel: SFV was removed - removing progressbar/completebar and -missing pointers.\n");
		removecomplete(g.v.misc.release_type);

		d_log("postdel: removing files created\n");
		if (fileexists(g.l.sfv)) {
			delete_sfv(g.l.sfv, &g.v);
			unlink(g.l.sfv);
		}
		if (fileexists(g.l.sfvbackup))
			unlink(g.l.sfvbackup);

		if (g.l.nfo_incomplete)
			unlink(g.l.nfo_incomplete);
		if (g.l.sample_incomplete)
			unlink(g.l.sample_incomplete);
		if (g.l.incomplete)
			unlink(g.l.incomplete);
		d_log("postdel: removing progressbar, if any\n");
		g.v.misc.release_type = ftype;
		move_progress_bar(1, &g.v, g.ui, g.gi);
		break;
	case 3:
		ftype = g.v.misc.release_type;
		d_log("postdel: Removing old complete bar, if any\n");
		removecomplete(g.v.misc.release_type);

		g.v.misc.write_log = matchpath(sfv_dirs, g.l.path) > 0 ? 1 - matchpath(group_dirs, g.l.path) : 0;

		if (fileexists(g.l.race)) {
			d_log("postdel: Reading race data from file to memory\n");
			readrace(g.l.race, &g.v, g.ui, g.gi);
		} else {
			empty_dir = 1;
		}
		if (fileexists(g.l.sfv)) {
#if ( create_missing_files == TRUE )
#if ( sfv_cleanup_lowercase == TRUE )
			strtolower(g.v.file.name);
#endif
			create_missing(g.v.file.name);
#endif
			d_log("postdel: Reading file count from SFV\n");
			readsfv(g.l.sfv, &g.v, 0);

			d_log("postdel: Caching progress bar\n");
			buffer_progress_bar(&g.v);
		}

		d_log("postdel: g.v.total.files_missing=%d, g.v.total.files=%d\n", g.v.total.files_missing, g.v.total.files);
		if (g.v.total.files_missing < g.v.total.files) {
			if (g.v.total.files_missing == 1) {
				d_log("postdel: Writing INCOMPLETE to %s\n", log);
				writelog(&g, convert(&g.v, g.ui, g.gi, incompletemsg), general_incomplete_type);
			}
			_incomplete = 1;
		} else {
			d_log("postdel: Removing old race data\n");
			unlink(g.l.race);
			if (findfileext(dir, ".sfv") == NULL) {
				empty_dir = 1;
			} else {
				_incomplete = 1;
			}
		}
		remove_from_race(g.l.race, g.v.file.name, &g.v);
		break;
	case 4:
		ftype = g.v.misc.release_type;
		if (!fileexists(g.l.race))
			empty_dir = 1;
		break;
	case 255:
		ftype = g.v.misc.release_type;
		if (!fileexists(g.l.race))
			empty_dir = 1;
		break;
	case 2:
		ftype = g.v.misc.release_type;
		if (!fileexists(g.l.race)) {
			empty_dir = 1;
		} else {
			d_log("postdel: Reading race data from file to memory\n");
			readrace(g.l.race, &g.v, g.ui, g.gi);
			d_log("postdel: Caching progress bar\n");
			buffer_progress_bar(&g.v);
			if (g.v.total.files_missing == g.v.total.files)
				empty_dir = 1;
		}
		break;
	}

	if (empty_dir == 1 && !findfileext(dir, ".sfv")) {

		d_log("postdel: Removing all files and directories created by zipscript\n");
		removecomplete(g.v.misc.release_type);
		if (fileexists(g.l.sfv))
			delete_sfv(g.l.sfv, &g.v);
		if (g.l.nfo_incomplete)
			unlink(g.l.nfo_incomplete);
		if (g.l.incomplete)
			unlink(g.l.incomplete);

		if (fileexists("file_id.diz"))
			unlink("file_id.diz");
		if (fileexists(g.l.race))
			unlink(g.l.race);
		if (fileexists(g.l.sfv))
			unlink(g.l.sfv);
		if (fileexists(g.l.sfvbackup))
			unlink(g.l.sfvbackup);
		if (fileexists(g.l.leader))
			unlink(g.l.leader);

		g.v.misc.release_type = ftype;
		move_progress_bar(1, &g.v, g.ui, g.gi);
		
#if (remove_dot_files_on_delete == TRUE)
		removedotfiles(dir);
#endif

	}

	if (_incomplete == 1 && g.v.total.files > 0) {

		g.v.misc.data_completed = 0;
		getrelname(&g);
		if (g.l.nfo_incomplete) {
			if (findfileext(dir, ".nfo")) {
				d_log("postdel: Removing missing-nfo indicator (if any)\n");
				remove_nfo_indicator(&g);
			} else if (matchpath(check_for_missing_nfo_dirs, g.l.path) && (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs)) {
				if (!g.l.in_cd_dir) {
					d_log("postdel: Creating missing-nfo indicator %s.\n", g.l.nfo_incomplete);
					if (create_incomplete_nfo()) {
						d_log("postdel: Warning: create_incomplete_nfo() returned something.\n");
					}
				} else {
					
					if (findfileextparent(parent, ".nfo")) {
						d_log("postdel: Removing missing-nfo indicator (if any)\n");
						remove_nfo_indicator(&g);
					} else {
						d_log("postdel: Creating missing-nfo indicator (base) %s.\n", g.l.nfo_incomplete);
		 				/* This is not pretty, but should be functional. */
						if ((inc_point[0] = find_last_of(g.l.path, "/")) != g.l.path)
							*inc_point[0] = '\0';
						if ((inc_point[1] = find_last_of(g.v.misc.release_name, "/")) != g.v.misc.release_name)
							*inc_point[1] = '\0';
						if (create_incomplete_nfo()) {
							d_log("postdel: Warning: create_incomplete_nfo() returned something.\n");
						}
						if (*inc_point[0] == '\0')
							*inc_point[0] = '/';
						if (*inc_point[1] == '\0')
							*inc_point[1] = '/';
					}
				}
			}
		}
#if (create_missing_sample_link)
		if (g.l.sample_incomplete) {
			if (findfileextsub(".", sample_types, sample_list) || matchpartialdirname(missing_sample_check_ignore_list, g.v.misc.release_name, missing_sample_check_ignore_dividers)) {
				d_log("postdel: Removing missing-sample indicator (if any)\n");
				remove_sample_indicator(&g);
			} else if (matchpath(check_for_missing_sample_dirs, g.l.path) && (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs)) {
				if (!g.l.in_cd_dir) {
					d_log("postdel: Creating missing-sample indicator %s.\n", g.l.sample_incomplete);
					if (create_incomplete_sample()) {
						d_log("postdel: Warning: create_incomplete_sample() returned something.\n");
					}
				} else {
					if (findfileextsub("..", sample_types, sample_list)) {
						d_log("postdel: Removing missing-sample indicator (if any)\n");
						remove_sample_indicator(&g);
					} else {
						d_log("postdel: Creating missing-sample indicator (base) %s.\n", g.l.sample_incomplete);

						/* This is not pretty, but should be functional. */
						if ((inc_point[0] = find_last_of(g.l.path, "/")) != g.l.path)
							*inc_point[0] = '\0';
						if ((inc_point[1] = find_last_of(g.v.misc.release_name, "/")) != g.v.misc.release_name)
							*inc_point[1] = '\0';
						if (create_incomplete_sample()) {
							d_log("postdel: Warning: create_incomplete_sample() returned something.\n");
						}
						if (*inc_point[0] == '\0')
							*inc_point[0] = '/';
						if (*inc_point[1] == '\0')
							*inc_point[1] = '/';
					}
				}
			}
		}
#endif
		if (!matchpath(group_dirs, g.l.path) || create_incomplete_links_in_group_dirs) {
			d_log("postdel: Creating incomplete indicator\n");
			d_log("postdel:    incomplete: '%s', path: '%s'\n", g.l.incomplete, g.l.path);
			if (create_incomplete()) {
				d_log("postdel: Warning: create_incomplete() returned something.\n");
			}
		}
		d_log("postdel: Moving progress bar (%d)\n", g.v.misc.release_type);
		g.v.misc.release_type = ftype;
		move_progress_bar(0, &g.v, g.ui, g.gi);
	}
	
	d_log("postdel: Releasing memory and removing lock.\n");
	closedir(dir);
	closedir(parent);
	updatestats_free(&g);
	ng_free(target);
	ng_free(g.l.race);
	ng_free(g.l.sfv);
	ng_free(g.l.sfvbackup);
	ng_free(g.l.leader);

	remove_lock(&g.v);

	if (empty_dir) {
		d_log("postdel: Removing missing-sfv indicator (if any)\n");
		unlink(g.l.sfv_incomplete);
		if (fileexists(".debug") && remove_dot_debug_on_delete)
			unlink(".debug");
	}

	d_log("postdel: Exit 0\n");

	return 0;
}
Beispiel #5
0
/*
 * Modified	: 01.16.2002 Author	: Dark0n3
 *
 * Description	: Goes through all untested files and compares crc of file
 * with one that is reported in sfv.
 *
 */
void
testfiles(struct LOCATIONS *locations, struct VARS *raceI, int rstatus)
{
	int		fd, lret, count;
	char		*ext, target[PATH_MAX], real_file[PATH_MAX];
	FILE		*racefile;
	unsigned int	Tcrc;
	struct stat	filestat;
	time_t		timenow;

	RACEDATA	rd;

	if ((fd = open(locations->race, O_CREAT | O_RDWR, 0666)) == -1) {
		if (errno != EEXIST) {
			d_log("testfiles: open(%s): %s\n", locations->race, strerror(errno));
			remove_lock(raceI);
			exit(EXIT_FAILURE);
		}
	}

	close(fd);
	if (!(racefile = fopen(locations->race, "r+"))) {
		d_log("testfiles: fopen(%s) failed\n", locations->race);
		exit(EXIT_FAILURE);
	}

	strlcpy(real_file, raceI->file.name, sizeof(real_file));

	if (rstatus)
		printf("\n");

	count = 0;
	rd.status = F_NOTCHECKED;
	while ((fread(&rd, sizeof(RACEDATA), 1, racefile))) {
		if (!update_lock(raceI, 1, 0)) {
			d_log("testfiles: Lock is suggested removed. Will comply and exit\n");
			remove_lock(raceI);
			fclose(racefile);
			exit(EXIT_FAILURE);
		}
		ext = find_last_of(raceI->file.name, ".");
		if (*ext == '.')
			ext++;
		strlcpy(raceI->file.name, rd.fname, NAME_MAX);
		Tcrc = readsfv(locations->sfv, raceI, 0);
		timenow = time(NULL);
		stat(rd.fname, &filestat);
		if (fileexists(rd.fname)) {
			d_log("testfiles: Processing %s\n", rd.fname);
			if (S_ISDIR(filestat.st_mode))
				rd.status = F_IGNORED;
			else if (rd.crc32 != 0 && Tcrc == rd.crc32)
				rd.status = F_CHECKED;
			else if (rd.crc32 != 0 && strcomp(ignored_types, ext))
				rd.status = F_IGNORED;
			else if (rd.crc32 != 0 && Tcrc == 0 && (strcomp(allowed_types, ext) && !matchpath(allowed_types_exemption_dirs, locations->path)))
				rd.status = F_IGNORED;
			else if ((rd.crc32 != 0) && (Tcrc != rd.crc32) &&
					  (strcomp(allowed_types, ext) &&
					   !matchpath(allowed_types_exemption_dirs, locations->path)))
				rd.status = F_IGNORED;
			else if ((rd.crc32 == 0) && strcomp(allowed_types, ext))
				rd.status = F_IGNORED;
			else if ((timenow == filestat.st_ctime) && (filestat.st_mode & 0111)) {
				d_log("testfiles: Looks like this file (%s) is in the process of being uploaded. Ignoring.\n", rd.fname);
				rd.status = F_IGNORED;
				create_missing(rd.fname, raceI);
			}
		} else if (snprintf(target, sizeof(target), "%s.bad", rd.fname) > 4 && fileexists(target)) {
       	                d_log("testfiles: File doesnt exist (%s), bad version of it does, keeping it marked as bad.\n", rd.fname);
			rd.status = F_BAD;
			if (rstatus)
				printf("File: %s BAD!\n", rd.fname);
		} else {
                        d_log("testfiles: File doesnt exist (%s), marking as missing.\n", rd.fname);
			rd.status = F_MISSING;
			if (rstatus)
				printf("File: %s MISSING!\n", rd.fname);
			remove_from_race(locations->race, rd.fname, raceI);
			--count;
		}

		if (rd.status == F_MISSING || rd.status == F_NOTCHECKED) {
			if (rd.status == F_NOTCHECKED) {
				d_log("testfiles: Marking file (%s) as bad and removing it.\n", rd.fname);
				mark_as_bad(rd.fname);
				if (rd.fname)
					unlink(rd.fname);
				rd.status = F_BAD;
				if (rstatus)
					printf("File: %s FAILED!\n", rd.fname);

			}
#if ( create_missing_files )
			if (Tcrc != 0)
				create_missing(rd.fname, raceI);
#endif

#if (enable_unduper_script == TRUE)
			if (!fileexists(unduper_script)) {
				d_log("Failed to undupe '%s' - '%s' does not exist.\n", rd.fname, unduper_script);
			} else {
				sprintf(target, unduper_script " \"%s\"", rd.fname);
				if (execute(target) == 0)
					d_log("testfiles: undupe of %s successful (%s).\n", rd.fname, target);
				else
					d_log("testfiles: undupe of %s failed (%s).\n", rd.fname, target);
			}
#endif
		}

		if (rd.status != F_MISSING) {
			if ((lret = fseek(racefile, sizeof(RACEDATA) * count, SEEK_SET)) == -1) {
				d_log("testfiles: fseek: %s\n", strerror(errno));
				fclose(racefile);
				remove_lock(raceI);
				exit(EXIT_FAILURE);
			}
			if (fwrite(&rd, sizeof(RACEDATA), 1, racefile) == 0)
				d_log("testfiles: write failed: %s\n", strerror(errno));

			if (rd.status != F_BAD && !((timenow == filestat.st_ctime) && (filestat.st_mode & 0111)))
				unlink_missing(rd.fname);
		}
		++count;
	}
	strlcpy(raceI->file.name, real_file, strlen(real_file)+1);
	raceI->total.files = raceI->total.files_missing = 0;
	fclose(racefile);
	d_log("testfiles: finished checking\n");
}