SHARE
TWEET

Untitled

a guest May 19th, 2019 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const fs = require('fs');
  2. const EventEmitter = require('events');
  3. const util = require('util');
  4. const os = require('os');
  5. const path = require('path');
  6. const child_process = require('child_process');
  7.  
  8. const readFile = util.promisify(fs.readFile);
  9. const appendFile = util.promisify(fs.appendFile);
  10. const writeFile = util.promisify(fs.writeFile);
  11. const mkdir = util.promisify(fs.mkdir);
  12.  
  13. function base64Encode(str) {
  14.     // first we use encodeURIComponent to get percent-encoded UTF-8,
  15.     // then we convert the percent encodings into raw bytes which
  16.     // can be fed into btoa.
  17.     const encodedURI = encodeURIComponent(str)
  18.     let result = Buffer.from(encodedURI.replace(/%([0-9A-F]{2})/g,
  19.         (match, p1) => {
  20.             let s = String.fromCharCode('0x' + p1);
  21.             return s;
  22.         }
  23.     ));
  24.     return result.toString('base64');
  25. }
  26.  
  27. function base64Decode(str) {
  28.     // Going backwards: from bytestream, to percent-encoding, to original string.
  29.     return decodeURIComponent(Buffer.from(str, 'base64').toString().split('').map(function (c) {
  30.         let s = '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  31.         return s;
  32.     }).join(''));
  33. }
  34.  
  35. async function createTempDir() {
  36.     const r1 = Math.round(Math.random() * 10000);
  37.     const r2 = Math.round(Math.random() * 10000);
  38.     const directory = path.join(os.tmpdir(), `judge-${r1}-${r2}`);
  39.  
  40.     await mkdir(directory);
  41.     return directory;
  42. }
  43.  
  44. async function execProcess(command, input) {
  45.     const options = { timeout: 5000, maxBuffer: 50 * 1024 * 1024 };
  46.  
  47.     return new Promise((resolve, reject) => {
  48.         const proc = child_process.exec(command, options, (error, stdout, stderr) => {
  49.             resolve({ stdout, stderr });
  50.         });
  51.  
  52.         if (input) {
  53.             proc.stdin.write(input, () => {
  54.                 proc.stdin.end();
  55.             });
  56.         }
  57.     });
  58. }
  59.  
  60. function deleteDir(path) {
  61.     setImmediate(async () => {
  62.         try {
  63.             await execProcess(`rmdir /Q /S ${path}`);
  64.         } catch (error) {
  65.             console.log(error);
  66.         }
  67.     })
  68. };
  69.  
  70. const runner = {
  71.     cpp: async (code, input) => {
  72.         const directory = await createTempDir();
  73.  
  74.         const mainFile = path.join(directory, 'main.cpp');
  75.         await writeFile(mainFile, code);
  76.  
  77.         const exeFile = path.join(directory, 'main.exe');
  78.  
  79.         let result = await execProcess(`clang "${mainFile}" --output "${exeFile}"`);
  80.         if (!result.stderr || !result.stderr.length) {
  81.             result = await execProcess(`"${exeFile}"`, input);
  82.         }
  83.  
  84.         deleteDir(directory);
  85.  
  86.         return result;
  87.     },
  88.     javascript: async (code, input) => {
  89.         const directory = await createTempDir();
  90.  
  91.         const mainFile = path.join(directory, 'main.js');
  92.         await writeFile(mainFile, code);
  93.  
  94.         const result = await execProcess(`node "${mainFile}"`, input);
  95.  
  96.         deleteDir(directory);
  97.  
  98.         return result;
  99.     }
  100. };
  101.  
  102. const propertyGetterSetter = {
  103.     getHostProps: async () => {
  104.         let data = await execProcess('VBoxControl guestproperty enumerate --patterns /Host/*');
  105.  
  106.         data = data ? data.stdout : data;
  107.  
  108.         let props = [];
  109.  
  110.         if (data && data.length) {
  111.             lines = data.split('\r\n').splice(3).filter(line => line.trim().length);
  112.  
  113.             props = lines.map(line => {
  114.                 const pairs = line.split(', ');
  115.  
  116.                 const rawName = pairs[0].split(': ')[1];
  117.                 const name = rawName.substr(rawName.lastIndexOf('/') + 1);
  118.                 const value = base64Decode(pairs[1].split(': ')[1]);
  119.                
  120.                 return { name, value };
  121.             });
  122.         }
  123.  
  124.         return props;
  125.     },
  126.     deleteHostProp: async (name) => {
  127.         await execProcess(`VBoxControl guestproperty delete "/Host/${name}"`);
  128.     },
  129.     setGuestProp: async (name, value) => {
  130.         await execProcess(`VBoxControl guestproperty set "/Guest/${name}" "${base64Encode(JSON.stringify(value))}"`);
  131.     }
  132. };
  133.  
  134. const eventEmitter = new EventEmitter();
  135. eventEmitter.on('solution', async (name, value) => {
  136.     try {
  137.         const { language, input, code } = value;
  138.         if (!language || !input || !code) {
  139.             throw new Error(`malformed [language=${language}] [input=${input}] [code=${code}]`);
  140.         }
  141.  
  142.         if (!runner[language]) {
  143.             throw new Error('language not found');
  144.         }
  145.  
  146.         const result = await runner[language](code, input);
  147.         await propertyGetterSetter.setGuestProp(name, result);
  148.        
  149.     } catch (error) {
  150.         await propertyGetterSetter.setGuestProp(name, 'error');
  151.         console.log(error);
  152.     } finally {
  153.         await propertyGetterSetter.deleteHostProp(name, '');
  154.     }
  155.  
  156. });
  157.  
  158. setInterval(async () => {
  159.     try {
  160.         let props = await propertyGetterSetter.getHostProps();
  161.         props.forEach((prop) => eventEmitter.emit('solution', prop.name, JSON.parse(prop.value)));
  162.     } catch (error) {
  163.         console.log(error);
  164.     }
  165. }, 1000);
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top