iNotify how to detect move-out - c

Hi there I am using iNotify to detect changes in a directory. The flags I am using are IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE
I am trying to differentiate between a IN_MOVED_FROM when renaming, and the IN_MOVED_FROM when a file is moved out of the folder.
I thought to check if the cookie field is not 0 when user moved the file out. As I thought cookie was only for rename procedure. However even when I move the file out of the directory it still has a cookie.
I also though to check for IN_MODIFY as I was hoping that would be there on rename but not on move, but its not there for either.
Does anyone have any ideas on how to detect if it was just "moved-out" or it is the "renamed-from-oldfilename"?
Thanks

You need to check for the IN_MOVED_FROM event and a following IN_MOVED_TO event. If the cookie is the same, the file has been renamed in the same folder. If you don't receive a IN_MOVED_TO event with the same cookie, the file has been moved outside of the watched folder.

I applied the logic mention by #hek2mgl and its working so big thanks to him. This is js-ctypes code:
while (true) {
let length = ostypes.API('read')(fd, buf, count);
length = parseInt(cutils.jscGetDeepest(length));
if (length == -1) {
throw new Error({
name: 'os-api-error',
message: 'Failed to read during poll',
uniEerrno: ctypes.errno
});
} else if (!length==0) {
// then its > 0 as its not -1
// something happend, read struct
let FSChanges = [];
var i = 0;
var numElementsRead = 0;
length = parseInt(cutils.jscGetDeepest(length));
var _cache_aRenamed_local = {}; // local means per buffer
do {
let iHoisted = i;
numElementsRead++;
var casted = ctypes.cast(buf.addressOfElement(iHoisted), ostypes.TYPE.inotify_event.ptr).contents;
var fileName = casted.addressOfField('name').contents.readString();
var mask = casted.addressOfField('mask').contents;
var len = casted.addressOfField('len').contents;
var cookie = cutils.jscGetDeepest(casted.addressOfField('cookie').contents)
var wd = casted.addressOfField('wd').contents;
var aEvent = convertFlagsToAEventStr(mask);
if (aEvent == 'renamed-to') {
if (cookie in _cache_aRenamed_local) { // assuming that renamed-from must happen before rename-to otherwise its a added
if (_cache_aRenamed_local[cookie].aExtra.aOSPath_parentDir_identifier == wd) { // aOSPath_parentDir_identifier is a wd if its different then the current wd then it was added/removed from that watched dir
var rezObj = {
aFileName: fileName,
aEvent: 'renamed',
aExtra: {
nixInotifyFlags: mask, // i should pass this, as if user did modify the flags, they might want to figure out what exactly changed
aOSPath_parentDir_identifier: wd,
aOld: {
aFileName: _cache_aRenamed_local[cookie].aFileName,
aExtra: {
nixInotifyFlags: _cache_aRenamed_local[cookie].aExtra.nixInotifyFlags
}
}
}
}
FSChanges.push(rezObj);
} else {
// the one in cache was removed from its parent folder, this one here was added to parent folder. so this is detect as file moved from one watched dir to another watched dir
if (_cache_aRenamed_local[cookie].aFileName != fileName) {
console.error('whaaaaa wd\'s are differnt and got renamed-to so names should be same');
_cache_aRenamed_local[cookie].aEvent = 'haaa names are different?? im just going to say REMOVED as a guess i have never encoutnered this situation yet and i dont think we ever should';
FSChanges.push(_cache_aRenamed_local[cookie]);
} else {
_cache_aRenamed_local[cookie].aEvent = 'removed';
FSChanges.push(_cache_aRenamed_local[cookie]);
}
}
delete _cache_aRenamed_local[cookie];
} else {
var rezObj = {
aFileName: fileName,
aEvent: 'added',
aExtra: {
aOSPath_parentDir_identifier: wd
}
}
FSChanges.push(rezObj);
}
} else if (aEvent == 'renamed-from') {
var rezObj = {
aFileName: fileName,
aEvent: aEvent,
aExtra: {
aOSPath_parentDir_identifier: wd
}
}
_cache_aRenamed_local[cookie] = rezObj;
} else {
var rezObj = {
aFileName: fileName,
aEvent: aEvent,
aExtra: {
aOSPath_parentDir_identifier: wd
}
}
FSChanges.push(rezObj);
}
if (len == 0) {
break;
};
i += nixStuff.sizeField0 + nixStuff.sizeField1 + nixStuff.sizeField2 + nixStuff.sizeField3 + parseInt(len);
} while (i < length);
for (var cookieLeft in _cache_aRenamed_local) {
// whatever is left in _cache_aRenamed_local is `removed` things
_cache_aRenamed_local[cookieLeft].aEvent = 'removed';
FSChanges.push(rezObj);
}
console.error('loop ended:', 'numElementsRead:', numElementsRead);
if (FSChanges.length > 0) {
return FSChanges;
} // else dont return and continue loop
}
}
I use this function to convert the flags to a string of like renamed-from or renamed-to
function convertFlagsToAEventStr(flags) {
var default_flags = {
IN_CLOSE_WRITE: 'contents-modified',
IN_MOVED_TO: 'renamed-to', // can also be a added
IN_DELETE: 'removed',
IN_MOVED_FROM: 'renamed-from', // can also be a removed
IN_CREATE: 'added'
};
for (var f in default_flags) {
if (flags & ostypes.CONST[f]) {
return default_flags[f];
}
}
return 'UNKNOWN FLAG';
}

Related

Webassembly C program crashing at malloc

I'm working on a Javascript/web module bundler program that is written in C and a bit of JavaScript. I keep having a problem with the program where the program will randomly crash at a random malloc call in a random function. It only occurs when I use it on a more complicated project with far more files and will work fine if used on a smaller project. I've had errors with malloc and free that were being caused by memory leaks/errors in other parts of the program but as far as I can tell there is nothing wrong this time that is noticeable.
This is the error message that occurs:
RuntimeError: memory access out of bounds
at dlmalloc (wasm://wasm/007a3c2a:wasm-function[339]:0x7db59)
at ReadDataFromFile (wasm://wasm/007a3c2a:wasm-function[114]:0x4cfd8)
at BundleFile (wasm://wasm/007a3c2a:wasm-function[128]:0x55e36)
at BundleFiles (wasm://wasm/007a3c2a:wasm-function[130]:0x6b9fb)
at /mnt/c/Users/redstarbird/Documents/Projects/ArrowStack/Build/CFunctions.js:985:22
at Object.ccall (/mnt/c/Users/redstarbird/Documents/Projects/ArrowStack/Build/CFunctions.js:5328:22)
at /mnt/c/Users/redstarbird/Documents/Projects/ArrowStack/src/ArrowPack.js:104:24
The function that it crashes in looks like this:
char EMSCRIPTEN_KEEPALIVE *ReadDataFromFile(char *path)
{ // returns contents of file
printf("path: %s\n", path);
FILE *filePTR = fopen(path, "r");
if (filePTR == NULL)
{
printf("Error opening file %s\n", path);
return NULL;
}
fseek(filePTR, 0, SEEK_END); // seek to end of file
long int length = ftell(filePTR); // get length of file
fseek(filePTR, 0, SEEK_SET); // go back to start of file
char *buffer = malloc(length + 1); // This is where it crashes
if (buffer == NULL)
{
printf("Error creating buffer\n");
exit(1);
}
int currentChar = 0;
do
{
if (feof(filePTR))
{
break;
}
buffer[currentChar] = fgetc(filePTR);
currentChar++;
} while (1);
fclose(filePTR);
buffer[currentChar - 1] = '\0';
return buffer;
}
The project is compiled using this command:
emcc --no-entry -s INITIAL_MEMORY=128mb -Wl,--export=__heap_base -Wl,--export=__data_end -Wl,--export=malloc -Wl,--export=free -sENVIRONMENT=node --profiling -sRUNTIME_DEBUG=1 -fsanitize=undefined -sLLD_REPORT_UNDEFINED -g3 -sSTACK_OVERFLOW_CHECK=2 -sASSERTIONS=2 src/Main.c src/C/cJSON/cJSON.c src/DependencyGraph/DependencyGraph.c ./src/C/StringRelatedFunctions.c ./src/Regex/RegexFunctions.c ./src/DependencyGraph/FindDependencies.c ./src/SettingsSingleton/settingsSingleton.c ./src/C/ProblemHandler.c ./src/C/TextColors.c ./src/C/FileHandler.c ./src/C/IntFunctions.c ./src/Minifiers/HTMLMinifier.c ./src/C/FileTypesHandler.c ./src/C/Stack.c ./src/C/BundleFiles.c ./src/C/ProgressBar.c ./src/C/StringShiftHandler.c ./src/Minifiers/JSMinifier.c -s EXPORT_ES6=0 -s MODULARIZE -s USE_ES6_IMPORT_META=0 -s EXPORTED_RUNTIME_METHODS=["ccall"] -s NODERAWFS=1 -sBINARYEN=1 -sEXIT_RUNTIME=1 -sALLOW_MEMORY_GROWTH -o Build/CFunctions.js
The javascript code to initialise the webassembly looks like this:
#!/usr/bin/env node
"use strict";
// js wrapper for arrowpack for NPM
const fs = require("fs");
const path = require("path");
const chalk = require("chalk");
const settingsSingleton = require("./SettingsSingleton/settingsSingleton");
const DirFunctions = require("./js/DirFunctions");
const wasm_exec = require("../Build/wasm_exec.js");
const CFunctionFactory = require("../Build/CFunctions.js");
const go = new Go();
// const Sleep = require("../src/js/Sleep");
const { mkdirIfNotExists } = require("./js/DirFunctions.js");
var StartTime = performance.now();
const argv = require("yargs/yargs")(process.argv.slice(2))
.option("c", {
alias: "config-path",
describe: "Path to config file if not in working directory",
type: "string"
})
.help().argv;
var CONFIG_FILE_NAME = "ArrowPack-config.json"
if (argv.c) { CONFIG_FILE_NAME = path.join(argv.c, CONFIG_FILE_NAME) } else { console.log("no custom file thingy"); }
var rawconfigData = null;
if (fs.existsSync(CONFIG_FILE_NAME)) { rawconfigData = fs.readFileSync(CONFIG_FILE_NAME, "utf8"); }
var temp;
const Settings = new settingsSingleton(rawconfigData);
if (Settings.getValue("largeProject") === false) {
temp = DirFunctions.RecursiveWalkDir(Settings.getValue("entry")); // eventually add pluginAPI event here
} else {
let RecursiveWalkDirWASM = fs.readFileSync("../Build/RecursiveWalkDir.wasm"); const { WebAssembly } = require("wasi");
let compiledWalkDirWASM = WebAssembly.compile(wasm);
let InstanceWalkDirWASM = WebAssembly.instantiate(compiledWalkDirWASM);
const { InstanceWalkDirWASMExports } = instance;
temp = InstanceWalkDirWASMExports.walk_dir(Settings.getValue("entry"));
}
var WalkedFiles = temp.Files;
var WalkedDirs = temp.Directories;
console.log(WalkedDirs);
if (WalkedDirs) {
WalkedDirs.forEach(Dir => {
console.log(chalk.red(Dir));
var tempDir = Settings.getValue("exit") + Dir.substring(Settings.getValue("entry").length);
console.log(chalk.yellowBright(tempDir));
DirFunctions.mkdirIfNotExists(tempDir);
//DirFunctions.mkdirIfNotExists(Dir);
});
}
DirFunctions.mkdirIfNotExists("ARROWPACK_TEMP_PREPROCESS_DIR");
var AbsoluteFilesCharLength = 0;
var WrappedWalkedFiles = "";
if (WalkedFiles && WalkedFiles.length > 0) { // Paths are wrapped into one string because passing array of strings from JS to C is complicated
WalkedFiles.forEach(FilePath => { WrappedWalkedFiles += FilePath + "::"; console.log(chalk.bold.blue(FilePath)); AbsoluteFilesCharLength += FilePath.length; });
console.log(chalk.red(WalkedFiles.length));
var StructsPointer;
CFunctionFactory().then((CFunctions) => {
CFunctions._CheckWasm();
CFunctions._InitFileTypes();
for (let k in Settings.settings) {
if (CFunctions.ccall(
"SendSettingsString",
"number",
["string"],
[k]
) != 1) {
throw "Error sending Wasm settings string: " + k;
}
console.log(chalk.bold.blue(k));
// Gives time to apply settings
if (CFunctions.ccall(
"SendSettingsString",
"number",
["string"],
[Settings.settings[k].toString()]
) != 1) {
throw "Error sending Wasm settings string: " + Settings.settings[k];
}
console.log(chalk.bold.blue(Settings.settings[k]));
// Also gives time to apply settings
}
var Success;
// StructsPointer = CFunctions._CreateTree(allocateUTF8(WrappedWalkedFiles), WalkedFiles.length, AbsoluteFilesCharLength); // Need to get this working eventually for faster speed but couldn't work out allocateUTF8
StructsPointer = CFunctions.ccall(
"CreateGraph",
"number",
["string", "number"],
[WrappedWalkedFiles, WalkedFiles.length]
);
Success = CFunctions.ccall(
"BundleFiles",
"number",
["number"],
[StructsPointer]
);
if (Success === 1 || Success === 0) {
fs.rm("ARROWPACK_TEMP_PREPROCESS_DIR", { recursive: true }, (err) => {
if (err) { console.error(err); } else {
console.log("Sucessfully removed temporary preprocess directory");
}
});
DirFunctions.DeleteDirectory(); //CFunctions.ccall("PrintTimeTaken", "void", ["number", "number"], [StartTime, performance.now()]); // Not working for some reason
console.log(chalk.magentaBright("Bundling files completed in " + (performance.now() - StartTime) / 1000 + " seconds"));
}
});
// console.log("\n\nBuild completed in" + (EndTime - StartTime) / 1000 + " seconds!\n\n\n"); // Need to get Wasm code to run this because Wasm code seems to be non-blocking
/*
WebAssembly.instantiateStreaming(DependencyTreeWasmBuffer, DependencyTreeMemory).then((instance) => {
StructsPointer = instance.ccall(
"CreateTree",
"number",
["string", "number", "string"],
[WrappedWalkedFiles, WalkedFiles.length, settings.getValue("entry"), settings.getValue("exit")]
)
});
var GoWASMFileHandler;
const goWASM = fs.readFileSync("../Build/FileHandler.wasm");
WebAssembly.instantiate(goWASM, go.importObject).then(function (obj) {
GoWASMFileHandler = obj.instance;
go.run(GoWASMFileHandler);
GoWASMFileHandler.exports.HandleFiles(StructsPointer, settings.getValue("entry"));
});*/
}
The full code for the project is at https://github.com/redstarbird/arrowpack. Any help would be appreciated because I'm very stuck as to how to fix this.

ReactJS file upload Axios

I am having form with 4 file upload fields, that users can submit up to 4 images.
I am adding files to array, loop and upload to server with PHP.
Now everything seams to be working fine.. but returned image names (I am using those to store in DB) are not in the same order as I am uploading them:
Here is example of code:
if (postImage1 !== null) {
postImagesArray.push(postImage1);
}
if (postImage2 !== null) {
postImagesArray.push(postImage2);
}
if (postImage3 !== null) {
postImagesArray.push(postImage3);
}
if (postImage4 !== null) {
postImagesArray.push(postImage4);
}
//Loop Array and make upload......
var startCount = 1;
var endCount = postImagesArray.length;
for (var i = 0; i < postImagesArray.length; i++) {
var currentImage = postImagesArray[i];
//##### UPLOADING IMAGE ###########
try {
var base_url = 'https://##############.com/uploadImage.php';
var fd = new FormData();
fd.append('avatar', currentImage, 'post.jpg');
axios.post(base_url, fd).then((res) => {
console.log(res);
if (res.data.status === 'success') {
let fileConstruct =
'https://############.com/' +
res.data.fileName +
'?fit=crop&w=840&q=80';
uploadImagesArray.push(fileConstruct);
} else {
// there was an error with file upload... revert to default...
console.log('No error but no image either......');
}
if (startCount == endCount) {
uploadImagesConstruct();
}
startCount++;
});
} catch (err) {
//console.error(err);
console.log(
'There was an error uploading file to the web server: ' + err
);
if (startCount == endCount) {
uploadImagesConstruct();
}
}
Interesting thing is, images are mixed up always in the same order... (so it is not random), instead of returned image1,image2,image3,image4 I am getting image3, image2, image4, image1....If I post only 2 images it is image2,image1.... so first image is always returned last.....
Can anybody see what I am doing wrong..
Thanks!!!!
If anyone need this in the future....
I simply added underscore and postion in the loop "_i" before ".jpg" when I am constructing file names..
fd.append('avatar', currentImage, 'post.jpg');
now is:
fd.append('avatar', currentImage, `post_${i}.jpg`);
and since I am putting all records in the array
uploadImagesArray.push(fileConstruct);
I just resorted it.. by the numbers I added..
uploadImagesArray.sort(function(x, y) {
var xp = x.substring(x.lastIndexOf('_') + 1, x.lastIndexOf('.jpg'));
var yp = y.substring(y.lastIndexOf('_') + 1, y.lastIndexOf('.jpg'));
return xp == yp ? 0 : xp < yp ? -1 : 1;
});

How to get rid of "undefined" in Discord embeds

I'm trying to make it so that the output of this Discord embed won't be "undefined" for the Bot, Mute, and Deafen part of the embed.
I tried to change some var to "let" or "const"
I've tampered with the aboutuser portion to change it to something different.
I've messed with the if portion of the code.
Here's the code.
async run(message, args){
if (message.channel instanceof discord.DMChannel) return message.channel.send('This command cannot be executed here.')
else
var serv = message.guild
if (serv.explicitContentFilter == 0) {
var eFC = "Don't Scan Any messages";
}
if (serv.explicitContentFilter == 1) {
var eFC = "Scan for users without a role.";
}
if (serv.explicitContentFilter == 2) {
var eFC = "Scan every message";
}
///////////////////////////////////////////////////////////////////////////////////////////////////
if (serv.verificationLevel == 4) {
var verL = "Intense (Verified Account & Verified Phone linked)";
}
if (serv.verificationLevel == 3) {
var verL = "Secure (Verified Account & Guild member for 10+ minutes)";
}
if (serv.verificationLevel == 2) {
var verL = "Medium (Verified Account for 5 minutes+)";
}
if (serv.verificationLevel == 1) {
var verL = "Low (Verified Account)";
}
if (serv.verificationLevel == 0) {
var verL = "None (No Restriction)";
}
//////////////
if (serv.region == `brazil`) {
var regio = "Brazil";
}
if (serv.region == `eu-central`) {
var regio = "Central Europe";
}
if (serv.region == `hongkong`) {
var regio = "Hong Kong";
}
if (serv.region == `japan`) {
var regio = "Japan";
}
if (serv.region == `russia`) {
var regio = "Russia";
}
if (serv.region == `singapore`) {
var regio = "Singapore";
}
if (serv.region == `southafrica`) {
var regio = "South Africa";
}
if (serv.region == `sydney`) {
var regio = "Sydney";
}
if (serv.region == `us-central`) {
var regio = "Central US";
}
if (serv.region == `us-east`) {
var regio = "East US";
}
if (serv.region == `us-south`) {
var regio = "South US";
}
if (serv.region == `us-west`) {
var regio = "West US";
}
if (serv.region == `eu-west`) {
var regio = "West Europe";
}
//
if (serv.defaultMessageNotifications == `ALL`) {
var defn = "Send all Messages";
}
if (serv.defaultMessageNotifications == `MENTIONS`) {
var defn = "Only #everyone";
}
var myInfo = new discord.RichEmbed()
.setAuthor(`${serv.name}'s guild info`,`${message.guild.iconURL}`)
.addField(`AFK Channel`,`${serv.afkChannel}`,true)
.addField(`AFK Timeout`,`${serv.afkTimeout}s`,true)
.addField(`Channels`,`${serv.channels.size}`,true)
.addField(`Creation of Guild`,`${serv.createdAt}`,true)
.addField(`Default Notification`, defn,true)
.addField(`Explicit Content Filter Level`, eFC,true)
.addField(`Guild ID`,`${serv.id}`,true)
.addField(`How much members`,`${serv.memberCount}`,true)
.addField(`Owner`,`${serv.owner}`,true)
.addField(`Region`, regio,true)
.addField('Roles', `Please do s!roles to find server roles!`, true)
/* serv.roles.map(r => `${r}`).join(' | ') */
.addField(`Verification Level`, verL,true)
.setColor(0x511fdd)
.setFooter('Aboutserver command')
.setThumbnail(`${message.guild.iconURL}`)
message.channel.sendEmbed(myInfo);
}
}
expected result : The bot will say Yes or No instead of undefined, or true or false.
actual result : The bot's output is just undefined.
There are a couple of things happening here, but let's focus on the main issue; how you have declared your variables.
To put it simply, variables can only be accessed within the scope in which they are declared in (The scope is all the code between the {}).
I'll explain it with a short example based on your code. In your if statements you declare your variables, meaning they can be used within that if statements' scope. You later want to use those same variables outside of the if statement and in your embed. Because those variables don't exist in that scope, they are undefined.
...
// At this point there is no variable 'eFC' available.
if (serv.explicitContentFilter == 0) {
// Here you create the variable 'eFC' but it can only be used inside this scope, meaning it cannot be accessed outside the 'if' statement.
var eFC = "Don't Scan Any messages";
}
if (serv.explicitContentFilter == 1) {
// Here you create another variable with the same name, but it would end up being a different variable.
var eFC = "Scan for users without a role.";
}
// Here there is still no variable 'eFC' available to us.
...
The simple solution is: declare your variables in another scope and assign the values later. Below you can see an example:
...
// Here we create a new variable called 'eFC' which can be used within this scope
var eFC;
if (serv.explicitContentFilter == 0) {
// Here we assign a value to the previously defined variable
eFC = "Don't Scan Any messages";
}
if (serv.explicitContentFilter == 1) {
// Here we assign a value to the previously defined variable
eFC = "Scan for users without a role.";
}
// Here we can use the variable 'eFC' which will have a value
console.log(eFC);
...
If you do this for all the variables which you use, the code should work fine.
Lastly I want to leave you with some extra help. I see you have created many, many, many if statements to check for e.g. the server region or the server verification level. Javascript (among many other programming languages) has a think called a switch case which basically does the same thing you have with all those if statements, but in a more neater way. Check out the link, I think it will help you make your code look a bit more readable

screeps.com: simple script not working, issue with bi-dimensional array

I get the following error from the console: "TypeError: Cannot read property '0' of undefined", it has something to do with the array but I cannot find the mistake.
module.exports =
{
create_creeps: function()
{
var aHarvester = [[TOUGH,TOUGH, MOVE, CARRY, WORK, MOVE]["harvester"]];
Spawn.prototype.createMyCreep = function(aCreep,sRole) {
if (!Game.spawns.Spawn1.spawning){
var nameCount = 0;
var name = null;
while(name == null)
{
nameCount++;
var tryName = sRole + nameCount;
if(Game.creeps[tryName] == undefined)
name = tryName;
}
var dbg= this.canCreateCreep(aCreep, name);
if(dbg == OK) {
console.log("Creating creep " + sRole);
return this.createCreep(aCreep , name,{ role:sRole });
} else {
console.log("error "+dbg+" "+sRole);
}
}
};
Game.spawns.Spawn1.createMyCreep(aHarvester[0],aHarvester[1][0]);
};
}
Please separate arrays with a comma
So
[[TOUGH,TOUGH, MOVE, CARRY, WORK, MOVE]["harvester"]]
Should be
[[TOUGH,TOUGH, MOVE, CARRY, WORK, MOVE],["harvester"]]

Get Count of selected files in Telerik Upload

I need to get a count of all selected files using Telerik MVC Upload Control. Can anyone tell me how can i do that. I tried code like this.
var count = e.files.length;
But its counting always as one.
try this code
[function onSelect(e) {
var selectedFiles = e.files.length;
totalFiles += selectedFiles;
}
function UploadRemove(e) {
totalFiles--;
if (totalFiles > 0) {
// Write true block code here.
}
else if (totalFiles == 0) {
// Write your false block code here.
}
}]
You could do this in your upload event handler:
upload: function (e) {
// File Count:
var fileCount = this.wrapper.find(".k-file").length;
// File Index:
var uid = e.files[0].uid;
var file = this.wrapper.find(".k-file[data-uid='" + uid + "']");
var fileIndex = file.index();
}

Resources