Exemplo n.º 1
0
static char *tms_thumbfile_for_filename(const char *filename, int size) {
	char *sizedir;
	if (size == 256) {
		sizedir = "large";
	} else if (size == 128) {
		sizedir = "normal";
	} else {
		warnx("requested thumbnail size %d which is not supported by the thumbnail managing standard", size);
		/* FIXME */
		sizedir = "normal";
	}

	/* FIXME ignore a "filename" in the thumbnail directory */

	/* FIXME FIXME use the right thumbnail directory */

	char *thumbdir = "/home/penma/.thumbnails";

	char *uri = tms_uri_for_filename(filename);

	/* hash the URI */

	char *digest = MD5Data(uri, strlen(uri), NULL);

	/* now we can build the filename */
	char *fn;
	asprintf(&fn, "%s/%s/%s.png", thumbdir, sizedir, digest);

	free(uri);
	free(digest);

	return fn;
}
Exemplo n.º 2
0
/* Add an MD5 checksum entry for a file or link */
void
add_cksum(Package *pkg, PackingList p, const char *fname)
{
    char *cp = NULL, buf[33];

    if (issymlink(fname)) {
	int len;
	char lnk[FILENAME_MAX];

	if ((len = readlink(fname, lnk, FILENAME_MAX)) > 0)
	    cp = MD5Data((unsigned char *)lnk, len, buf);
    } else if (isfile(fname)) {
	/* Don't record MD5 checksum for device nodes and such */
	cp = MD5File(fname, buf);
    }

    if (cp != NULL) {
	PackingList tmp = new_plist_entry();

	tmp->name = copy_string(strconcat("MD5:", cp));
	tmp->type = PLIST_COMMENT;
	tmp->next = p->next;
	tmp->prev = p;
	p->next = tmp;
	if (pkg->tail == p)
	    pkg->tail = tmp;
    }
}
/**
 * Add's a file the the +CONTENTS file
 */
int
pkg_freebsd_contents_add_file(struct pkg_freebsd_contents *contents,
		struct pkgfile *file)
{
	char md5[33], tmp[37];
	const char *data;

	if (contents == NULL || contents->file != NULL || file == NULL)
		return -1;

	if (pkg_freebsd_contents_add_line(contents, PKG_LINE_FILE,
	    pkgfile_get_name(file)) != 0) {
		return -1;
	}

	data = pkgfile_get_data(file);
	if (!data)
		return -1;
	MD5Data(data, pkgfile_get_size(file), md5);
	snprintf(tmp, 37, "MD5:%s", md5);
	if (pkg_freebsd_contents_add_line(contents, PKG_LINE_COMMENT, tmp)
	    != 0) {
		return -1;
	}

	if (contents->cnts_file != NULL) {
		pkgfile_free(contents->cnts_file);
		contents->cnts_file = NULL;
	}
	return 0;
}
Exemplo n.º 4
0
/* Show files that don't match the recorded checksum */
int
show_cksum(const char *title, Package *plist)
{
    PackingList p;
    const char *dir = ".";
    char *prefix = NULL;
    char tmp[FILENAME_MAX];
    int errcode = 0;

    if (!Quiet) {
	printf("%s%s", InfoPrefix, title);
	fflush(stdout);
    }

    for (p = plist->head; p != NULL; p = p->next)
	if (p->type == PLIST_CWD) {
	    if (!prefix)
		prefix = p->name;
	    if (p->name == NULL)
		dir = prefix;
	    else
		dir = p->name;
	} else if (p->type == PLIST_FILE) {
	    snprintf(tmp, FILENAME_MAX, "%s/%s", elide_root(dir), p->name);
	    if (!fexists(tmp)) {
		warnx("%s doesn't exist", tmp);
		errcode = 1;
	    } else if (p->next && p->next->type == PLIST_COMMENT &&
	             (strncmp(p->next->name, "MD5:", 4) == 0)) {
		char *cp = NULL, buf[33];

		/*
		 * For packing lists whose version is 1.1 or greater, the md5
		 * hash for a symlink is calculated on the string returned
		 * by readlink().
		 */
		if (issymlink(tmp) && verscmp(plist, 1, 0) > 0) {
		    int len;
		    char linkbuf[FILENAME_MAX];

		    if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0)
			cp = MD5Data((unsigned char *)linkbuf, len, buf);
		} else if (isfile(tmp) || verscmp(plist, 1, 1) < 0)
		    cp = MD5File(tmp, buf);

		if (cp != NULL) {
		    /* Mismatch? */
		    if (strcmp(cp, p->next->name + 4))
			printf("%s fails the original MD5 checksum\n", tmp);
		    else if (Verbose)
			printf("%s matched the original MD5 checksum\n", tmp);
		}
	    }
	}
    return (errcode);
}
Exemplo n.º 5
0
int
main(int argc, char **argv)
{
	MD5_CTX ctx;
	char ret[10];

	MD5Init(&ctx);
	MD5Data(data, sizeof data - 1, ret);
	printf("%s\n", ret);
}
Exemplo n.º 6
0
/* Checks a file against a given md5 checksum */
int
pkg_checksum_md5(struct pkg_file *file, char *chk_sum)
{
	char sum[33];

	if (!file) {
		return -1;
	}

	if (!sum) {
		return -1;
	}

	/* Perform a checksum on the file to install */
	MD5Data(file->contents, file->len, sum);
	if (strcmp(sum, chk_sum)) {
		return -1;
	}
	return 0;
}
Exemplo n.º 7
0
void HXCloakedV2TCPSocket::_ResetResourceAndHash()
{
    CHXString tmp = "";
    
    //Generate a unique file name to use for this connection.
    _CreateRandomString(m_ResourceName);
    m_ResourceName += ".html";

    //Find a name to use for the name value pair that holds the
    //MD5 hash.
    int nIndex = RandBetween(0, sizeof(zm_NameList)/sizeof(char*)-1);
    m_NVPairName = zm_NameList[nIndex];

    //Compute the hash.
    char ucHash[65];
    tmp += m_ResourceName + zm_HashName;
    MD5Data( ucHash, (const unsigned char*)(const char*)tmp, tmp.GetLength() );
    ucHash[64] = '\0';
    m_NVPairValue = ucHash;

}
Exemplo n.º 8
0
void
Add(const char *dir1, const char *dir2, const char *name, struct dirent *de)
{
	change++;
	if (de->d_type == DT_DIR) {
		char *p = alloca(strlen(name)+strlen(de->d_name)+2);
		strcpy(p, name);  strcat(p, de->d_name); strcat(p, "/");
		name_stat("CTMDM", dir2, name, de);
		putchar('\n');
		s_new_dirs++;
		DoDir(dir1, dir2, p);
	} else if (de->d_type == DT_REG) {
		char *buf2 = alloca(strlen(dir2) + strlen(name) + 
			strlen(de->d_name) + 3);
		char *m2, md5_2[33];
		u_char *p1;
		struct stat st;
		int fd1;

		strcpy(buf2, dir2); 
			strcat(buf2, "/"); strcat(buf2, name);
			strcat(buf2, "/"); strcat(buf2, de->d_name);
		fd1 = open(buf2, O_RDONLY);
		if (fd1 < 0) { err(3, "%s", buf2); }
		fstat(fd1, &st);
		p1=mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
		if (p1 == (u_char *)MAP_FAILED) { err(3, "%s", buf2); }
		close(fd1);
		m2 = MD5Data(p1, st.st_size, md5_2);
		name_stat("CTMFM", dir2, name, de);
		printf(" %s %u\n", m2, (unsigned)st.st_size);
		fwrite(p1, 1, st.st_size, stdout);
		putchar('\n');
		munmap(p1, st.st_size);
		s_new_files++;
		s_new_bytes += st.st_size;
	}
}
Exemplo n.º 9
0
/* Checks a file against a given md5 checksum */
int
pkg_checksum_md5(struct pkg_file *file, char *chk_sum)
{
	char sum[33];

	if (!file) {
		pkg_error_set(&pkg_null, "No file specified");
		return PKG_FAIL;
	}

	if (!sum) {
		pkg_error_set((struct pkg_object *)file, "No checksum specified");
		return PKG_FAIL;
	}

	/* Perform a checksum on the file to install */
	MD5Data(file->contents, file->len, sum);
	if (strcmp(sum, chk_sum)) {
		pkg_error_set((struct pkg_object *)file,
		    "File checksum incorrect");
		return PKG_FAIL;
	}
	return PKG_OK;
}
Exemplo n.º 10
0
/*
 * Delete the results of a package installation.
 *
 * This is here rather than in the pkg_delete code because pkg_add needs to
 * run it too in cases of failure.
 */
int
delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
{
    PackingList p;
    const char *Where = ".", *last_file = "";
    Boolean fail = SUCCESS;
    Boolean preserve;
    char tmp[FILENAME_MAX], *name = NULL;
    char *prefix = NULL;

    preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
    for (p = pkg->head; p; p = p->next) {
	switch (p->type)  {
	case PLIST_NAME:
	    name = p->name;
	    break;

	case PLIST_IGNORE:
	    p = p->next;
	    break;

	case PLIST_CWD:
	    if (!prefix)
		prefix = p->name;
	    Where = (p->name == NULL) ? prefix : p->name;
	    if (Verbose)
		printf("Change working directory to %s\n", Where);
	    break;

	case PLIST_UNEXEC:
	    format_cmd(tmp, FILENAME_MAX, p->name, Where, last_file);
	    if (Verbose)
		printf("Execute '%s'\n", tmp);
	    if (!Fake && system(tmp)) {
		warnx("unexec command for '%s' failed", tmp);
		fail = FAIL;
	    }
	    break;

	case PLIST_FILE:
	    last_file = p->name;
	    if (*p->name == '/')
		strlcpy(tmp, p->name, FILENAME_MAX);
	    else
		sprintf(tmp, "%s/%s", Where, p->name);
	    if (isdir(tmp) && fexists(tmp) && !issymlink(tmp)) {
		warnx("cannot delete specified file '%s' - it is a directory!\n"
	   "this packing list is incorrect - ignoring delete request", tmp);
	    }
	    else {
		if (p->next && p->next->type == PLIST_COMMENT && !strncmp(p->next->name, "MD5:", 4)) {
		    char *cp = NULL, buf[33];

		    /*
		     * For packing lists whose version is 1.1 or greater, the md5
		     * hash for a symlink is calculated on the string returned
		     * by readlink().
		     */
		    if (issymlink(tmp) && verscmp(pkg, 1, 0) > 0) {
			int len;
			char linkbuf[FILENAME_MAX];

			if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0)
			     cp = MD5Data((unsigned char *)linkbuf, len, buf);
		    } else if (isfile(tmp) || verscmp(pkg, 1, 1) < 0)
			cp = MD5File(tmp, buf);

		    if (cp != NULL) {
			/* Mismatch? */
			if (strcmp(cp, p->next->name + 4)) {
			    warnx("'%s' fails original MD5 checksum - %s",
				  tmp, Force ? "deleted anyway." : "not deleted.");
			    if (!Force) {
				fail = FAIL;
				continue;
			    }
			}
		    }
		}
		if (Verbose)
		    printf("Delete file %s\n", tmp);
		if (!Fake) {
		    if (delete_hierarchy(tmp, ign_err, nukedirs))
			fail = FAIL;
		    if (preserve && name) {
			char tmp2[FILENAME_MAX];
			    
			if (make_preserve_name(tmp2, FILENAME_MAX, name, tmp)) {
			    if (fexists(tmp2)) {
				if (rename(tmp2, tmp))
				   warn("preserve: unable to restore %s as %s",
					tmp2, tmp);
			    }
			}
		    }
		}
	    }
	    break;

	case PLIST_DIR_RM:
	    sprintf(tmp, "%s/%s", Where, p->name);
	    if (!isdir(tmp) && fexists(tmp)) {
		warnx("cannot delete specified directory '%s' - it is a file!\n"
	"this packing list is incorrect - ignoring delete request", tmp);
	    }
	    else {
		if (Verbose)
		    printf("Delete directory %s\n", tmp);
		if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) {
		    warnx("unable to completely remove directory '%s'", tmp);
		    fail = FAIL;
		}
	    }
	    last_file = p->name;
	    break;

	default:
	    break;
	}
    }
    return fail;
}
Exemplo n.º 11
0
/**
 * Perform authentication by getting user and password from the PostgreSQL
 * database.
 * 
 * It will:
 * 1. Escape the user string
 * 2. Get password from database according to given username.
 * 3. Encrypt the password and compare with password in database.
 * 4. Cache the user's group and home directory
 * 
 * @param user     The login user
 * @param password The login password
 * 
 * @return 0: Authentication success.
 *         -1: Failed to auth
 */
int auth_pgsql_check(const char *user, const char *password)
{
	PGconn *connection = NULL;
	char *spwd = NULL, *crypted = NULL, *escaped_user = NULL;
	char sql[1024];
	int error = -1;

	user_cache_free(&pwcache);

	connection = smbftpd_pgsql_connect();
	if (!connection) {
		return -1;
	}

	escaped_user = smbftpd_pgsql_escape_string(connection, user);
	if (!escaped_user) {
		goto Error;
	}

	if (NULL == smbftpd_pgsql_get_sql(pgsql_db_info.sql_get_password, escaped_user, sql, sizeof(sql))) {
		goto Error;
	}

	spwd = smbftpd_pgsql_get_query(connection, sql);
	if (!spwd) {
		goto Error;
	}

	if (strcasecmp(pgsql_db_info.crypt, "crypt") == 0) {
		crypted = crypt(password, spwd);
		if (!crypted) {
			goto Error;
		}
		if (strcmp(crypted, spwd) != 0) {
			goto Error;
		}
	} else if (strcasecmp(pgsql_db_info.crypt, "md5") == 0) {
#ifdef   HAVE_MD5FILE
		crypted = MD5Data(password, strlen(password), NULL);
		if (!crypted) {
			goto Error;
		}
		if (strcmp(spwd, crypted) != 0) {
			free(crypted);
			goto Error;
		}
		free(crypted);
#else
		syslog(LOG_ERR, "%s (%d) md5 password encrypt is not supported.", __FILE__, __LINE__);
		goto Error;
#endif
	} else if (strcasecmp(pgsql_db_info.crypt, "plaintext") == 0) {
		if (strcmp(password, spwd) != 0) {
			goto Error;
		}
	}

	// Get group
	if (NULL == smbftpd_pgsql_get_sql(pgsql_db_info.sql_get_group, escaped_user, sql, sizeof(sql))) {
		goto Error;
	}
	pwcache.group = smbftpd_pgsql_get_query(connection, sql);
	if (NULL == pwcache.group) {
		goto Error;
	}

	// Get home
	if (NULL == smbftpd_pgsql_get_sql(pgsql_db_info.sql_get_home, escaped_user, sql, sizeof(sql))) {
		goto Error;
	}
	pwcache.home = smbftpd_pgsql_get_query(connection, sql);
	if (NULL == pwcache.home) {
		goto Error;
	}

	pwcache.user = strdup(user);
	if (NULL == pwcache.user) {
		syslog(LOG_ERR, "%s (%d) Out of memory.", __FILE__, __LINE__);
		goto Error;
	}

	error = 0;
Error:
	if (connection) {
		smbftpd_pgsql_close(connection);
	}
	if (escaped_user) {
		free(escaped_user);
	}
	if (spwd) {
		free(spwd);
	}
	return error;
}
Exemplo n.º 12
0
int
Pass1(FILE *fd, unsigned applied)
{
    u_char *p,*q;
    MD5_CTX ctx;
    int i,j,sep,cnt;
    u_char *md5=0,*name=0,*trash=0;
    struct CTM_Syntax *sp;
    int slashwarn=0, match=0, total_matches=0;
    unsigned current;
    char md5_1[33];

    if(Verbose>3)
	printf("Pass1 -- Checking integrity of incoming CTM-patch\n");
    MD5Init (&ctx);

    GETFIELD(p,' ');				/* CTM_BEGIN */
    if(strcmp(p,"CTM_BEGIN")) {
	Fatal("Probably not a CTM-patch at all.");
	if(Verbose>3)
	    fprintf(stderr,"Expected \"CTM_BEGIN\" got \"%s\".\n",p);
	return 1;
    }

    GETFIELDCOPY(Version,' ');				/* <Version> */
    if(strcmp(Version,VERSION)) {
	Fatal("CTM-patch is wrong version.");
	if(Verbose>3)
	    fprintf(stderr,"Expected \"%s\" got \"%s\".\n",VERSION,p);
	return 1;
    }

    GETFIELDCOPY(Name,' ');				/* <Name> */
    GETFIELDCOPY(Nbr,' ');				/* <Nbr> */
    GETFIELDCOPY(TimeStamp,' ');			/* <TimeStamp> */
    GETFIELDCOPY(Prefix,'\n');				/* <Prefix> */

    sscanf(Nbr, "%u", &current);
    if (FilterList || ListIt)
	current = 0;	/* ignore if -l or if filters are present */
    if(current && current <= applied) {
	if(Verbose > 0)
	    fprintf(stderr,"Delta number %u is already applied; ignoring.\n",
		    current);
	return Exit_Version;
    }

    for(;;) {
	Delete(md5);
	Delete(name);
	Delete(trash);
	cnt = -1;
	/* if a filter list is defined we assume that all pathnames require
	   an action opposite to that requested by the first filter in the
	   list.
	   If no filter is defined, all pathnames are assumed to match. */
	match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE);

	GETFIELD(p,' ');			/* CTM_something */

	if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') {
	    Fatal("Expected CTM keyword.");
	    fprintf(stderr,"Got [%s]\n",p);
	    return 1;
	}

	if(!strcmp(p+3,"_END"))
	    break;

	for(sp=Syntax;sp->Key;sp++)
	    if(!strcmp(p+3,sp->Key))
		goto found;
	Fatal("Expected CTM keyword.");
	fprintf(stderr,"Got [%s]\n",p);
	return 1;
    found:
	if(Verbose > 5)
	    fprintf(stderr,"%s ",sp->Key);
	for(i=0;(j = sp->List[i]);i++) {
	    if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
		sep = ' ';
	    else
		sep = '\n';

	    if(Verbose > 5)
	        fprintf(stderr," %x(%d)",sp->List[i],sep);

	    switch (j & CTM_F_MASK) {
		case CTM_F_Name: /* XXX check for garbage and .. */
		    GETFIELDCOPY(name,sep);
		    j = strlen(name);
		    if(name[j-1] == '/' && !slashwarn)  {
			fprintf(stderr,"Warning: contains trailing slash\n");
			slashwarn++;
		    }
		    if (name[0] == '/') {
			Fatal("Absolute paths are illegal.");
			Delete(name);
			return Exit_Mess;
		    }
		    q = name;
		    for (;;) {
			if (q[0] == '.' && q[1] == '.')
			    if (q[2] == '/' || q[2] == '\0') {
				Fatal("Paths containing '..' are illegal.");
				Delete(name);
				return Exit_Mess;
			    }
			if ((q = strchr(q, '/')) == NULL)
			    break;
			q++;
		    }

		    /* if we have been asked to `keep' files then skip
		       removes; i.e. we don't match these entries at
		       all. */
		    if (KeepIt &&
			(!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) {
			match = CTM_FILTER_DISABLE;
			break;
		    }

		    /* If filter expression have been defined, match the
		       path name against the expression list.  */
		    
		    if (FilterList) {
			struct CTM_Filter *filter;

			for (filter = FilterList; filter; 
			     filter = filter->Next) {
				if (0 == regexec(&filter->CompiledRegex, name,
					0, 0, 0))
					/* if the name matches, adopt the 
					   action */
					match = filter->Action;
			}
		    }

		    /* Add up the total number of matches */
		    total_matches += match;
		    break;
		case CTM_F_Uid:
		    GETFIELD(p,sep);
		    while(*p) {
			if(!isdigit(*p)) {
			    Fatal("Non-digit in uid.");
			    return 32;
			}
			p++;
		    }
		    break;
		case CTM_F_Gid:
		    GETFIELD(p,sep);
		    while(*p) {
			if(!isdigit(*p)) {
			    Fatal("Non-digit in gid.");
			    return 32;
			}
			p++;
		    }
		    break;
		case CTM_F_Mode:
		    GETFIELD(p,sep);
		    while(*p) {
			if(!isdigit(*p)) {
			    Fatal("Non-digit in mode.");
			    return 32;
			}
			p++;
		    }
		    break;
		case CTM_F_MD5:
		    if(j & CTM_Q_MD5_Chunk) {
			GETFIELDCOPY(md5,sep);  /* XXX check for garbage */
		    } else if(j & CTM_Q_MD5_Before) {
			GETFIELD(p,sep);  /* XXX check for garbage */
		    } else if(j & CTM_Q_MD5_After) {
			GETFIELD(p,sep);  /* XXX check for garbage */
		    } else {
			fprintf(stderr,"List = 0x%x\n",j);
			Fatal("Unqualified MD5.");
			return 32;
		    }
		    break;
		case CTM_F_Count:
		    GETBYTECNT(cnt,sep);
		    break;
		case CTM_F_Bytes:
		    if(cnt < 0) WRONG
		    GETDATA(trash,cnt);
		    p = MD5Data(trash,cnt,md5_1);
		    if(md5 && strcmp(md5,p)) {
			Fatal("Internal MD5 failed.");
			return Exit_Garbage;
		default:
			fprintf(stderr,"List = 0x%x\n",j);
			Fatal("List had garbage.");
			return Exit_Garbage;
		    }
	    }
	}
	if(Verbose > 5)
	    putc('\n',stderr);
	if(ListIt && match)
	    printf("> %s %s\n", sp->Key, name);
    }

    Delete(md5);
    Delete(name);
    Delete(trash);

    q = MD5End (&ctx,md5_1);
    if(Verbose > 2)
	printf("Expecting Global MD5 <%s>\n",q);
    GETFIELD(p,'\n');			/* <MD5> */
    if(Verbose > 2)
	printf("Reference Global MD5 <%s>\n",p);
    if(strcmp(q,p)) {
	Fatal("MD5 sum doesn't match.");
	fprintf(stderr,"\tI have:<%s>\n",q);
	fprintf(stderr,"\tShould have been:<%s>\n",p);
	return Exit_Garbage;
    }
    if (-1 != getc(fd)) {
	if(!Force) {
	    Fatal("Trailing junk in CTM-file.  Can Force with -F.");
	    return 16;
	}
    }
    if ((Verbose > 1) && (0 == total_matches))
	printf("No matches in \"%s\"\n", FileName);
    return (total_matches ? Exit_OK : Exit_NoMatch);
}
Exemplo n.º 13
0
void
Equ(const char *dir1, const char *dir2, const char *name, struct dirent *de)
{
	if (de->d_type == DT_DIR) {
		char *p = alloca(strlen(name)+strlen(de->d_name)+2);

		strcpy(p, name);  strcat(p, de->d_name); strcat(p, "/");
		DoDir(dir1, dir2, p);
		s_same_dirs++;
	} else {
		char *buf1 = alloca(strlen(dir1) + strlen(name) + 
			strlen(de->d_name) + 3);
		char *buf2 = alloca(strlen(dir2) + strlen(name) + 
			strlen(de->d_name) + 3);
		char *m1, md5_1[33], *m2, md5_2[33];
		u_char *p1, *p2;
		int fd1, fd2;
		struct stat s1, s2;

		strcpy(buf1, dir1); 
			strcat(buf1, "/"); strcat(buf1, name);
			strcat(buf1, "/"); strcat(buf1, de->d_name);
		fd1 = open(buf1, O_RDONLY);
		if(fd1 < 0) { err(3, "%s", buf1); }
		fstat(fd1, &s1);
		strcpy(buf2, dir2); 
			strcat(buf2, "/"); strcat(buf2, name);
			strcat(buf2, "/"); strcat(buf2, de->d_name);
		fd2 = open(buf2, O_RDONLY);
		if(fd2 < 0) { err(3, "%s", buf2); }
		fstat(fd2, &s2);
#if 0
		/* XXX if we could just trust the size to change... */
		if (s1.st_size == s2.st_size) {
			s_same_files++;
			s_same_bytes += s1.st_size;
			close(fd1);
			close(fd2);
			goto finish;
		}
#endif
		p1=mmap(0, s1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
		if (p1 == (u_char *)MAP_FAILED) { err(3, "%s", buf1); }
		close(fd1);

		p2=mmap(0, s2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
		if (p2 == (u_char *)MAP_FAILED) { err(3, "%s", buf2); }
		close(fd2);

		/* If identical, we're done. */
		if((s1.st_size == s2.st_size) && !memcmp(p1, p2, s1.st_size)) {
			s_same_files++;
			s_same_bytes += s1.st_size;
			goto finish;
		}

		s_files_chg++;
		change++;
		if (s1.st_size > s2.st_size)
			s_bytes_del += (s1.st_size - s2.st_size);
		else
			s_bytes_add += (s2.st_size - s1.st_size);

		m1 = MD5Data(p1, s1.st_size, md5_1);
		m2 = MD5Data(p2, s2.st_size, md5_2);
		
		/* Just a curiosity... */
		if(!strcmp(m1, m2)) {
			if (s1.st_size != s2.st_size) 
				fprintf(stderr,
		"Notice: MD5 same for files of diffent size:\n\t%s\n\t%s\n",
					buf1, buf2);
			goto finish;
		}

		{
			u_long l = s2.st_size + 2;
			u_char *cmd = alloca(strlen(buf1)+strlen(buf2)+100);
			u_char *ob = malloc(l), *p;
			int j;
			FILE *F;
			
			if (s1.st_size && p1[s1.st_size-1] != '\n') {
				if (verbose > 0) 
					fprintf(stderr,
					    "last char != \\n in %s\n",
					     buf1);
				goto subst;
			}

			if (s2.st_size && p2[s2.st_size-1] != '\n') {
				if (verbose > 0) 
					fprintf(stderr,
					    "last char != \\n in %s\n",
					     buf2);
				goto subst;
			}

			for (p=p1; p<p1+s1.st_size; p++)
				if (!*p) {
					if (verbose > 0) 
						fprintf(stderr,
						    "NULL char in %s\n",
						     buf1);
					goto subst;
				}

			for (p=p2; p<p2+s2.st_size; p++)
				if (!*p) {
					if (verbose > 0) 
						fprintf(stderr,
						    "NULL char in %s\n",
						     buf2);
					goto subst;
				}

			strcpy(cmd, "diff -n ");
			strcat(cmd, buf1);
			strcat(cmd, " ");
			strcat(cmd, buf2);
			F = popen(cmd, "r");
			for (j = 1, l = 0; l < s2.st_size; ) {
				j = fread(ob+l, 1, s2.st_size - l, F);
				if (j < 1) 
					break;
				l += j;
				continue;
			}
			if (j) {
				l = 0;
				while (EOF != fgetc(F))
					continue;
			}
			pclose(F);
			
			if (l && l < s2.st_size) {
				name_stat("CTMFN", dir2, name, de);
				printf(" %s %s %d\n", m1, m2, (unsigned)l);
				fwrite(ob, 1, l, stdout);
				putchar('\n');
				s_edit_files++;
				s_edit_bytes += l;
				s_edit_saves += (s2.st_size - l);
			} else {
			subst:
				name_stat("CTMFS", dir2, name, de);
				printf(" %s %s %u\n", m1, m2, (unsigned)s2.st_size);
				fwrite(p2, 1, s2.st_size, stdout);
				putchar('\n');
				s_sub_files++;
				s_sub_bytes += s2.st_size;
			}
			free(ob);
		}
	    finish:
		munmap(p1, s1.st_size);
		munmap(p2, s2.st_size);
	}
}
Exemplo n.º 14
0
bool MD5String(const char* string,unsigned char* pMD5 /* 16 Byte*/)
{
	size_t size = strlen(string);
	return MD5Data(string,size,pMD5);
}