Beispiel #1
0
// parse a project's app_info.xml (anonymous platform) file
//
int CLIENT_STATE::parse_app_info(PROJECT* p, FILE* in) {
    char buf[256], path[MAXPATHLEN];
    MIOFILE mf;
    mf.init_file(in);
    XML_PARSER xp(&mf);

    while (!xp.get_tag()) {
        if (xp.match_tag("app_info")) continue;
        if (xp.match_tag("/app_info")) {
            notices.remove_notices(p, REMOVE_APP_INFO_MSG);
            return 0;
        }
        if (xp.match_tag("file_info") || xp.match_tag("file")) {
            FILE_INFO* fip = new FILE_INFO;
            if (fip->parse(xp)) {
                delete fip;
                continue;
            }
            if (!fip->download_urls.empty() || !fip->upload_urls.empty()) {
                msg_printf(p, MSG_INFO,
                    "Can't specify URLs in app_info.xml"
                );
                delete fip;
                continue;
            }
            if (link_file_info(p, fip)) {
                delete fip;
                continue;
            }
            // check that the file is actually there
            //
            get_pathname(fip, path, sizeof(path));
            if (!boinc_file_exists(path)) {
                safe_strcpy(buf,
                    _("File referenced in app_info.xml does not exist: ")
                );
                strcat(buf, fip->name);
                msg_printf(p, MSG_USER_ALERT, "%s", buf);
                delete fip;
                continue;
            }
            fip->status = FILE_PRESENT;
            fip->anonymous_platform_file = true;
            file_infos.push_back(fip);
            continue;
        }
        if (xp.match_tag("app")) {
            APP* app = new APP;
            if (app->parse(xp)) {
                delete app;
                continue;
            }
            if (lookup_app(p, app->name)) {
                delete app;
                continue;
            }
            link_app(p, app);
            apps.push_back(app);
            continue;
        }
        if (xp.match_tag("app_version")) {
            APP_VERSION* avp = new APP_VERSION;
            if (avp->parse(xp)) {
                delete avp;
                continue;
            }
            if (cc_config.dont_use_vbox && strstr(avp->plan_class, "vbox")) {
                msg_printf(p, MSG_INFO,
                    "skipping vbox app in app_info.xml; vbox disabled in cc_config.xml"
                );
                delete avp;
                continue;
            }
            if (strlen(avp->platform) == 0) {
                safe_strcpy(avp->platform, get_primary_platform());
            }
            if (link_app_version(p, avp)) {
                delete avp;
                continue;
            }
            app_versions.push_back(avp);
            continue;
        }
        if (log_flags.unparsed_xml) {
            msg_printf(p, MSG_INFO,
                "Unparsed line in app_info.xml: %s",
                xp.parsed_tag
            );
        }
    }
    return ERR_XML_PARSE;
}
Beispiel #2
0
// parse a scheduler reply.
// Some of the items go into the SCHEDULER_REPLY object.
// Others are copied straight to the PROJECT
//
int SCHEDULER_REPLY::parse(FILE* in, PROJECT* project) {
    char buf[256], msg_buf[1024], pri_buf[256], attr_buf[256];
    int retval;
    MIOFILE mf;
    XML_PARSER xp(&mf);
    std::string delete_file_name;

    mf.init_file(in);
    bool found_start_tag = false, btemp;
    double cpid_time = 0;

    clear();
    safe_strcpy(host_venue, project->host_venue);
        // the project won't send us a venue if it's doing maintenance
        // or doesn't check the DB because no work.
        // Don't overwrite the host venue in that case.
    sr_feeds.clear();
    trickle_up_urls.clear();

    if (!project->anonymous_platform) {
        for (int i=0; i<MAX_RSC; i++) {
            project->no_rsc_apps[i] = false;
        }
    }

    // First line should either be tag (HTTP 1.0) or
    // hex length of response (HTTP 1.1)
    //
    while (!xp.get_tag(attr_buf, sizeof(attr_buf))) {
        if (!found_start_tag) {
            if (xp.match_tag("scheduler_reply")) {
                found_start_tag = true;
            }
            continue;
        }
        if (xp.match_tag("/scheduler_reply")) {

            // update statistics after parsing the scheduler reply
            // add new record if vector is empty or we have a new day
            //
            if (project->statistics.empty() || project->statistics.back().day!=dday()) {
                project->trim_statistics();
                DAILY_STATS nds;
                project->statistics.push_back(nds);
            }
            DAILY_STATS& ds = project->statistics.back();
            ds.day=dday();
            ds.user_total_credit=project->user_total_credit;
            ds.user_expavg_credit=project->user_expavg_credit;
            ds.host_total_credit=project->host_total_credit;
            ds.host_expavg_credit=project->host_expavg_credit;

            project->write_statistics_file();

            if (cpid_time) {
                project->cpid_time = cpid_time;
            } else {
                project->cpid_time = project->user_create_time;
            }
            if (project->dont_use_dcf) {
                project->duration_correction_factor = 1;
            }
            return 0;
        }
        else if (xp.parse_str("project_name", project->project_name, sizeof(project->project_name))) {
            continue;
        }
        else if (xp.parse_str("master_url", master_url, sizeof(master_url))) {
            continue;
        }
        else if (xp.parse_str("symstore", project->symstore, sizeof(project->symstore))) continue;
        else if (xp.parse_str("user_name", project->user_name, sizeof(project->user_name))) continue;
        else if (xp.parse_double("user_total_credit", project->user_total_credit)) continue;
        else if (xp.parse_double("user_expavg_credit", project->user_expavg_credit)) continue;
        else if (xp.parse_double("user_create_time", project->user_create_time)) continue;
        else if (xp.parse_double("cpid_time", cpid_time)) continue;
        else if (xp.parse_str("team_name", project->team_name, sizeof(project->team_name))) continue;
        else if (xp.parse_int("hostid", hostid)) continue;
        else if (xp.parse_double("host_total_credit", project->host_total_credit)) continue;
        else if (xp.parse_double("host_expavg_credit", project->host_expavg_credit)) continue;
        else if (xp.parse_str("host_venue", host_venue, sizeof(host_venue))) continue;
        else if (xp.parse_double("host_create_time", project->host_create_time)) continue;
        else if (xp.parse_double("request_delay", request_delay)) continue;
        else if (xp.parse_double("next_rpc_delay", next_rpc_delay)) continue;
        else if (xp.match_tag("global_preferences")) {
            retval = dup_element_contents(
                xp.f->f,
                "</global_preferences>",
                &global_prefs_xml
            );
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse global prefs in scheduler reply: %s",
                    boincerror(retval)
                );
                return retval;
            }
        } else if (xp.match_tag("project_preferences")) {
            retval = dup_element_contents(
                xp.f->f,
                "</project_preferences>",
                &project_prefs_xml
            );
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse project prefs in scheduler reply: %s",
                    boincerror(retval)
                );
                return retval;
            }
        } else if (xp.match_tag("gui_urls")) {
            std::string foo;
            retval = copy_element_contents(xp.f->f, "</gui_urls>", foo);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse GUI URLs in scheduler reply: %s",
                    boincerror(retval)
                );
                return retval;
            }
            project->gui_urls = "<gui_urls>\n"+foo+"</gui_urls>\n";
        } else if (xp.match_tag("code_sign_key")) {
            retval = dup_element_contents(
                xp.f->f,
                "</code_sign_key>",
                &code_sign_key
            );
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse code sign key in scheduler reply: %s",
                    boincerror(retval)
                );
                return ERR_XML_PARSE;
            }
            strip_whitespace(code_sign_key);
        } else if (xp.match_tag("code_sign_key_signature")) {
            retval = dup_element_contents(
                xp.f->f,
                "</code_sign_key_signature>",
                &code_sign_key_signature
            );
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse code sign key signature in scheduler reply: %s",
                    boincerror(retval)
                );
                return ERR_XML_PARSE;
            }
        } else if (xp.match_tag("app")) {
            APP app;
            retval = app.parse(xp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse application in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                apps.push_back(app);
            }
        } else if (xp.match_tag("file_info")) {
            FILE_INFO file_info;
            retval = file_info.parse(xp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse file info in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                file_infos.push_back(file_info);
            }
        } else if (xp.match_tag("app_version")) {
            APP_VERSION av;
            retval = av.parse(xp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse application version in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                app_versions.push_back(av);
            }
        } else if (xp.match_tag("workunit")) {
            WORKUNIT wu;
            retval = wu.parse(xp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse workunit in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                workunits.push_back(wu);
            }
        } else if (xp.match_tag("result")) {
            RESULT result;      // make sure this is here so constructor
                                // gets called each time
            retval = result.parse_server(xp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse task in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                results.push_back(result);
            }
        } else if (xp.match_tag("result_ack")) {
            RESULT result;
            retval = result.parse_name(xp, "/result_ack");
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse ack in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                result_acks.push_back(result);
            }
        } else if (xp.match_tag("result_abort")) {
            RESULT result;
            retval = result.parse_name(xp, "/result_abort");
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse result abort in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                result_abort.push_back(result);
            }
        } else if (xp.match_tag("result_abort_if_not_started")) {
            RESULT result;
            retval = result.parse_name(xp, "/result_abort_if_not_started");
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't parse result abort-if-not-started in scheduler reply: %s",
                    boincerror(retval)
                );
            } else {
                result_abort_if_not_started.push_back(result);
            }
        } else if (xp.parse_string("delete_file_info", delete_file_name)) {
            file_deletes.push_back(delete_file_name);
        } else if (xp.parse_str("message", msg_buf, sizeof(msg_buf))) {
            parse_attr(attr_buf, "priority", pri_buf, sizeof(pri_buf));
            USER_MESSAGE um(msg_buf, pri_buf);
            messages.push_back(um);
            continue;
        } else if (xp.parse_bool("message_ack", message_ack)) {
            continue;
        } else if (xp.parse_bool("project_is_down", project_is_down)) {
            continue;
        } else if (xp.parse_str("email_hash", project->email_hash, sizeof(project->email_hash))) {
            continue;
        } else if (xp.parse_str("cross_project_id", project->cross_project_id, sizeof(project->cross_project_id))) {
            continue;
        } else if (xp.parse_str("external_cpid", project->external_cpid, sizeof(project->external_cpid))) {
            continue;
        } else if (xp.match_tag("trickle_down")) {
            retval = gstate.handle_trickle_down(project, in);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "handle_trickle_down failed: %s", boincerror(retval)
                );
            }
            continue;
        } else if (xp.parse_bool("non_cpu_intensive", project->non_cpu_intensive)) {
            continue;
        } else if (xp.parse_bool("ended", project->ended)) {
            continue;
        } else if (xp.parse_bool("no_cpu_apps", btemp)) {
            if (!project->anonymous_platform) {
                handle_no_rsc_apps("CPU", project, btemp);
            }
            continue;

        // deprecated syntax
        } else if (xp.parse_bool("no_cuda_apps", btemp)) {
            if (!project->anonymous_platform) {
                handle_no_rsc_apps(GPU_TYPE_NVIDIA, project, btemp);
            }
            continue;
        } else if (xp.parse_bool("no_ati_apps", btemp)) {
            if (!project->anonymous_platform) {
                handle_no_rsc_apps(GPU_TYPE_ATI, project, btemp);
            }
            continue;

        } else if (xp.parse_str("no_rsc_apps", buf, sizeof(buf))) {
            if (!project->anonymous_platform) {
                handle_no_rsc_apps(buf, project, true);
            }
            continue;
        } else if (xp.parse_bool("verify_files_on_app_start", project->verify_files_on_app_start)) {
            continue;
        } else if (xp.parse_bool("send_full_workload", send_full_workload)) {
            continue;
        } else if (xp.parse_bool("dont_use_dcf", dont_use_dcf)) {
            continue;
        } else if (xp.parse_int("send_time_stats_log", send_time_stats_log)){
            continue;
        } else if (xp.parse_int("send_job_log", send_job_log)) {
            continue;
        } else if (xp.parse_int("scheduler_version", scheduler_version)) {
            continue;
        } else if (xp.match_tag("project_files")) {
            retval = parse_project_files(xp, project_files);
#ifdef ENABLE_AUTO_UPDATE
        } else if (xp.match_tag("auto_update")) {
            retval = auto_update.parse(xp);
            if (!retval) auto_update.present = true;
#endif
        } else if (xp.match_tag("rss_feeds")) {
            got_rss_feeds = true;
            parse_rss_feed_descs(xp, sr_feeds);
            continue;
        } else if (xp.match_tag("trickle_up_urls")) {
            parse_trickle_up_urls(xp, trickle_up_urls);
            continue;
        } else if (xp.parse_int("userid", project->userid)) {
            continue;
        } else if (xp.parse_int("teamid", project->teamid)) {
            continue;
        } else if (xp.parse_double("desired_disk_usage", project->desired_disk_usage)) {
            continue;
        } else {
            if (log_flags.unparsed_xml) {
                msg_printf(project, MSG_INFO,
                    "[unparsed_xml] SCHEDULER_REPLY::parse(): unrecognized %s\n",
                    xp.parsed_tag
                );
            }
        }
    }
    if (found_start_tag) {
        msg_printf(project, MSG_INTERNAL_ERROR, "No close tag in scheduler reply");
    } else {
        msg_printf(project, MSG_INTERNAL_ERROR, "No start tag in scheduler reply");
    }

    return ERR_XML_PARSE;
}
Beispiel #3
0
bool
FLDR::FProcess()
	{
	bool			fStat;
	char			szPath[MAX_PATH];
	char			szName[MAX_PATH];
	char			szMsg[cchLogMsgMax];
	HANDLE			hfind;
	WIN32_FIND_DATA	ffdt;

	fStat = fFalse;

	if (CchOfSz(szPathSrc) == 0) {
		apst.SetErrLast(errAppNoSrcPath);
		return fStat;
	}

	if (CchOfSz(szPathDst) == 0) {
		apst.SetErrLast(errAppNoDstPath);
		return fStat;
	}

	/* Determine whether we are walking the source tree or the destinaton tree,
	** and initialize szPath appropriately.
	*/
	if (apst.FUpdateDst()) {
		/* If we are performing an update operation, we need to walk the
		** source tree.
		*/
		SzCopy(szPath, szPathSrc);
	}
	else if (apst.FTrimDst()) {
		/* When deleting files from the destination tree that aren't in the
		** source tree, we need to walk the destination tree.
		*/
		SzCopy(szPath, szPathDst);
	}
	else if (apst.FExtractDst()) {
		/* When performing an extract operation, we need to walk the
		** destination tree.
		*/
		SzCopy(szPath, szPathDst);
	}
	else {
		/* Internal error. We shouldn't be able to get here without one
		** of the above conditions being true.
		*/
		apst.SetErrLast(errInternalError);
		return fStat;
	}

	if ((CchOfSz(szPath)+CchOfSz(szFindAll)) > MAX_PATH) {
		/* The path name is too long to process.
		*/
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\n", szPath);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		return fStat;
	}	
	//SzAppendPathSeparator(SzEnd(szPath));
	SzAppend(szPath, szFindAll);

	if ((hfind = FindFirstFile(szPath, &ffdt)) == INVALID_HANDLE_VALUE) {
		apst.SetErrLast(errFileSystem);
		if (apst.ErrLast() == ERROR_PATH_NOT_FOUND) {
			sprintf_s(szMsg, cchLogMsgMax, "Path not found: %s\n", szPath);
			app.PrintMessage(idMsgError, szMsg);
			cmdx.LogMessage(idMsgError, szMsg);
		}
		return fStat;
	}
	
	fldrmg.BeginDirectory();

	do {
		/* Check for system files, and only process them if the parameter
		** was set on the command line.
		*/
		if ((ffdt.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) {
			if (!apst.FDoSystem()) {
				continue;
			}
		}

		/* Check for hidden files and only process them if the parameter
		** was set on the command line.
		*/
		if ((ffdt.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) {
			if (!apst.FDoHidden()) {
				continue;
			}
		}

		/* Check if this is a directory.
		*/
		if ((ffdt.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
			/* Is thie folder being excluded.
			*/
			if (fldrmg.FMatchXclDir(ffdt.cFileName)) {
				if (apst.FPrintXclDir() || apst.FLogXclDir()) {
					SzCopy(szName, szPathSrc);
					SzAppendPathSeparator(SzEnd(szName));					
					if (CchOfSz(szName)+CchOfSz(ffdt.cFileName) > MAX_PATH) {
						apst.SetStProg(stPathLength);
						sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, ffdt.cFileName);
						app.PrintMessage(idMsgSkipDir, szMsg);
						cmdx.LogMessage(idMsgSkipDir, szMsg);
						continue;
					}
					SzAppend(szName, ffdt.cFileName);					
					sprintf_s(szMsg, cchLogMsgMax, "Skipping: %s\n", szName);
					app.PrintMessage(idMsgSkipDir, szMsg);
					cmdx.LogMessage(idMsgSkipDir, szMsg);
				}
				fldrmg.DirExcluded();
				continue;
			}
			/* Add it to the list of folders to be processed.
			*/
			if (!FProcessDirectory(ffdt.cFileName)) {
				break;
			}
		}
		else {
			/* Process the file
			*/
			if (fldrmg.FMatchXclExt(SzExtOfName(ffdt.cFileName)) || 
			    fldrmg.FMatchXclFile(ffdt.cFileName)) {
			    if (apst.FPrintXclFile()|| apst.FLogXclFile()) {
					SzCopy(szName, szPathSrc);
					SzAppendPathSeparator(SzEnd(szName));					
					if (CchOfSz(szName)+CchOfSz(ffdt.cFileName) > MAX_PATH) {
						apst.SetStProg(stPathLength);
						sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, ffdt.cFileName);
						app.PrintMessage(idMsgSkipDir, szMsg);
						cmdx.LogMessage(idMsgSkipDir, szMsg);
						continue;
					}
					SzAppend(szName, ffdt.cFileName);					
					sprintf_s(szMsg, cchLogMsgMax, "Excluding: %s\n", szName);
					app.PrintMessage(idMsgExclFile, szMsg);
					cmdx.LogMessage(idMsgExclFile, szMsg);
				}
				fldrmg.FileExcluded();
				continue;
			}
			if (!FProcessFile(ffdt.cFileName)) {
				break;
			}
		}

	} while (FindNextFile(hfind, &ffdt) != 0);
	
	fldrmg.EndDirectory();

	if (GetLastError() == ERROR_NO_MORE_FILES) {
		fStat = fTrue;
	}

	FindClose(hfind);
	return fStat;
}
Beispiel #4
0
int CLIENT_STATE::parse_state_file_aux(const char* fname) {
    PROJECT *project=NULL;
    int retval=0;
    string stemp;

    FILE* f = fopen(fname, "r");
    if (!f) return ERR_FOPEN;
    MIOFILE mf;
    XML_PARSER xp(&mf);
    mf.init_file(f);
    while (!xp.get_tag()) {
        if (xp.match_tag("/client_state")) {
            break;
        }
        if (xp.match_tag("client_state")) {
            continue;
        }
        if (xp.match_tag("project")) {
            PROJECT temp_project;
            retval = temp_project.parse_state(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR, "Can't parse project in state file");
            } else {
#ifdef SIM
                project = new PROJECT;
                *project = temp_project;
                projects.push_back(project);
#else
                project = lookup_project(temp_project.master_url);
                if (project) {
                    project->copy_state_fields(temp_project);
                } else {
                    msg_printf(&temp_project, MSG_INTERNAL_ERROR,
                        "Project %s is in state file but no account file found",
                        temp_project.get_project_name()
                    );
                }
#endif
            }
            continue;
        }
        if (xp.match_tag("app")) {
            APP* app = new APP;
            retval = app->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Application %s outside project in state file",
                    app->name
                );
                delete app;
                continue;
            }
            if (project->anonymous_platform) {
                delete app;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse application in state file"
                );
                delete app;
                continue;
            }
            retval = link_app(project, app);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't handle application %s in state file",
                    app->name
                );
                delete app;
                continue;
            }
            apps.push_back(app);
            continue;
        }
        if (xp.match_tag("file_info") || xp.match_tag("file")) {
            FILE_INFO* fip = new FILE_INFO;
            retval = fip->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "File info outside project in state file"
                );
                delete fip;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't handle file info in state file"
                );
                delete fip;
                continue;
            }
            retval = link_file_info(project, fip);
            if (project->anonymous_platform && retval == ERR_NOT_UNIQUE) {
                delete fip;
                continue;
            }
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't handle file info %s in state file",
                    fip->name
                );
                delete fip;
                continue;
            }
            file_infos.push_back(fip);
#ifndef SIM
            // If the file had a failure before,
            // don't start another file transfer
            //
            int failnum;
            if (fip->had_failure(failnum)) {
                if (fip->pers_file_xfer) {
                    delete fip->pers_file_xfer;
                    fip->pers_file_xfer = NULL;
                }
            }
            if (fip->pers_file_xfer) {
                retval = fip->pers_file_xfer->init(fip, fip->pers_file_xfer->is_upload);
                if (retval) {
                    msg_printf(project, MSG_INTERNAL_ERROR,
                        "Can't initialize file transfer for %s",
                        fip->name
                    );
                }
                retval = pers_file_xfers->insert(fip->pers_file_xfer);
                if (retval) {
                    msg_printf(project, MSG_INTERNAL_ERROR,
                        "Can't start persistent file transfer for %s",
                        fip->name
                    );
                }
            }
#endif
            continue;
        }
        if (xp.match_tag("app_version")) {
            APP_VERSION* avp = new APP_VERSION;
            retval = avp->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Application version outside project in state file"
                );
                delete avp;
                continue;
            }
            if (project->anonymous_platform) {
                delete avp;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse application version in state file"
                );
                delete avp;
                continue;
            } 
            if (strlen(avp->platform) == 0) {
                safe_strcpy(avp->platform, get_primary_platform());
            } else {
                if (!is_supported_platform(avp->platform)) {
                    // if it's a platform we haven't heard of,
                    // must be that the user tried out a 64 bit client
                    // and then reverted to a 32-bit client.
                    // Let's not throw away the app version and its WUs
                    //
#ifndef SIM
                    msg_printf(project, MSG_INTERNAL_ERROR,
                        "App version has unsupported platform %s; changing to %s",
                        avp->platform, get_primary_platform()
                    );
#endif
                    safe_strcpy(avp->platform, get_primary_platform());
                }
            }
            if (avp->missing_coproc) {
                msg_printf(project, MSG_INFO,
                    "Application uses missing %s GPU",
                    avp->missing_coproc_name
                );
            }
            retval = link_app_version(project, avp);
            if (retval) {
                delete avp;
                continue;
            }
            app_versions.push_back(avp);
            continue;
        }
        if (xp.match_tag("workunit")) {
            WORKUNIT* wup = new WORKUNIT;
            retval = wup->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Workunit outside project in state file"
                );
                delete wup;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse workunit in state file"
                );
                delete wup;
                continue;
            }
            retval = link_workunit(project, wup);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't handle workunit in state file"
                );
                delete wup;
                continue;
            }
            workunits.push_back(wup);
            continue;
        }
        if (xp.match_tag("result")) {
            RESULT* rp = new RESULT;
            retval = rp->parse_state(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Task %s outside project in state file",
                    rp->name
                );
                delete rp;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse task in state file"
                );
                delete rp;
                continue;
            }
            retval = link_result(project, rp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't link task %s in state file",
                    rp->name
                );
                delete rp;
                continue;
            }
            // handle transition from old clients which didn't store result.platform;
            // skip for anon platform
            if (!project->anonymous_platform) {
                if (!strlen(rp->platform) || !is_supported_platform(rp->platform)) {
                    safe_strcpy(rp->platform, get_primary_platform());
                    rp->version_num = latest_version(rp->wup->app, rp->platform);
                }
            }
            rp->avp = lookup_app_version(
                rp->wup->app, rp->platform, rp->version_num, rp->plan_class
            );
            if (!rp->avp) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "No application found for task: %s %d %s; discarding",
                    rp->platform, rp->version_num, rp->plan_class
                );
                delete rp;
                continue;
            }
            if (rp->avp->missing_coproc) {
                msg_printf(project, MSG_INFO,
                    "Missing coprocessor for task %s", rp->name
                );
                rp->coproc_missing = true;
            }
            rp->wup->version_num = rp->version_num;
            results.push_back(rp);
            continue;
        }
        if (xp.match_tag("project_files")) {
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Project files outside project in state file"
                );
                xp.skip_unexpected();
                continue;
            }
            parse_project_files(xp, project->project_files);
            project->link_project_files();
            continue;
        }
        if (xp.match_tag("host_info")) {
#ifdef SIM
            retval = host_info.parse(xp, false);
            coprocs = host_info.coprocs;
            coprocs.bound_counts();
#else
            retval = host_info.parse(xp, true);
#endif
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse host info in state file"
                );
            }
            continue;
        }
        if (xp.match_tag("time_stats")) {
            retval = time_stats.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse time stats in state file"
                );
            }
            continue;
        }
        if (xp.match_tag("net_stats")) {
            retval = net_stats.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse network stats in state file"
                );
            }
            continue;
        }
        if (xp.match_tag("active_task_set")) {
            retval = active_tasks.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse active tasks in state file"
                );
            }
            continue;
        }
        if (xp.parse_string("platform_name", statefile_platform_name)) {
            continue;
        }
        if (xp.parse_string("alt_platform", stemp)) {
            continue;
        }
        if (xp.parse_int("user_run_request", retval)) {
            cpu_run_mode.set(retval, 0);
            continue;
        }
        if (xp.parse_int("user_run_prev_request", retval)) {
            cpu_run_mode.set_prev(retval);
            continue;
        }
        if (xp.parse_int("user_gpu_request", retval)) {
            gpu_run_mode.set(retval, 0);
            continue;
        }
        if (xp.parse_int("user_gpu_prev_request", retval)) {
            gpu_run_mode.set_prev(retval);
            continue;
        }
        if (xp.parse_int("user_network_request", retval)) {
            network_run_mode.set(retval, 0);
            continue;
        }
        if (xp.parse_int("core_client_major_version", old_major_version)) {
            continue;
        }
        if (xp.parse_int("core_client_minor_version", old_minor_version)) {
            continue;
        }
        if (xp.parse_int("core_client_release", old_release)) {
            continue;
        }
        if (xp.parse_str("language", language, sizeof(language))) {
            continue;
        }
        if (xp.match_tag("proxy_info")) {
            retval = gui_proxy_info.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse proxy info in state file"
                );
            }
            continue;
        }
        if (xp.parse_str("host_venue", main_host_venue, sizeof(main_host_venue))) {
            continue;
        }
        if (xp.parse_double("new_version_check_time", new_version_check_time)) {
            continue;
        }
        if (xp.parse_double("all_projects_list_check_time", all_projects_list_check_time)) {
            continue;
        }
        if (xp.parse_string("newer_version", newer_version)) {
            continue;
        }
#ifdef ENABLE_AUTO_UPDATE
        if (xp.match_tag("auto_update")) {
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "auto update outside project in state file"
                );
                xp.skip_unexpected();
                continue;
            }
            if (!auto_update.parse(xp) && !auto_update.validate_and_link(project)) {
                auto_update.present = true;
            }
            continue;
        }
#endif
        if (log_flags.unparsed_xml) {
            msg_printf(0, MSG_INFO,
                "[unparsed_xml] state_file: unrecognized: %s",
                xp.parsed_tag
            );
        }
        xp.skip_unexpected();
    }
    sort_results();
    fclose(f);
    
    // if total resource share is zero, set all shares to 1
    //
    if (projects.size()) {
        unsigned int i;
        double x=0;
        for (i=0; i<projects.size(); i++) {
            x += projects[i]->resource_share;
        }
        if (!x) {
            msg_printf(NULL, MSG_INFO,
                "All projects have zero resource share; setting to 100"
            );
            for (i=0; i<projects.size(); i++) {
                projects[i]->resource_share = 100;
            }
        }
    }
    return 0;
}
Beispiel #5
0
bool
FLDT::FProcessFile(char * szFile)
	{
	bool		fStat;
	char		szSrc[MAX_PATH];
	char		szDst[MAX_PATH];
	char		szMsg[cchLogMsgMax];
	HANDLE		hfindSrc;
	HANDLE		hfindDst;
	WIN32_FIND_DATA	ffdtSrc;
	WIN32_FIND_DATA	ffdtDst;
	DWORD		err;

	fStat = fFalse;
	fldrmg.FileProcessed();

	/* Set up the path and file name for the source file.
	*/
	if ((CchOfSz(szPathSrc)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szSrc, szPathSrc);
	SzAppendPathSeparator(SzEnd(szSrc));
	SzAppend(szSrc, szFile);
	
	/* Set up the path and file name for the destination file.
	*/
	if ((CchOfSz(szPathDst)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetStProg(stPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathDst, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szDst, szPathDst);
	SzAppendPathSeparator(SzEnd(szDst));
	SzAppend(szDst, szFile);
	
	/* Tell the FLDRMG about these path strings to it can keep
	** track of the longest.
	*/
	fldrmg.SetCchPath(CchOfSz(szSrc));
	fldrmg.SetCchPath(CchOfSz(szDst));

	/* Get information about the files to determine which is newer.
	*/
	hfindDst = FindFirstFile(szDst, &ffdtDst);
	FindClose(hfindDst);
	
	hfindSrc = FindFirstFile(szSrc, &ffdtSrc);
	if (hfindSrc == INVALID_HANDLE_VALUE) {
		err = GetLastError();
		if (err == ERROR_FILE_NOT_FOUND) {
			/* The file doesn't exist in the source tree, delete it.
			*/ 
			goto lDeleteFile;
		}
		else if (err = ERROR_PATH_NOT_FOUND) {
			/* The folder that this file is in doesn't exist in the
			** source tree, so we should delete it. Ideally, we would
			** also delete the folder.
			*/
			goto lDeleteFile;
		}
		else {
			/* Some other error is a real error.
			*/
			goto lErrorExit;
		}
	}
	FindClose(hfindDst);
	
	/* We get here if both files exist. Since we're only deleting files
	** in the destination tree that don't exist in the source tree, we
	** don't need to do anything with this file.
	*/
	goto lNoDelete;


	/* We haven't come up with a reason not to copy this file, so
	** the destination file needs to be copied to the extraction tree.
	*/
lDeleteFile:
	if (apst.FPrintFile() || apst.FLogFile()) {
		sprintf_s(szMsg, cchLogMsgMax, "Deleting:  %s\n", szDst);
		app.PrintMessage(idMsgDelFile, szMsg);
		cmdx.LogMessage(idMsgDelFile, szMsg);
	}

	if (!apst.FNoCopyFile()) {
		fldrmg.FileDeleted();
		if (DeleteFile(szDst) == 0) {
			if (GetLastError() == ERROR_ACCESS_DENIED) {
				if (apst.FPrintFile() || apst.FLogFile()) {
					sprintf_s(szMsg, cchLogMsgMax, "Access Denied!\n");
					app.PrintMessage(idMsgError, szMsg);
					cmdx.LogMessage(idMsgError, szMsg);
				}
			}
			else {
				apst.SetErrLast(errFileSystem);
				sprintf_s(szMsg, cchLogMsgMax, "Error copying file: %s\n", szDst);
				app.PrintMessage(idMsgError, szMsg);
				cmdx.LogMessage(idMsgError, szMsg);
				goto lErrorExit;
			}
		}
	}

lNoDelete:
	fStat = fTrue;

lErrorExit:
	apst.FSetSzFileCur(szFile);
	return fStat;
	
}
Beispiel #6
0
bool
FLDT::FProcessDirectory(char * szDir)
	{
	bool		fStat;
	FLDT *		pfldt;
	char 		szSrc[MAX_PATH];
	char 		szDst[MAX_PATH];
	char		szMsg[cchLogMsgMax];

	fStat = fFalse;

	/* Don't add the '.' and '..' directories to the list.
	*/
	if ((CompareSz(szDir, ".") == 0) || (CompareSz(szDir, "..") == 0)) {
		return fTrue;
	}

	/* Set up the destination path string.
	*/
	if ((CchOfSz(szPathDst)+CchOfSz(szDir)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathDst, szDir);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szDst, szPathDst);
	SzAppendPathSeparator(SzEnd(szDst));
	SzAppend(szDst, szDir);
	
	/* Check if this directory is one that is being excluded.
	*/	
	if (fldrmg.FMatchXclPath(szDst)) {
		if (apst.FPrintXclDir()) {
			sprintf_s(szMsg, cchLogMsgMax, "Skipping: %s\n", szDst);
			app.PrintMessage(idMsgExclFile, szDst);
			cmdx.LogMessage(idMsgExclFile, szDst);
		}
		fldrmg.DirExcluded();
		return fTrue;
	}

	/* Set the source path string
	*/
	if ((CchOfSz(szPathSrc)+CchOfSz(szDir)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, szDir);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szSrc, szPathSrc);
	SzAppendPathSeparator(SzEnd(szSrc));
	SzAppend(szSrc, szDir);

	/* Create the new folder object.
	*/
	pfldt = new FLDT;
	if (pfldt == NULL) {
		apst.SetErrLast(errOutOfMemory);
		goto lErrorExit;
	}

	/* Set the path names into the FLDR object and add it to the list
	** of directories to be processed.
	*/
	pfldt->SetPathSrc(szSrc);
	pfldt->SetPathDst(szDst);

	fldrmg.AddPfldr(pfldt);
	fStat = fTrue;

lErrorExit:
	return fStat;
	
}
Beispiel #7
0
bool
FLDX::FProcessFile(char * szFile)
	{
	bool		fStat;
	char		szSrc[MAX_PATH];
	char		szDst[MAX_PATH];
	char		szXtr[MAX_PATH];
	char		szMsg[cchLogMsgMax];
	HANDLE		hfindSrc;
	HANDLE		hfindDst;
	WIN32_FIND_DATA	ffdtSrc;
	WIN32_FIND_DATA	ffdtDst;
	FSIG		fsig;
	bool		fSameSize;
	bool		fSameTime;
	int			dftTime;
	DWORD		sigSrc;
	DWORD		sigDst;
	DWORD		err;

	fStat = fFalse;
	fldrmg.FileProcessed();

	/* Set up the path and file name for the source file.
	*/
	if ((CchOfSz(szPathSrc)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathSrc, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szSrc, szPathSrc);
	SzAppendPathSeparator(SzEnd(szSrc));
	SzAppend(szSrc, szFile);
	
	/* Set up the path and file name for the destination file.
	*/
	if ((CchOfSz(szPathDst)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathDst, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szDst, szPathDst);
	SzAppendPathSeparator(SzEnd(szDst));
	SzAppend(szDst, szFile);
	
	/* Tell the FLDRMG about these path strings to it can keep
	** track of the longest.
	*/
	fldrmg.SetCchPath(CchOfSz(szSrc));
	fldrmg.SetCchPath(CchOfSz(szDst));

	/* Get information about the files to determine which is newer.
	*/
	hfindDst = FindFirstFile(szDst, &ffdtDst);
	FindClose(hfindDst);
	
	hfindSrc = FindFirstFile(szSrc, &ffdtSrc);
	if (hfindSrc == INVALID_HANDLE_VALUE) {
		err = GetLastError();
		if ((err == ERROR_FILE_NOT_FOUND) || (err = ERROR_PATH_NOT_FOUND)) {
			if (apst.FExtractUnique()) {
				/* The file doesn't exist in the source tree. If we are
				** extracting unique files, we need to copy this one.
				*/ 
				goto lCopy;
			}
			else {
				/* If we're not extracting unique files, there's nothing
				** to do.
				*/
				goto lNoCopy;
			}
		}
		else {
			/* Some other error is a real error.
			*/
			goto lErrorExit;
		}
	}
	FindClose(hfindDst);
	
	/* We get here if both files exist. If we're not doing extract
	** files that differ, then get we shouldn't be copying the file.
	*/
	if (!apst.FExtractDiff()) {
		goto lNoCopy;
	}

	/* Compare the file sizes.
	*/
	if ((ffdtSrc.nFileSizeHigh == ffdtDst.nFileSizeHigh) &&
		(ffdtSrc.nFileSizeLow  == ffdtDst.nFileSizeLow)) {
		fSameSize = fTrue;
	}
	else {
		fSameSize = fFalse;
	}

	/* Check if there is a FAT file system involved.
	*/
	if (apst.FSrcFsFat() || apst.FDstFsFat()) {
		/* Either the source or destination are on a FAT file system.
		** modify the times so that they will compare. the NTFS keeps
		** last write time at 10ms resolution, the FAT file system keeps
		** last write time as 2s resolution.
		*/
		ffdtSrc.ftLastWriteTime.dwLowDateTime &= 0xFE000000;
		ffdtDst.ftLastWriteTime.dwLowDateTime &= 0xFE000000;
	}
		
	/* Compare the file times
	** dftTime has the following meaning:
	**		-1	source file older than destination
	**		 0	source file and destination file have same times
	**		 1  source file newer than destination
	*/
	dftTime = CompareFileTime(&(ffdtSrc.ftLastWriteTime), &(ffdtDst.ftLastWriteTime));
	if (dftTime == 0) {
		fSameTime = fTrue;
	}
	else {
		fSameTime = fFalse;
	}

	/* Determine if we need to copy the source file over the destination file.
	*/
	if (apst.FUseSignatures()) {
		if (fSameSize) {
			/* When using file signatures:
			** If they are the same size and  have the same last write time,
			** they are identical, so don't extract this file.
			*/
			if (fSameTime) {
				goto lNoCopy;
			}

			/* When the files are the same size, but have different times,
			** check the signatures to see if they are identical.
			*/
			fsig.FInit(szSrc, fldrmg.CbSigBuf(), fldrmg.PbSigBuf());
			fsig.FGenerate(&sigSrc);
			fsig.Terminate();

			fsig.FInit(szDst, fldrmg.CbSigBuf(), fldrmg.PbSigBuf());
			fsig.FGenerate(&sigDst);
			fsig.Terminate();

			if (sigSrc == sigDst) {
				/* They have the same content, so don't extract the file.
				*/
				goto lNoCopy;
			}

		}
	}
	else {
		/* When not using file signatures:
		** Files that are the same size and have the same date and time
		** don't get copied.
		** If they are different size or have a different date and time,
		** copy the destination file to the extraction tree.
		*/
		if (fSameTime & fSameSize) {
			goto lNoCopy;
		}
	}

	/* We haven't come up with a reason not to copy this file, so
	** the destination file needs to be copied to the extraction tree.
	*/
lCopy:

	/* Make sure that this directory path exists.
	*/
	if (!apst.FNoCopyDir()) {
		fldrmg.DirCreated();
		if (!FCreatePath(szPathXtr)) {
			apst.SetErrLast(errFileSystem);
			sprintf_s(szMsg, cchLogMsgMax, "Error creating folder: %s\n", szPathXtr);
			app.PrintMessage(idMsgError, szMsg);
			cmdx.LogMessage(idMsgError, szMsg);
			goto lErrorExit;
		}
	}
	
	/* Set up the path and file name for the extracted file.
	*/
	if ((CchOfSz(szPathXtr)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathXtr, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szXtr, szPathXtr);	
	SzAppendPathSeparator(SzEnd(szXtr));
	SzAppend(szXtr, szFile);

	fldrmg.SetCchPath(CchOfSz(szXtr));
	
	if (apst.FPrintFile() || apst.FLogFile()) {
		sprintf_s(szMsg, cchLogMsgMax, "Extracting:  %s\n", szDst);
		app.PrintMessage(idMsgExtrFile, szMsg);
		cmdx.LogMessage(idMsgExtrFile, szMsg);
	}

	if (!apst.FNoCopyFile()) {
		fldrmg.FileCopied();
		if (CopyFile(szDst, szXtr, fFalse) == 0) {
			apst.SetErrLast(errFileSystem);
			sprintf_s(szMsg, cchLogMsgMax, "Error copying file: %s\n", szSrc);
			app.PrintMessage(idMsgError, szMsg);
			cmdx.LogMessage(idMsgError, szMsg);
			goto lErrorExit;
		}
	}

lNoCopy:
	fStat = fTrue;

lErrorExit:
	apst.FSetSzFileCur(szFile);
	return fStat;
}
Beispiel #8
0
bool
FLDS::FProcessFile(char * szFile)
	{
	bool		fStat;
	char		szSrc[MAX_PATH];
	char		szDst[MAX_PATH];
	char		szMsg[cchLogMsgMax];
	HANDLE		hfindSrc;
	HANDLE		hfindDst;
	HANDLE		fhDst;
	WIN32_FIND_DATA	ffdtSrc;
	WIN32_FIND_DATA	ffdtDst;
	FSIG		fsig;
	bool		fSameSize;
	bool		fSameTime;
	int			dftTime;
	DWORD		sigSrc;
	DWORD		sigDst;
	DWORD		err;

	fStat = fFalse;
	fldrmg.FileProcessed();

	/* Set up the source file name.
	*/
	if ((CchOfSz(szPathSrc)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathSrc, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szSrc, szPathSrc);
	SzAppendPathSeparator(SzEnd(szSrc));
	SzAppend(szSrc, szFile);
	
	/* Set up the destination file name
	*/
	if ((CchOfSz(szPathDst)+CchOfSz(szFile)+1) >= MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathDst, szFile);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szDst, szPathDst);
	SzAppendPathSeparator(SzEnd(szDst));
	SzAppend(szDst, szFile);

	/* Accumulate the maximum path length.
	*/
	fldrmg.SetCchPath(CchOfSz(szSrc));
	fldrmg.SetCchPath(CchOfSz(szDst));

	/* Get information about the files to determine which is newer.
	*/
	hfindSrc = FindFirstFile(szSrc, &ffdtSrc);
	FindClose(hfindSrc);
	hfindDst = FindFirstFile(szDst, &ffdtDst);
	if (hfindDst == INVALID_HANDLE_VALUE) {
		err = GetLastError();
		if (err == ERROR_FILE_NOT_FOUND) { 
			goto lCopy;
		}
		else if (apst.FNoCopyDir() && (err == ERROR_PATH_NOT_FOUND)) {
			goto lNoCopy;
		}
		else {
			apst.SetErrLast(errFileSystem);
			goto lErrorExit;
		}
	}
	FindClose(hfindDst);

	/* Compare the file sizes.
	*/
	if ((ffdtSrc.nFileSizeHigh == ffdtDst.nFileSizeHigh) &&
		(ffdtSrc.nFileSizeLow  == ffdtDst.nFileSizeLow)) {
		fSameSize = fTrue;
	}
	else {
		fSameSize = fFalse;
	}

	/* Check if there is a FAT file system involved.
	*/
	if (apst.FSrcFsFat() || apst.FDstFsFat()) {
		/* Either the source or destination are on a FAT file system.
		** modify the times so that they will compare. the NTFS keeps
		** last write time at 10ms resolution, the FAT file system keeps
		** last write time as 2s resolution.
		*/
		ffdtSrc.ftLastWriteTime.dwLowDateTime &= 0xFE000000;
		ffdtDst.ftLastWriteTime.dwLowDateTime &= 0xFE000000;
	}
		
	/* Compare the file times
	** dftTime has the following meaning:
	**		-1	source file older than destination
	**		 0	source file and destination file have same times
	**		 1  source file newer than destination
	*/
	dftTime = CompareFileTime(&(ffdtSrc.ftLastWriteTime), &(ffdtDst.ftLastWriteTime));
	if (dftTime == 0) {
		fSameTime = fTrue;
	}
	else {
		fSameTime = fFalse;
	}

	/* Determine if we need to copy the source file over the destination file.
	*/
	if (apst.FUseSignatures()) {
		if (fSameSize) {
			/* When using file signatures:
			** If they are the same size and  have the same last write time,
			** they are identical, so don't copy.
			*/
			if (fSameTime) {
				goto lNoCopy;
			}

			/* When the files are the same size, but have different times,
			** check the signatures to see if they are identical.
			*/
			fsig.FInit(szSrc, fldrmg.CbSigBuf(), fldrmg.PbSigBuf());
			fsig.FGenerate(&sigSrc);
			fsig.Terminate();

			fsig.FInit(szDst, fldrmg.CbSigBuf(), fldrmg.PbSigBuf());
			fsig.FGenerate(&sigDst);
			fsig.Terminate();

			if (sigSrc == sigDst) {
				/* They have the same content. Update the destination file
				** to have the same times as the source file.
				*/
				goto lSetTime;
			}

			/* They don't have the same content, so check the last write
			** times to see whether or not to copy the source file.
			*/
			if (dftTime <= 0) {
				goto lNoCopy;
			}
		}
	}
	else {
		/* When not using file signatures:
		** Files that are the same size and have the same date and time
		** don't get copied.
		** If they are different size or have a different date and time,
		** copy the source file if it is newer.
		*/
		if (fSameTime & !fSameSize) {
			/* This shouldn't happen. The files have the same name and same
			** time, but are different size.
			*/
			printf("** Files have same modification data and time, but are different size:\n");
			printf("    %s\n", szSrc);
			printf("    %s\n", szDst);
			goto lNoCopy;
		}
		
		if (fSameTime & fSameSize) {
			goto lNoCopy;
		}

		if (dftTime <= 0) {
			goto lNoCopy;
		}
	}

	/* We haven't come up with a reason not to copy this file, so
	** the source file needs to be copied over the destination file.
	*/
	goto lCopy;

	/* The files are identical, but have different times.
	** Set the Creation Time and Last Write Time of the
	** destination file to match the source file.
	*/
lSetTime:
	if (apst.FPrintFile() || apst.FLogFile()) {
		sprintf_s(szMsg, cchLogMsgMax, "Setting time: %s\n", szDst);
		app.PrintMessage(idMsgCopyFile, szMsg);
		cmdx.LogMessage(idMsgCopyFile, szMsg);
	}

	if (!apst.FNoCopyFile()) {
		fhDst = CreateFile(szDst, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
					0, NULL);
		SetFileTime(fhDst, &(ffdtSrc.ftCreationTime), NULL, &(ffdtSrc.ftLastWriteTime));
		CloseHandle(fhDst);
	}
	goto lNoCopy;

	/* Copy the source file to the destination.
	*/
lCopy:
	if (apst.FPrintFile() || apst.FLogFile()) {
		sprintf_s(szMsg, cchLogMsgMax, "Copying:  %s\n", szSrc);
		app.PrintMessage(idMsgCopyFile, szMsg);
		cmdx.LogMessage(idMsgCopyFile, szMsg);
	}

	if (!apst.FNoCopyFile()) {
		fldrmg.FileCopied();
		if (CopyFile(szSrc, szDst, fFalse) == 0) {
			apst.SetErrLast(errFileSystem);
			sprintf_s(szMsg, cchLogMsgMax, "Error copying file: %s\n", szSrc);
			app.PrintMessage(idMsgError, szMsg);
			cmdx.LogMessage(idMsgError, szMsg);
			goto lErrorExit;
		}
	}

lNoCopy:
	fStat = fTrue;

lErrorExit:
	apst.FSetSzFileCur(szFile);
	return fStat;

}
Beispiel #9
0
bool
FLDS::FProcessDirectory(char * szDir)
	{
	bool		fStat;
	FLDS *		pflds;
	HANDLE		fh;
	char 		szSrc[MAX_PATH];
	char 		szDst[MAX_PATH];
	char		szMsg[cchLogMsgMax];
	DWORD		err;

	fStat = fFalse;

	/* Don't add the '.' and '..' directories to the list.
	*/
	if ((CompareSz(szDir, ".") == 0) || (CompareSz(szDir, "..") == 0)) {
		return fTrue;
	}

	/* Set the source path string
	*/
	if ((CchOfSz(szPathSrc)+CchOfSz(szDir)+1) > MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathSrc, szDir);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szSrc, szPathSrc);
	SzAppendPathSeparator(SzEnd(szSrc));
	SzAppend(szSrc, szDir);

	/* Set up the destination path string.
	*/	
	if ((CchOfSz(szPathDst)+CchOfSz(szDir)+1) > MAX_PATH) {
		apst.SetErrLast(errPathLength);
		sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathDst, szDir);
		app.PrintMessage(idMsgError, szMsg);
		cmdx.LogMessage(idMsgError, szMsg);
		goto lErrorExit;
	}
	SzCopy(szDst, szPathDst);
	SzAppendPathSeparator(SzEnd(szDst));
	SzAppend(szDst, szDir);

	/* Check if this directory is one that is being excluded.
	*/	
	if (fldrmg.FMatchXclPath(szSrc)) {
		if (apst.FPrintXclDir() || apst.FLogXclDir()) {
			sprintf_s(szMsg, cchLogMsgMax, "Skipping: %s\n", szSrc);
			app.PrintMessage(idMsgSkipDir, szMsg);
			cmdx.LogMessage(idMsgSkipDir, szMsg);
		}
		fldrmg.DirExcluded();
		return fTrue;
	}

	/* Check that the destination directory exists, and create it if
	** it doesn't
	*/
	fh = CreateFile(szDst, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
				FILE_ATTRIBUTE_READONLY|FILE_FLAG_BACKUP_SEMANTICS, NULL);
	if (fh == INVALID_HANDLE_VALUE) {

		err = GetLastError();
		if ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND)) {
			apst.SetStProg(stFileSystemError);
			goto lErrorExit;
		}

		if (apst.FPrintDir() || apst.FLogDir()) {
			sprintf_s(szMsg, cchLogMsgMax, "Creating: %s\n", szDst);
			app.PrintMessage(idMsgCreateDir, szMsg);
			cmdx.LogMessage(idMsgCreateDir, szMsg);
		}

		if (!apst.FNoCopyDir()) {
			fldrmg.DirCreated();
			if (!FCreatePath(szDst)) {
				apst.SetErrLast(errFileSystem);
				sprintf_s(szMsg, cchLogMsgMax, "Error creating directory: %s", szDst);
				app.PrintMessage(idMsgError, szMsg);
				cmdx.LogMessage(idMsgError, szMsg);
				goto lErrorExit;
			}
		}
	}
	else {
		CloseHandle(fh);
	}

	/* Create the new folder object.
	*/
	pflds = new FLDS;
	if (pflds == NULL) {
		apst.SetErrLast(errOutOfMemory);
		goto lErrorExit;
	}

	/* Set the path names into the FLDR object and add it to the list
	** of directories to be processed.
	*/
	pflds->SetPathSrc(szSrc);
	pflds->SetPathDst(szDst);

	fldrmg.AddPfldr(pflds);
	fStat = fTrue;

lErrorExit:
	return fStat;

}