Esempio n. 1
0
 def _type(self, command):
     """Manages the type of the `TField`"""
     if len(command) == 1:
         print(self._f.type, '\n')
         return
     # Parsing the arguments
     cp = CommandParser(FieldInterface._type_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     # Print the help
     if args["-h"]:
         Interface.print_help(FieldInterface._type_help())
     # Add a new type
     elif args["-a"]:
         if args["-a"] == "hex":
             self._f.to_hex()
             Interface._print_info("New type added")
         elif args["-a"] == "bytes":
             self._f.to_bytes()
             Interface._print_info("New type added")
         elif args["-a"] == "str":
             self._f.to_str()
             Interface._print_info("New type added")
         elif args["-a"] == "int":
             if args["-o"] in ['big', 'little']:
                 self._f.to_int(args["-o"])
                 Interface._print_info("New type added")
             else:
                 Interface._print_error(
                     "Wrong order. Please select big or little")
         else:
             Interface._print_error(
                 "Wrong type. Please choose between ('hex', 'bytes', 'str', 'int')")
Esempio n. 2
0
 def _save(self, command):
     """Saves the `Template` to disk."""
     if len(command) == 1:
         path = input("Introduce the path and the file name: ")
         try:
             self._t.write(path)
             Interface._print_info("Template saved to disk")
         except:
             Interface._print_error("The path %s does not exist" % path)
         return
     # Parsing arguments
     cp = CommandParser(TemplateInterface._save_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     # Print the help
     if args["-h"]:
         Interface.print_help(TemplateInterface._save_help())
     # Write to a specific path
     elif args["-p"]:
         try:
             self._t.write(args['-p'])
             Interface._print_info("Template saved to disk")
         except:
             Interface._print_error("The path %s does not exist" %
                                    args['-p'])
Esempio n. 3
0
 def run(self):
     """Runs the interface and waits for user input commands."""
     completer = WordCompleter([
         'value', 'type', 'show', 'name', 'slice', 'size', 'dump', 'clear',
         'back'
     ])
     history = FileHistory(self._polym_path + '/.finterface_history')
     session = PromptSession(history=history)
     while True:
         try:
             command = session.prompt(
                 HTML("<bold>PH:cap/t%d/%s/<red>%s</red> > </bold>" %
                      (self._tindex, self._lname, self._f.name)),
                 completer=completer,
                 complete_style=CompleteStyle.READLINE_LIKE,
                 auto_suggest=AutoSuggestFromHistory(),
                 enable_history_search=True)
         except KeyboardInterrupt:
             self.exit_program()
             continue
         try:
             command = command.rstrip().split(" ")
             if command[0] in self.EXIT:
                 self.exit_program()
             elif command[0] in self.RET:
                 break
             elif command[0] in ['v', 'value']:
                 self._value(command)
             elif command[0] in ['s', 'show']:
                 self._show(command)
             elif command[0] == 'name':
                 print(self._f.name, '\n')
             elif command[0] == "slice":
                 print(self._f.slice, '\n')
             elif command[0] == "type":
                 self._type(command)
             elif command[0] == "size":
                 print(self._f.size, '\n')
             elif command[0] in ['d', 'dump']:
                 Interface.color_dump(self._f.pkt_raw, self._f.slice.start,
                                      self._f.slice.stop)
             elif command[0] == "clear":
                 Interface._clear()
             elif command[0] == "":
                 continue
             else:
                 Interface._wrong_command()
         except SystemExit:
             raise
         except Exception as e:
             Interface._print_error(
                 "Exception: Error processing the previous command. More info:"
             )
             print(e)
Esempio n. 4
0
 def _import(self, command):
     if len(command) == 1:
         Interface.print_help(MainInterface._import_help())
         return
     # Parsing additional options
     cp = CommandParser(MainInterface._import_opts())
     args = cp.parse(command)
     # Wrong arguments will return None
     if not args:
         Interface._argument_error()
         return
     # Importing a template
     if args["-h"]:
         Interface.print_help(MainInterface._import_help())
     elif args["-t"]:
         if os.path.isfile(args["-t"]):
             try:
                 template = readtemplate(args["-t"])
                 t = TemplateInterface(template, 0, self._poisoner)
                 t.run()
             except:
                 Interface._print_error("Wrong Template file")
         else:
             Interface._print_error("The file does not exist")
     elif args["-pcap"]:
         if os.path.isfile(args["-pcap"]):
             try:
                 tlist = readpcap(args["-pcap"])
                 tl = TListInterface(tlist, self._poisoner)
                 tl.run()
             except:
                 Interface._print_error("Wrong pcap file")
         else:
             Interface._print_error("The file does not exist")
Esempio n. 5
0
 def _layer(self, command):
     """Manages the access to a `TLayer` of the `Template`."""
     if len(command) == 1:
         Interface.print_help(TemplateInterface._layer_help())
     elif len(command) == 2 and command[1].upper() in self._t.layernames():
         li = LayerInterface(self._t.getlayer(command[1].upper()),
                             self._index, self._poisoner)
         li.run()
     else:
         cp = CommandParser(TemplateInterface._layer_opts())
         args = cp.parse(command)
         if not args:
             Interface._argument_error()
             return
         # Print the help
         if args["-h"]:
             Interface.print_help(TemplateInterface._layer_help())
         # Adds a new layer
         elif args["-a"]:
             hexdump.hexdump(self._t.raw)
             print()
             start = input("Start byte of the custom layer: ")
             end = input("End byte of the custom layer: ")
             if start.isdecimal() and end.isdecimal():
                 lslice = str(slice(int(start), int(end))).encode().hex()
                 new_layer = TLayer(args["-a"],
                                    raw=self._t.raw.hex(),
                                    lslice=lslice,
                                    custom=True)
                 self._t.addlayer(new_layer)
                 Interface._print_info(
                     "New layer %s added to the Template" % args["-a"])
             else:
                 Interface._print_error(
                     "The start or end byte is not a number")
         # Deletes an existing layer
         elif args["-d"]:
             del_layer = self._t.getlayer(args["-d"])
             if del_layer:
                 self._t.dellayer(del_layer)
                 Interface._print_info("Layer %s deleted" % args["-d"])
             else:
                 Interface._print_error("The layer %s does not exist" %
                                        args["-d"])
Esempio n. 6
0
 def _recalculate(self, command):
     """Manages all the recalculate options for the fields of the layer."""
     if len(command) == 1:
         Interface.print_help(LayerInterface._recalculate_help())
         return
     # Parsing the arguments
     cp = CommandParser(LayerInterface._recalculate_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     # Print the help
     if args["-h"]:
         Interface.print_help(LayerInterface._recalculate_help())
     # Adds a new recalculate expression
     elif args["-f"] and args["-sb"] and args["-e"]:
         fields = LayerInterface._extrac_deps(args["-sb"], args["-e"])
         if fields:
             try:
                 self._l.add_struct(args["-f"], fields, args["-sb"],
                                    args["-e"])
                 Interface._print_info("Struct added to field %s" %
                                       args["-f"])
             except:
                 Interface._print_error(
                     "Wrong fields or wrong syntax referring to the fields")
                 return
         else:
             Interface._print_error(
                 "Wrong syntax for referring to the fields. Please use 'this.field' syntax"
             )
     # Tests a created struct
     elif args["-t"] and len(command) == 3:
         if self._l.is_struct(args["-t"]):
             try:
                 print(self._l.test_struct(args["-t"]), "\n")
             except construct.core.StreamError as e:
                 Interface._print_error(
                     "The Struct is not well formed. Please check the fields and their type.\n%s"
                     % str(e))
         else:
             Interface._print_error("The Struct %s is not in the layer" %
                                    args['-t'])
     # Show the struct for a particular field
     elif args["-s"] and len(command) == 3:
         self._l.show_structs(args["-s"])
     # Deletes a struct for a field
     elif args["-d"] and len(command) == 3:
         if self._l.is_struct(args["-d"]):
             self._l.del_struct(args["-d"])
             Interface._print_info("Struct deleted for %s" % args["-d"])
         else:
             self._print_error("The Struct %s is not in the layer" %
                               args["-d"])
Esempio n. 7
0
 def run(self):
     """Runs the interface and waits for user input commands."""
     completer = WordCompleter(
         ['show', 'template', 'wireshark', 'clear', 'back'])
     history = FileHistory(self._polym_path + '/.tlinterface_history')
     session = PromptSession(history=history)
     while True:
         try:
             command = session.prompt(
                 HTML("<bold>PH:<red>cap</red> > </bold>"),
                 completer=completer,
                 complete_style=CompleteStyle.READLINE_LIKE,
                 auto_suggest=AutoSuggestFromHistory(),
                 enable_history_search=True)
         except KeyboardInterrupt:
             self.exit_program()
             continue
         try:
             command = command.rstrip().split(" ")
             if command[0] in self.EXIT:
                 self.exit_program()
             elif command[0] in self.RET:
                 break
             elif command[0] in ["show", "s"]:
                 self._show(command)
             elif command[0] in ["template", "t"]:
                 self._template(command)
             elif command[0] in ["wireshark", "w"]:
                 self._wireshark(command)
             elif command[0] == "clear":
                 Interface._clear()
             elif command[0] == "":
                 continue
             else:
                 Interface._wrong_command()
         except SystemExit:
             raise
         except Exception as e:
             Interface._print_error(
                 "Exception: Error processing the previous command. More info:"
             )
             print(e)
Esempio n. 8
0
 def _value(self, command):
     """Manages the value of the `TField`."""
     if len(command) == 1:
         print(self._f.value, '\n')
         return
     # Parsing the arguments
     cp = CommandParser(FieldInterface._value_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     # Print the help
     if args["-h"]:
         Interface.print_help(FieldInterface._value_help())
     # Prints the value encoded in hex
     if args["-hex"]:
         print(self._f.valuehex, '\n')
     # Prints the value encoded in bytes
     elif args["-b"]:
         print(self._f.valuebytes, '\n')
     # Adds a new value
     elif args["-a"]:
         if args["-t"] == 'str':
             self._f.value = args["-a"]
             Interface._print_info("New value added to the field")
         elif args["-t"] == 'int':
             self._f.value = int(args["-a"])
             Interface._print_info("New value added to the field")
         elif args["-t"] == 'hex':
             self._f.value = args["-a"]
             Interface._print_info("New value added to the field")
         elif args["-t"] == 'bytes':
             self._f.value = args["-a"].encode()
             Interface._print_info("New value added to the field")
         else:
             Interface._print_error(
                 "Wrong type. Please choose between ('hex', 'bytes', 'str', 'int')"
             )
Esempio n. 9
0
 def _type(self, command):
     """Manages the type of the `TField`"""
     if len(command) == 1:
         print(self._f.type, '\n')
         return
     # Parsing the arguments
     cp = CommandParser(FieldInterface._type_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     # Print the help
     if args["-h"]:
         Interface.print_help(FieldInterface._type_help())
     # Add a new type
     elif args["-a"]:
         ftype = input("\n1: FT_INT_BE\n"
                       "2: FT_INT_LE\n"
                       "3: FT_STRING\n"
                       "4: FT_BYTES\n"
                       "5: FT_BIN_BE\n"
                       "6: FT_BIN_LE\n"
                       "7: FT_HEX\n"
                       "8: FT_ETHER\n"
                       "9: FT_IPv4\n"
                       "10: FT_IPv6\n"
                       "11: FT_ABSOLUTE_TIME\n"
                       "12: FT_RELATIVE_TIME\n"
                       "13: FT_EUI64\n\n"
                       "Select the type of the field: ")
         if not ftype.isdecimal() or int(ftype) > 12 or int(ftype) < 0:
             Interface._print_error("Select a number between 1 and 12")
             return
         if int(ftype) in [5, 6]:
             fmask = input("Select the bitmask (ie: 11110000): ")
             if not fmask.isdecimal():
                 Interface._print_error("Select a binary number")
                 return
             fmask = int(fmask, 2)
         else:
             fmask = 0
         try:
             ftype = Ftype(int(ftype) - 1)
             cv = Converter()
             frepr = cv.get_frepr(ftype, self._f.raw, self._f.size, fmask,
                                  self._f.name)
         except Exception as e:
             print(e)
             Interface._print_error(
                 "The value of the field in bytes is wrong")
             return
         self._f._ftype = ftype
         self._f._frepr = frepr
         Interface._print_info("New type %s added to the field." %
                               str(ftype))
Esempio n. 10
0
 def no_captured():
     """Shows no packets captured."""
     Interface._print_error("No packets have been captured.")
Esempio n. 11
0
 def _conditions(self, command, cond):
     """Manages the preconditions, postconditions and executions for a
     particular `Template`."""
     if len(command) == 1:
         self._t.show_conditions(cond)
         return
     # Parsing the arguments
     cp = CommandParser(TemplateInterface._conditions_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     if len(command) == 2:
         # Print the help
         if args['-h']:
             Interface.print_help(TemplateInterface._conditions_help(cond))
         # Show the source code
         elif args['-s']:
             self._t.show_conditions(cond, True)
         # Show all conditions on disk
         elif args['-sa']:
             self._t.show_all_conds(cond)
         # Show all conditions source on disk
         elif args['-sas']:
             self._t.show_all_conds(cond, True)
     else:
         # Deletes a condition
         if args['-d']:
             try:
                 self._t.del_function(cond, args['-d'])
                 Interface._print_info("Condition %s deleted" % args['-d'])
             except KeyError:
                 Interface._print_error(
                     "The condition %s is not in the list" % args['-d'])
                 return
         # Adds a condition
         elif args['-a']:
             # Create the new file
             self._create_cond(cond, args["-a"])
             ret = os.system(
                 "%s %s.py" %
                 (args["-e"], join(self._conds_path, cond, args["-a"])))
             if ret != 0:
                 Interface._print_error(
                     "The editor is not installed or is not in the PATH")
                 return
             # Save the condition to the Template
             try:
                 self._add_cond(cond, args["-a"])
             except:
                 Interface._print_error(
                     "Bad syntax, please check the code syntax")
                 return
             # If user wants, delete condition from disk
             keepindisk = confirm('Keep file on disk (%s)? [y/N] ' %
                                  join(self._conds_path, cond))
             if not keepindisk:
                 os.remove("%s.py" %
                           join(self._conds_path, cond, args["-a"]))
             Interface._print_info("Condition %s added" % args["-a"])
         # Imports a condition from disk
         elif args['-i']:
             name = args['-i']
             if name[-3:] == ".py":
                 name = name[:-3]
             try:
                 self._add_cond(cond, name)
                 Interface._print_info("Condition %s imported" % args['-i'])
             except ModuleNotFoundError:
                 Interface._print_error("The condition %s is not in disk" %
                                        args['-i'])
                 print("(Please place your .py file in %s folder)\n" %
                       join(self._conds_path, cond))
                 return
Esempio n. 12
0
 def _field(self, command):
     """Manages the access an creation of `TField`."""
     if len(command) == 1:
         Interface.print_help(LayerInterface._field_help())
     elif len(command) == 2 and command[1].lower() in self._l.fieldnames():
         fi = FieldInterface(self._l.getfield(command[1].lower()),
                             self._tindex, self._l.name, self._poisoner)
         fi.run()
     else:
         cp = CommandParser(LayerInterface._field_opts())
         args = cp.parse(command)
         if not args:
             Interface._argument_error()
             return
         # Print the help
         if args["-h"]:
             Interface.print_help(LayerInterface._field_help())
         # Adds a new field
         elif args["-a"]:
             Interface.color_dump(self._l.raw, self._l.slice.start)
             start = input("Start byte of the custom field: ")
             end = input("End byte of the custom field: ")
             if not start.isdecimal() or not end.isdecimal():
                 Interface._print_error(
                     "The start or end byte is not a number")
                 return
             else:
                 fslice = slice(int(start), int(end))
                 fvalue = self._l.raw[fslice]
                 fsize = len(fvalue)
                 new_field = TField(name=args["-a"],
                                    value=fvalue,
                                    tslice=str(fslice).encode().hex(),
                                    custom=True,
                                    size=fsize,
                                    raw=self._l.raw.hex(),
                                    layer=self._l)
                 # Set the type
                 ftype = input("Field type [int/str/bytes/hex]: ")
                 if ftype == "int":
                     new_field.to_int()
                 elif ftype == "str":
                     new_field.to_str()
                 elif ftype == "hex":
                     new_field.to_hex()
                 elif ftype == "bytes":
                     new_field.to_bytes()
                 # Add the field to the layer
                 self._l.addfield(new_field)
                 Interface._print_info("Field %s added to the layer" %
                                       args['-a'])
         # Deletes a field from the layer
         elif args["-d"]:
             del_field = self._l.getfield(args["-d"])
             if del_field:
                 self._l.delfield(del_field)
                 Interface._print_info("Field %s deleted from the layer" %
                                       args["-d"])
             else:
                 Interface._print_error("The field %s is not in the layer" %
                                        args["-d"])
Esempio n. 13
0
 def _conditions(self, command, cond):
     """Manages the preconditions, postconditions and executions for a
     particular `Template`."""
     if len(command) == 1:
         self._t.show_conditions(cond)
         return
     # Parsing the arguments
     cp = CommandParser(TemplateInterface._conditions_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     if len(command) == 2:
         # Print the help
         if args['-h']:
             Interface.print_help(TemplateInterface._conditions_help(cond))
         # Show the source code
         elif args['-s']:
             self._t.show_conditions(cond, verbose=True)
         # Show all conditions on disk
         elif args['-sa']:
             self._t.show_all_conds(cond)
         # Show all conditions source on disk
         elif args['-sas']:
             self._t.show_all_conds(cond, verbose=True)
     else:
         # Select a specific condition
         if args['-c']:
             if args['-s']:
                 self._t.show_conditions(cond, args['-c'], True)
             elif args['-p']:
                 try:
                     index = int(args['-p'])
                     if index >= 0 and index < len(
                             self._t._functions[cond]):
                         self._t.change_cond_pos(cond, args['-c'], index)
                     else:
                         Interface._print_error("Wrong index")
                 except ValueError:
                     Interface._print_error(
                         "Please enter a positive integer")
         # Deletes a condition
         if args['-d']:
             try:
                 self._t.del_function(cond, args['-d'])
                 Interface._print_info("Condition %s deleted" % args['-d'])
             except KeyError:
                 Interface._print_error(
                     "The condition %s is not in the list" % args['-d'])
                 return
         # Adds a condition
         elif args['-a']:
             # Create the new file if not exists
             if not os.path.isfile(
                     join(self._conds_path, cond, args["-a"] + ".py")):
                 self._create_cond(cond, args["-a"])
             ret = os.system(
                 "%s %s.py" %
                 (args["-e"], join(self._conds_path, cond, args["-a"])))
             if ret != 0:
                 Interface._print_error(
                     "The editor is not installed or is not in the PATH")
                 return
             # Save the condition to the Template
             try:
                 self._add_cond(cond, args["-a"])
             except:
                 Interface._print_error(
                     "Bad syntax, please check the code syntax")
                 return
             # If user wants, delete condition from disk
             keepindisk = confirm('Keep file on disk (%s)? [y/N] ' %
                                  join(self._conds_path, cond))
             if not keepindisk:
                 os.remove("%s.py" %
                           join(self._conds_path, cond, args["-a"]))
             Interface._print_info("Condition %s added" % args["-a"])
         # Imports a condition from disk
         elif args['-i']:
             name = args['-i']
             if "/" in name or "\\" in name:
                 if os.path.isfile(name):
                     file = os.path.split(name)[-1]
                     copyfile(name, join(self._conds_path, cond, file))
                     name = file
             if name[-3:] == ".py":
                 name = name[:-3]
             try:
                 self._add_cond(cond, name)
                 Interface._print_info("Condition %s imported" % args['-i'])
             except ModuleNotFoundError:
                 Interface._print_error("The condition %s is not in disk" %
                                        args['-i'])
                 print("(Please place your .py file in correct path)")
                 return
Esempio n. 14
0
 def run(self):
     """Runs the interface and waits for user input commands."""
     completer = WordCompleter([
         'show', 'name', 'layer', 'dump', 'layers', 'functions',
         'intercept', 'timestamp', 'version', 'save', 'description',
         'spoof', 'clear', 'back'
     ])
     # Initialization of the command history
     history = FileHistory(join(self._polym_path, '.tinterface_history'))
     session = PromptSession(history=history)
     while True:
         try:
             command = session.prompt(
                 HTML("<bold>PH:cap/<red>t%d</red> > </bold>" %
                      self._index),
                 completer=completer,
                 complete_style=CompleteStyle.READLINE_LIKE,
                 auto_suggest=AutoSuggestFromHistory(),
                 enable_history_search=True)
         except KeyboardInterrupt:
             self.exit_program()
             continue
         try:
             command = command.rstrip().split(" ")
             if command[0] in self.EXIT:
                 self.exit_program()
             elif command[0] in self.RET:
                 answer = confirm(
                     "Are you sure you want to leave this interface?\n"
                     "If you have not saved the template you will lose"
                     " the changes")
                 if answer:
                     break
                 print("")
             elif command[0] == "name":
                 self._name(command)
             elif command[0] in ["dump", "d"]:
                 self._dump(command)
             elif command[0] in ["layer", "l"]:
                 self._layer(command)
             elif command[0] in ['funcs', 'functions']:
                 self._function(command)
             elif command[0] in ["show", "s"]:
                 self._show(command)
             elif command[0] in ["intercept", "i"]:
                 self._intercept(command)
             elif command[0] in ["layers", "ls"]:
                 self._layers(command)
             elif command[0] == "timestamp":
                 print(self._t.timestamp, '\n')
             elif command[0] == "version":
                 self._version(command)
             elif command[0] in ['desc', 'description']:
                 self._description(command)
             elif command[0] == "save":
                 self._save(command)
             elif command[0] in ["spoof"]:
                 self._spoof(command)
             elif command[0] == "clear":
                 Interface._clear()
             elif command[0] == "":
                 continue
             else:
                 Interface._wrong_command()
         except SystemExit:
             raise
         except Exception as e:
             Interface._print_error(
                 "Exception: Error processing the previous command. More info:"
             )
             print(e)
Esempio n. 15
0
 def _function(self, command):
     """Manages the functions for particular `Template`."""
     if len(command) == 1:
         self._t.show_functions()
         return
     # Parsing the arguments
     cp = CommandParser(TemplateInterface._function_opts())
     args = cp.parse(command)
     if not args:
         Interface._argument_error()
         return
     if len(command) == 2:
         # Print the help
         if args['-h']:
             Interface.print_help(TemplateInterface._function_help())
         # Show the source code
         elif args['-s']:
             self._t.show_functions(verbose=True)
         # Show all functions on disk
         elif args['-sa']:
             self._t.show_all_funcs()
         # Show all functions source on disk
         elif args['-sas']:
             self._t.show_all_funcs(verbose=True)
     else:
         # Select a specific function
         if args['-c']:
             if args['-c'].isdecimal():
                 if int(args['-c']) in range(len(self._t._functions)):
                     if args['-s']:
                         self._t.show_functions(int(args['-c']), True)
                     elif args['-p']:
                         try:
                             newindex = int(args['-p'])
                             if newindex >= 0 and newindex < len(
                                     self._t._functions):
                                 self._t.change_func_pos(
                                     int(args['-c']), newindex)
                             else:
                                 Interface._print_error("Wrong index")
                         except ValueError:
                             Interface._print_error(
                                 "Please enter a positive integer")
                 else:
                     Interface._print_error(
                         "The function %s is not in the list" %
                         str(args['-d']))
                     return
             else:
                 Interface._print_error(
                     "Please enter the function order number")
                 return
         # Deletes a function
         if args['-d']:
             try:
                 if args['-d'].isdecimal():
                     if int(args['-d']) in range(len(self._t._functions)):
                         self._t.del_function(int(args['-d']))
                         Interface._print_info("Function %s deleted" %
                                               str(args['-d']))
                     else:
                         Interface._print_error(
                             "The function %s is not in the list" %
                             str(args['-d']))
                         return
                 else:
                     Interface._print_error(
                         "Please enter the function order number")
                     return
             except:
                 Interface._print_error("Error deleting the function")
                 return
         # Adds a function
         elif args['-a']:
             # Create the new file if not exists
             if not os.path.isfile(
                     join(self._funcs_path, args["-a"] + ".py")):
                 self._create_func(args["-a"])
             ret = os.system(
                 "%s %s.py" %
                 (args["-e"], join(self._funcs_path, args["-a"])))
             if ret != 0:
                 Interface._print_error(
                     "The editor is not installed or is not in the PATH")
                 return
             # Save the function to the Template
             try:
                 self._add_func(args["-a"])
             except:
                 Interface._print_error(
                     "Bad syntax, please check the code syntax")
                 return
             Interface._print_info("Function %s added" % args["-a"])
         # Imports a function from disk
         elif args['-i']:
             name = args['-i']
             if "/" in name or "\\" in name:
                 if os.path.isfile(name):
                     file = os.path.split(name)[-1]
                     copyfile(name, join(self._funcs_path, file))
                     name = file
             if name[-3:] == ".py":
                 name = name[:-3]
             try:
                 self._add_func(name)
                 Interface._print_info("Function %s imported" % args['-i'])
             except ModuleNotFoundError:
                 Interface._print_error("The function %s is not in disk" %
                                        args['-i'])
                 print("(Please place your .py file in correct path)")
                 return