Example #1
0
static int test_tempdir(const char *temp_dir)
{
  char *tpath = NULL;
  int fd = -1;
  int rv = asprintf(&tpath, "%s/tmp.XXXXXX", temp_dir);

#ifdef _WIN32
  _mktemp_s(tpath, strlen(tpath));
  fd = open(tpath, O_CREAT|O_WRONLY);
#else
  fd = mkstemp(tpath);
#endif

  if (fd == -1) {
    free(tpath);
    return 1;
  }

  rv = write(fd, "!", 1);
  if (rv != 1) {
    close(fd);
#ifdef _WIN32
    _unlink(tpath);
#endif
    free(tpath);
    return 1;
  }

  close(fd);
#ifdef _WIN32
  _unlink(tpath);
#endif
  free(tpath);
  return 0;
}
Example #2
0
bool CPhotoPubDoc::WriteDefPages(void)
{
	char buf[MAX_BUF_SIZE];
	GetModuleFileName(NULL,buf,MAX_BUF_SIZE);
	CString pathname(buf);
	pathname=pathname.Left(pathname.ReverseFind('\\')+1);

	char tmpname[MAX_BUF_SIZE]="tmpXXXXXX";
	FILE *fptmp,*fpfmt;
	if (_mktemp_s(tmpname,MAX_BUF_SIZE))
		return false;
	if( fopen_s( &fptmp, pathname+tmpname, "w" ) )
		return false;
	if( fopen_s( &fpfmt, pathname+"pages.fmt", "r" ) )
		return false;
	size_t size=m_PreDefinedPages.size();
	for (size_t i=0;i<size;++i){
		fprintf_s(fptmp,"[%d]\n",i);
		m_PreDefinedPages[i]->SavePage(fptmp);
	}
	fprintf_s(fptmp,"%s","[End]");

	fclose(fptmp);
	fclose(fpfmt);

   if( remove( pathname+"pages.fmt" )  )
      return false;

   if (rename(pathname+tmpname,pathname+"pages.fmt"))
	   return false;


	return true;
}
Example #3
0
static inline int
gg_mkstemp(char *path)
{
	mode_t old_umask, file_mask;
	int ret;

	file_mask = S_IRWXO | S_IRWXG;
	old_umask = umask(file_mask);
#ifdef HAVE_MKSTEMP
	ret = mkstemp(path);
#else
#ifdef _WIN32
	if (_mktemp_s(path, strlen(path) + 1) != 0)
#else
	/* coverity[secure_temp : FALSE]
	 *
	 * mktemp may be unsafe, because it creates files with predictable
	 * names, but it's not a real problem for automatic tests.
	 */
	if (strcmp(mktemp(path), "") == 0)
#endif
		ret = -1;
	else
		ret = open(path, O_EXCL | O_RDWR | O_CREAT, file_mask);
#endif
	umask(old_umask);

	return ret;
}
Example #4
0
void Gmktempdir(char* templ) {
#ifdef __WIN32__
  int blen=strlen(templ);
  if (_mktemp_s(templ, blen)!=0)
	  GError("Error creating temp dir %s!\n", templ);
#else
  char* cdir=mkdtemp(templ);
  if (cdir==NULL)
	  GError("Error creating temp dir %s!(%s)\n", templ, strerror(errno));
#endif
}
Example #5
0
int p_mkstemp(char *tmp_path)
{
#if defined(_MSC_VER)
	if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0)
		return GIT_EOSERR;
#else
	if (_mktemp(tmp_path) == NULL)
		return GIT_EOSERR;
#endif

	return p_creat(tmp_path, 0744);
}
Example #6
0
char *tmp_file_path(const char *tmp_dir, const char *prefix)
{
    char *file_path;
    size_t tmp_dir_len, prefix_len, total_len;
#ifdef WINDOWS
    errno_t err;
#else
    int fd;
#endif


    tmp_dir_len = strlen(tmp_dir);
    prefix_len = strlen(prefix);
    total_len = tmp_dir_len + 1 + prefix_len + sizeof(TMP_FILE_SUFFIX);
    file_path = (char *) malloc(total_len);

    if (file_path == NULL) {
        return NULL;
    }

    memcpy(file_path, tmp_dir, tmp_dir_len);
    /* Windows specific file API functions and stdio file functions on Windows
     * convert forward slashes to back slashes. */
    file_path[tmp_dir_len] = '/';
    memcpy(file_path + tmp_dir_len + 1, prefix, prefix_len);
    memcpy(file_path + tmp_dir_len + 1 + prefix_len,
           TMP_FILE_SUFFIX,
           sizeof(TMP_FILE_SUFFIX));

#ifdef WINDOWS
    err = _mktemp_s(file_path, total_len);
    if (err != 0) {
        free(file_path);
        return NULL;
    }
#else
    fd = mkstemp(file_path);
    if (fd == -1) {
        free(file_path);
        return NULL;
    }
    close(fd);
    remove(file_path);
#endif

    return file_path;
}
Example #7
0
int get_mercurial_info(char * hgbranch, char * hgtag, char * hgrev, int size)
{
    int result = 0;
    char filename[CMD_SIZE];
    char cmdline[CMD_SIZE];

    strcpy_s(filename, CMD_SIZE, "tmpXXXXXX");
    if (_mktemp_s(filename, CMD_SIZE) == 0) {
        int rc;

        strcpy_s(cmdline, CMD_SIZE, "hg id -bit > ");
        strcat_s(cmdline, CMD_SIZE, filename);
        rc = system(cmdline);
        if (rc == 0) {
            FILE * fp;
            
            if (fopen_s(&fp, filename, "r") == 0) {
                char * cp = fgets(cmdline, CMD_SIZE, fp);

                if (cp) {
                    char * context = NULL;
                    char * tp = strtok_s(cp, DELIMS, &context);
                    if (tp) {
                        strcpy_s(hgrev, size, tp);
                        tp = strtok_s(NULL, DELIMS, &context);
                        if (tp) {
                            strcpy_s(hgbranch, size, tp);
                            tp = strtok_s(NULL, DELIMS, &context);
                            if (tp) {
                                strcpy_s(hgtag, size, tp);
                                result = 1;
                            }
                        }
                    }
                }
                fclose(fp);
            }
        }
        _unlink(filename);
    }
    return result;
}
Example #8
0
/**
 * @brief A Windows version of mktemp().
 *
 * @param[in] fname_pattern - File name pattern.
 *
 * @return Returns a pointer to the modified template or NULL indicates an error.
 *
 */
char *
win_mktemp(char *fname_pattern)
{
	size_t sizeInChars = -1;
	errno_t ret = -1;

	if ((fname_pattern != NULL) && (*fname_pattern != '\0')) {
		sizeInChars = strlen(fname_pattern)+1;
	} else {
		errno = EINVAL;
		return NULL;
	}

	ret = _mktemp_s(fname_pattern, sizeInChars);
	if (ret != 0) {
		return NULL;
	}

	return fname_pattern;
}
Example #9
0
/******************************************************************************

MODULE:  InitLogHandler

PURPOSE:  Create a temporary log file.

RETURN VALUE:
Type = boolean
Value           Description
-----           -----------
TRUE            Success
FALSE           Failure to write

HISTORY:
Version  Date   Programmer       Code  Reason
-------  -----  ---------------  ----  -------------------------------------
         04/04   Gail Schmidt           Original Development

NOTES:
  Creating a temporary log file and then appending it to the mrtswath
  log file. This should avoid the possibility that two processes might
  write to the log file at the same time.

******************************************************************************/
bool InitLogHandler (void)
{
    FILE *templog = NULL;    /* filename of the temporary log file */

    /* if it is already open */
    if ( loginitialized )
	return ( false );

    /* create a temporary name */
    strcpy(templogname, "tmpXXXXXX");
#ifdef WIN32
    if (_mktemp_s(templogname, strlen(templogname)+1) != 0)
#else
    if( mkstemp(templogname) == -1 )
#endif
    {
	fprintf( stdout, "Error: %s : %s\n", "InitLogHandler",
	    "cannot generate unique templogname with mkstemp()" );
        fflush( stdout );
	return ( false );
    }

    /* open a temporary log file in the current directory */
    templog = fopen( templogname, "w" );
    if ( !templog )
    {
	fprintf( stdout, "Error: %s : %s\n", "InitLogHandler",
	    ERRORMSG_LOGFILE_OPEN );
        fflush( stdout );
	return ( false );
    }

    /* let someone else open and close */
    fclose( templog );
    loginitialized = true;

    return ( true );
}
static int _mkstemp(const char * t){
  size_t l = strlen(t) + 1;
  char s[50];
  strncpy(s, t, l);
  return _mktemp_s(s, l) ? -1 : _open(s, _O_CREAT|_O_EXCL);
}
Example #11
0
char *fix_at_file(char *in)
{
  char *tmpdir;
  char name[2048];
  char *atname;
  char *buffer;
  size_t buflen=65536;
  size_t used=0;
  size_t len;
  int rc;
  FILE *atout;
  FILE *atin;
  char block[2048];
  size_t blocklen;
  char *fixed;

  atin = fopen(in+1, "r");
  if (atin == NULL) {
    fprintf(stderr, "Could not read at file %s\n", in+1);
    exit(-1);
  }

  tmpdir = getenv("TMP");
  if (tmpdir == NULL) {
    tmpdir = "c:/cygwin/tmp";
  }
  _snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir);

  rc = _mktemp_s(name, strlen(name)+1);
  if (rc) {
    fprintf(stderr, "Could not create temporary file name for at file!\n");
    exit(-1);
  }

  atout = fopen(name, "w");
  if (atout == NULL) {
    fprintf(stderr, "Could not open temporary file for writing! %s\n", name);
    exit(-1);
  }

  buffer = malloc(buflen);
  while((blocklen = fread(block,1,sizeof(block),atin)) > 0) {
    append(&buffer, &buflen, &used, block, blocklen);
  }
  buffer[used] = 0;
  if (getenv("DEBUG_FIXPATH") != NULL) {
    fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
  }
  fixed = replace_cygdrive(buffer);
  if (getenv("DEBUG_FIXPATH") != NULL) {
    fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
  }
  fwrite(fixed, strlen(fixed), 1, atout);
  fclose(atin);
  fclose(atout);
  free(fixed);
  free(buffer);
  files_to_delete[num_files_to_delete] = malloc(strlen(name)+1);
  strcpy(files_to_delete[num_files_to_delete], name);
  num_files_to_delete++;
  atname = malloc(strlen(name)+2);
  atname[0] = '@';
  strcpy(atname+1, name);
  return atname;
}
Example #12
0
/**
 * Gets the temp directory when blender first runs.
 * If the default path is not found, use try $TEMP
 * 
 * Also make sure the temp dir has a trailing slash
 *
 * \param fullname The full path to the temporary temp directory
 * \param basename The full path to the persistent temp directory (may be NULL)
 * \param maxlen The size of the fullname buffer
 * \param userdir Directory specified in user preferences 
 */
static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir)
{
	/* Clear existing temp dir, if needed. */
	BKE_tempdir_session_purge();

	fullname[0] = '\0';
	if (basename) {
		basename[0] = '\0';
	}

	if (userdir && BLI_is_dir(userdir)) {
		BLI_strncpy(fullname, userdir, maxlen);
	}
	
	
#ifdef WIN32
	if (fullname[0] == '\0') {
		const char *tmp = getenv("TEMP"); /* Windows */
		if (tmp && BLI_is_dir(tmp)) {
			BLI_strncpy(fullname, tmp, maxlen);
		}
	}
#else
	/* Other OS's - Try TMP and TMPDIR */
	if (fullname[0] == '\0') {
		const char *tmp = getenv("TMP");
		if (tmp && BLI_is_dir(tmp)) {
			BLI_strncpy(fullname, tmp, maxlen);
		}
	}
	
	if (fullname[0] == '\0') {
		const char *tmp = getenv("TMPDIR");
		if (tmp && BLI_is_dir(tmp)) {
			BLI_strncpy(fullname, tmp, maxlen);
		}
	}
#endif
	
	if (fullname[0] == '\0') {
		BLI_strncpy(fullname, "/tmp/", maxlen);
	}
	else {
		/* add a trailing slash if needed */
		BLI_add_slash(fullname);
#ifdef WIN32
		if (userdir && userdir != fullname) {
			BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */
		}
#endif
	}

	/* Now that we have a valid temp dir, add system-generated unique sub-dir. */
	if (basename) {
		/* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */
		char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX");
		const size_t ln = strlen(tmp_name) + 1;
		if (ln <= maxlen) {
#ifdef WIN32
			if (_mktemp_s(tmp_name, ln) == 0) {
				BLI_dir_create_recursive(tmp_name);
			}
#else
			mkdtemp(tmp_name);
#endif
		}
		if (BLI_is_dir(tmp_name)) {
			BLI_strncpy(basename, fullname, maxlen);
			BLI_strncpy(fullname, tmp_name, maxlen);
			BLI_add_slash(fullname);
		}
		else {
			printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname);
		}

		MEM_freeN(tmp_name);
	}
}
Example #13
0
/* Create a temporary file */
int mkstemp_ex(char *tmp_path)
{
    DWORD dwResult;
    int result;
    int status = -1;

    HANDLE h = NULL;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea[2];
    SECURITY_ATTRIBUTES sa;

    PSID pAdminGroupSID = NULL;
    PSID pSystemGroupSID = NULL;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};

#if defined(_MSC_VER) && _MSC_VER >= 1500
    result = _mktemp_s(tmp_path, strlen(tmp_path) + 1);

    if (result != 0) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned (%d)",
            __local_name,
            tmp_path,
            result
        );

        return (-1);
    }
#else
    if (_mktemp(tmp_path) == NULL) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]",
            __local_name,
            tmp_path,
            errno,
            strerror(errno)
        );

        return (-1);
    }
#endif

    /* Create SID for the BUILTIN\Administrators group */
    result = AllocateAndInitializeSid(
                 &SIDAuthNT,
                 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pAdminGroupSID
             );

    if (!result) {
        log2file(
            "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Create SID for the SYSTEM group */
    result = AllocateAndInitializeSid(
                 &SIDAuthNT,
                 1,
                 SECURITY_LOCAL_SYSTEM_RID,
                 0, 0, 0, 0, 0, 0, 0,
                 &pSystemGroupSID
             );

    if (!result) {
        log2file(
            "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Initialize an EXPLICIT_ACCESS structure for an ACE */
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));

    /* Add Administrators group */
    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID;

    /* Add SYSTEM group */
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID;

    /* Set entries in ACL */
    dwResult = SetEntriesInAcl(2, ea, NULL, &pACL);

    if (dwResult != ERROR_SUCCESS) {
        log2file(
            "%s: ERROR: Could not set ACL entries which returned (%lu)",
            __local_name,
            dwResult
        );

        goto cleanup;
    }

    /* Initialize security descriptor */
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
              LPTR,
              SECURITY_DESCRIPTOR_MIN_LENGTH
          );

    if (pSD == NULL) {
        log2file(
            "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
        log2file(
            "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Set owner */
    if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set owner which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Set group owner */
    if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set group owner which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Add ACL to security descriptor */
    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Initialize security attributes structure */
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = FALSE;

    h = CreateFileA(
            tmp_path,
            GENERIC_WRITE,
            0,
            &sa,
            CREATE_NEW,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );

    if (h == INVALID_HANDLE_VALUE) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned (%lu)",
            __local_name,
            tmp_path,
            GetLastError()
        );

        goto cleanup;
    }

    if (!CloseHandle(h)) {
        log2file(
            "%s: ERROR: Could not close file handle to (%s) which returned (%lu)",
            __local_name,
            tmp_path,
            GetLastError()
        );

        goto cleanup;
    }

    /* Success */
    status = 0;

cleanup:
    if (pAdminGroupSID) {
        FreeSid(pAdminGroupSID);
    }

    if (pSystemGroupSID) {
        FreeSid(pSystemGroupSID);
    }

    if (pACL) {
        LocalFree(pACL);
    }

    if (pSD) {
        LocalFree(pSD);
    }

    return (status);
}
bool ValidWriteAssert(bool ok)
{
    if (gShutdownChecks == SCM_CRASH && !ok) {
        MOZ_CRASH();
    }

    // We normally don't poison writes if gShutdownChecks is SCM_NOTHING, but
    // write poisoning can get more users in the future (profiling for example),
    // so make sure we behave correctly.
    if (gShutdownChecks == SCM_NOTHING || ok || !sProfileDirectory ||
        !Telemetry::CanRecord()) {
        return ok;
    }

    // Write the stack and loaded libraries to a file. We can get here
    // concurrently from many writes, so we use multiple temporary files.
    std::vector<uintptr_t> rawStack;

    NS_StackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
                 reinterpret_cast<void*>(&rawStack), 0, nullptr);
    Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack);

    nsPrintfCString nameAux("%s%s%s", sProfileDirectory,
                            NS_SLASH, "Telemetry.LateWriteTmpXXXXXX");
    char *name;
    nameAux.GetMutableData(&name);

    // We want the sha1 of the entire file, so please don't write to fd
    // directly; use sha1Stream.
    FILE *stream;
#ifdef XP_WIN
    HANDLE hFile;
    do {
      // mkstemp isn't supported so keep trying until we get a file
      int result = _mktemp_s(name, strlen(name) + 1);
      hFile = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    } while (GetLastError() == ERROR_FILE_EXISTS);

    if (hFile == INVALID_HANDLE_VALUE) {
      NS_RUNTIMEABORT("Um, how did we get here?");
    }

    // http://support.microsoft.com/kb/139640
    int fd = _open_osfhandle((intptr_t)hFile, _O_APPEND);
    if (fd == -1) {
      NS_RUNTIMEABORT("Um, how did we get here?");
    }

    stream = _fdopen(fd, "w");
#else
    int fd = mkstemp(name);
    stream = fdopen(fd, "w");
#endif

    SHA1Stream sha1Stream(stream);

    size_t numModules = stack.GetNumModules();
    sha1Stream.Printf("%u\n", (unsigned)numModules);
    for (size_t i = 0; i < numModules; ++i) {
        Telemetry::ProcessedStack::Module module = stack.GetModule(i);
        sha1Stream.Printf("%s %s\n", module.mBreakpadId.c_str(),
                          module.mName.c_str());
    }

    size_t numFrames = stack.GetStackSize();
    sha1Stream.Printf("%u\n", (unsigned)numFrames);
    for (size_t i = 0; i < numFrames; ++i) {
        const Telemetry::ProcessedStack::Frame &frame =
            stack.GetFrame(i);
        // NOTE: We write the offsets, while the atos tool expects a value with
        // the virtual address added. For example, running otool -l on the the firefox
        // binary shows
        //      cmd LC_SEGMENT_64
        //      cmdsize 632
        //      segname __TEXT
        //      vmaddr 0x0000000100000000
        // so to print the line matching the offset 123 one has to run
        // atos -o firefox 0x100000123.
        sha1Stream.Printf("%d %x\n", frame.mModIndex, (unsigned)frame.mOffset);
    }

    SHA1Sum::Hash sha1;
    sha1Stream.Finish(sha1);

    // Note: These files should be deleted by telemetry once it reads them. If
    // there were no telemery runs by the time we shut down, we just add files
    // to the existing ones instead of replacing them. Given that each of these
    // files is a bug to be fixed, that is probably the right thing to do.

    // We append the sha1 of the contents to the file name. This provides a simple
    // client side deduplication.
    nsPrintfCString finalName("%s%s", sProfileDirectory, "/Telemetry.LateWriteFinal-");
    for (int i = 0; i < 20; ++i) {
        finalName.AppendPrintf("%02x", sha1[i]);
    }
    PR_Delete(finalName.get());
    PR_Rename(name, finalName.get());
    return false;
}
// main関数
int main(int argc, char* argv[])
{
	// 引数解釈
	const char*	makefile	= NULL;
	const char*	top_dir		= NULL;

	for (int i=1; i < argc; i++) {
		char*	p = argv[i];
		if (*p == '/' || *p =='-') {
			p++;
			if (_strnicmp(p,"file",4) == 0) {
				p += 4;
				if (*p == '\0') {
					if (i < argc) {
						makefile = argv[++i];
					}
				}
				else {
					if (*p == '=') p++;
					makefile = p;
				}
			}
			else if (_strnicmp(p,"dir",3) == 0) {
				p += 3;
				if (*p == '\0') {
					if (i < argc) {
						top_dir = argv[++i];
					}
				}
				else {
					if (*p == '=') p++;
					top_dir = p;
				}
			}
			else {
				printf("Error: 不明な引数[%s]\n", argv[i]);
				return usage();
			}
		}
		else {
			printf("Error: 不明な引数[%s]\n", argv[i]);
			return usage();
		}
	}
	if (makefile == NULL && top_dir != NULL) { return usage(); }
	if (!makefile)	{ printf("Error: makefileを指定してください\n\n");				return usage(); }
	if (!top_dir)	{ printf("Error: トップディレクトリを指定してください\n\n");	return usage(); }


	// トップディレクトリのチェック
	struct stat		st;
	int		ret = stat( top_dir, &st );
	if (ret != 0 || !(st.st_mode & _S_IFDIR)) {
		printf("Error: トップディレクトリ[%s]が見つかりません\n", top_dir);
		return 1;
	}

	// ファイルオープン
	FILE*	in = NULL;
	if (fopen_s( &in, makefile, "rt" ) != 0) {
		printf("Error: 出力ファイル[%s]を開けません\n", makefile);
		return 1;
	}

	// テンポラリファイルの作成
	char	tmp_file[_MAX_PATH];
	char	drive[_MAX_DRIVE], dir[_MAX_DIR];
	if (_splitpath_s( makefile, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0 )) {
		printf("Error: 一時ファイル名を作れません[%s]\n", makefile);
		return 1;
	}
	if (_makepath_s( tmp_file, _countof(tmp_file), drive, dir, "mfXXXXXX", NULL )) {
		printf("Error: 一時ファイル名を作れません[%s, %s]\n", drive, dir);
		return 1;
	}
	if (_mktemp_s(tmp_file, _countof(tmp_file))) {
		printf("Error: 一時ファイル名を作れません[%s]\n", tmp_file);
		return 1;
	}
	FILE*	out = NULL;
	if (fopen_s( &out, tmp_file, "wt" ) != 0) {
		printf("Error: 一時ファイル[%s]を開けません\n", tmp_file);
		return 1;
	}

	// ファイルリストの作成
	makeFileListTop(top_dir);

	// ファイルの書替え
	int			mode = 0;			// 0:.obj前 1:.obj中 2:.obj後
	bool		change = false;		// 変更あり

	char		line[1024];
	char		mkline[1024];
	char*		wtline;
	const char*	fl_nm;

	while (fgets(line, _countof(line), in) != NULL) {
		wtline = line;
		switch (mode) {
		case 0:
			if (strstr(line, "OBJS")) {
				mode = 1;
			}
			break;
		case 1:
			if (line[0] == '\n' || line[0] == '\0') {
				// リスト終了?
				fl_nm = getFile();
				if (fl_nm != NULL) {
					// ファイルが増えた
					change = true;
					do {
						//出力
						fprintf(out, "%s", makeObjLine( mkline, _countof(mkline), fl_nm ) );
					} while ((fl_nm = getFile()) != NULL);
				}
				mode = 2;
			}
			else {
				fl_nm = getFile();
				if (fl_nm == NULL) {
					// ファイルが減った
					change = true;
					continue;
				}
				makeObjLine( mkline, _countof(mkline), fl_nm );
				// 変更有りか?
				if (!change && strcmp(line, mkline) != 0)
					change = true;
				wtline = mkline;
			}
			break;
		case 2:
			break;
		}
		//出力
		fprintf(out,"%s", wtline);
	}

	// close
	fclose(in);
	fclose(out);
#ifdef _DEBUG
	printf("%d個のオブジェクトファイル名が出力されました\n", file_list.size());
#endif

	// ファイルの入換え
	if (change) {
		if (remove(makefile)) {
			printf("Error: makefile[%s]を削除出来ません\n", tmp_file);
			return 1;
		}
		if (rename( tmp_file, makefile )) {
			printf("Error: 一時ファイル[%s]をmakfile[%s]に出来ません\n", tmp_file, makefile);
			return 1;
		}
	}
	else {
		if (remove(tmp_file)) {
			printf("Warning: 一時ファイル[%s]を削除出来ません\n", tmp_file);
		}
		printf("出力ファイルは最新です\n");
	}

	return 0;
}