Friday, May 5, 2023

How to Uninstall Microsoft Edge Browser Completely

How to Uninstall Microsoft Edge Browser Completely

  • Warning: Take a backup of existing system before you perform these steps. It comes with no warranty.
  • Restart Windows 11 in safe mode (try web search restart windows 11 safe mode)
  • Explore to C:\Program Files (x86)\Microsoft\
  • Select All directories and press Delete.
  • Press Continue if asked.

 


  • Restart the system in Normal mode.
  • Install other browser of your choice. [For eg: Librewolf https://librewolf.net/installation/windows/]
  • Note1: Some applications may stop working.
  • Note2: There are lot of methods available online for uninstalling Edge Browser of which none of them works. For eg:
    • "C:\Program Files (x86)\Microsoft\Edge\Application\112.0.1722.58\Installer\setup.exe" --uninstall --system-level --verbose-logging --force-uninstall
    • Remove-AppxPackage <Full Package Name> 
    • and some some registry tweaks.

Tuesday, March 21, 2023

Linux: Mute Notifications while on a Zoom Conference.

 

There is a problem while on a zoom share suddenly notification message pops-up however you do not want other to see.

The following script will check if the zoom is on a meeting and disable notifications for dunst and gnome. Bonus: This will also disable hide the top bar if the extension 'hidetopbar@mathieu.bidon.ca' is installed.

Saturday, September 18, 2021

Flood Fill 4-directional using Java

How it works?
Flood-fill (node):
  1. Set Q to the empty queue or stack.
  2. Add the current node to the end of Q.
  3. While Q is not empty:
  4.   Set n equal to the first element of Q.
  5.   Remove first element from Q.
  6.   If n is Inside:
         Set the n
         Add the node to the north of n to the end of Q.
         Add the node to the south of n to the end of Q.
         Add the node to the west of n to the end of Q.
         Add the node to the east of n to the end of Q.
  7. Continue looping until Q is exhausted.
  8. Return.

package samples;

import java.util.ArrayDeque;
import java.util.Queue;

public class FloodFill {

public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {

int oldColor = image[sr][sc];
if (oldColor == newColor)
return image;

Queue<Pair> queue = new ArrayDeque();
queue.add(new Pair(sr, sc));

while (!queue.isEmpty()) {

Pair p = queue.poll();
if (isInside(image, p.i, p.j, oldColor))
set(image, p.i, p.j, newColor);

// up -> row-1
if (isInside(image, p.i - 1, p.j, oldColor))
queue.add(new Pair(p.i - 1, p.j));

// down -> row+1
if (isInside(image, p.i + 1, p.j, oldColor))
queue.add(new Pair(p.i + 1, p.j));

// left -> col-1
if (isInside(image, p.i, p.j - 1, oldColor))
queue.add(new Pair(p.i, p.j - 1));

// right -> col+1
if (isInside(image, p.i, p.j + 1, oldColor))
queue.add(new Pair(p.i, p.j + 1));

}


return image;
}

/**
* Set the new color at row i and column j
*/
private void set(int[][] image, int i, int j, int newColor) {
image[i][j] = newColor;
}


/**
* @return Returns true if (i,j) inside the matrix and of the same old color.
*/
private boolean isInside(int[][] image, int i, int j, int oldColor) {
if (i > -1 && i < image.length && j > -1 && j < image[0].length && image[i][j] == oldColor)
return true;
else
return false;
}
}

class Pair {
int i;
int j;

public Pair(int i, int j) {
this.i = i;
this.j = j;
}
}


Thursday, August 29, 2019

Getting Split-Tunneling in Linux to work








In general when you are connected to virtual private network of your office without split tunneling, all the data will go through your vpn network interface.
Problems:
  1. It makes your system network to work slow as all the data will go through the vpn network.
  2. There might be some domains, websites which might be restricted on vpn network. For eg torrent application is running which might be prohibited in your office network.
The purpose of this article is to allow normal internet traffic via systems default network interface (eth0) and private network traffic via vpn interface (vpn0).

Next >>

The first thing to make sure is that once vpn is connected that it should not be your default route gateway.
This is achieved using vpn profile in Network Manager. Go through the vpn profile in Network Manager settings and check the box as shown below.



Next >>

The route table should look like this. Note the default traffic is still going through eth0 as per the table.

$ route -n
Kernel IP routing table
Destination  Gateway     Genmask Flags Metric Ref Use Iface
0.0.0.0      192.168.0.1 0.0.0.0 UG 600 0 0 eth0
10.193.199.0 0.0.0.0     255.255.224.0 U 50 0 0 vpn0
169.254.0.0  0.0.0.0     255.255.0.0 U 1000 0 0 eth0
192.168.0.0  0.0.0.0     255.255.255.0 U 600 0 0 eth0
192.168.0.1  0.0.0.0     255.255.255.255 UH 600 0 0 eth0
196.11.21.67 192.168.0.1 255.255.255.255 UGH 600 0 0 eth0

0.0.0.0 is the default route, any route which is not matching will end up in this route and go through it.
There may be some extra routes added by the vpn client, so you can keep them. Some VPN servers push the routes from the VPN server so as to make sure the particular range of IP traffic always go through the particular route.
  1. 10.193.199.0 is the endpoint IP through which the vpn traffic flows in and out. This is an internally assigned IP by vpn server. Each and every vpn client will get a different IP.
  2. 196.11.21.67 is the public IP through which the vpn traffic flows via internet. This IP will be common throughout all vpn clients and usually this is the vpn public server IP.

Next >>

Integrate custom script into the system default behavior whenever a vpn client connection is established and terminated.
Let’s assume you have created a vpnscript.
$HOME/bin/vpnscript.sh

#!/bin/sh
# Don't run until we bring up a real network device
[ "$IFACE" != "lo" ] || exit 0
if [ "$IFACE" = "vpn0" ]; then
if [ "$MODE" = "start" ] && [ "$ADDRFAM" = "inet" ]; then
/home/<user>/bin/routes.sh
fi
if [ "$MODE" = "stop" ] && [ "$ADDRFAM" = "inet" ]; then
#do something else
fi
fi
Make the vpnscript functional. You can also copy these scripts to a permanent place. Change $HOME to an absolute path..

sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-up.d/
sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-down.d/
sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-post-down.d/


$HOME/bin/routes.sh
route add vpnsystem.domain.com dev vpn0
route add vpnsystem2.domain.com dev vpn0
route add VPN.SYSTEM.IP.0 dev vpn0
route add dns.vpn.ip dev vpn0
...
...
...

dns.vpn.ip could be your vpn dns server, this would also be populated into /etc/resolv.conf once vpn is connected. You can also use two dns servers in this order to make sure if the dns lookup fails in the public server then the VPN dns server is tried for lookup.
  Public/Default DNS server
  VPN DNS server

Manually enter the hosts entries which are contacted frequently. This may not be required if you are only using DNS server approach.

/etc/hosts


10.2.3.4 vpnsystem.domain.com
10.2.3.4 vpnsystem2.domain.com
..
..
..

Woof!! That is a lot of networking system but not too much for a networking expert.
Now take a pause and lets understand before moving forward.

Scenario 1:
You want to surf https://www.wikipedia.org
The public dns server will resolve your dns query to a public IP and the internet traffic goes via eth0

Scenario 2:
You want to do ssh to somesystem.domain.com
The dns query to somesystem.domain.com will fail first via public IP then the system will try to resolve dns query using vpn dns server which will eventually resolve to an IP.
Hint: Try this command first to make sure the dns query is working properly for a vpn domain.

$ dig somesystem.domain.com
; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> somesystem.domain.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11024
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;somesystem.domain.com. IN A
;; ANSWER SECTION:
somesystem.domain.com. 600 IN A 10.12.20.23
;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Thu Aug 29 20:48:41 IST 2019
;; MSG SIZE rcvd: 78

After the IP is resolved to 10.12.20.23, the system will check if there a specific route in the routing table. If it is there then it will go through that interface, otherwise the ssh will try to connect it through default route which is eth0.
If it fails then you have to add the route manually like this.

$ sudo route add 10.12.20.23 dev vpn0
#also add it in routes.sh for future use.


Next >>

Seamless browsing in Firefox/Chrome without worrying about the data traffic. This will also work if your VPN provider has http proxy. In my case I will use socks5 proxy.
  • Install the FoxyProxy Extension/Add-on
  • Select the default mode User proxies based on their pre-defined patterns and priorities.
  • Add a proxy for your vpn provider and enter details.
  • Add the pattern rules for this proxy, for eg: *.domain.com*
  • If there is an option to use proxy for dns then select this option to make sure private domains are resolved via this proxy.
  • Great enjoy!!
Socks5 proxy using ssh
$ ssh -D 5353 -o ConnectTimeout=10 -o ConnectionAttempts=1 -C -N user@somesystem.domain.com
# -D dynamic socks5 port
# -C compression
# -o for extra option
# -N do not execute any remote command

Monday, September 17, 2018

Simplified Breadth-first Search

Simplified Breadth-first Search

Given a graph G = (V, E) and a distinguished source vertex s, breadth-first search systematically explores the edges of G to “discover” every vertex that is reachable from s. It computes the distance (smallest number of edges) from s to each reachable vertex. It also produces a “breadth-first tree” with root s that contains all reachable vertices. For any vertex reachable from s, the simple path in the breadth-first tree from s to corresponds to a “shortest path” from s to v in G, that is, a path containing the smallest number of edges. The algorithm works on both directed and undirected graphs.

Python

class Graph:
  def __init__(self, nodes):
      self.nodes = nodes
      self.edges = 0
      self.adj = [[] for i in range(self.nodes)]

  def addEdge(self, v, w):
      self.adj[v].append(w)
      self.edges += 1

  def bfs(self, startingNode):
      from queue import Queue
      seen = [False for i in range(self.nodes)]
      q = Queue()
      q.put(startingNode)
      while not q.empty():
          node = q.get()
          print(node, end=", ")
          seen[node] = True
          for neighbour in self.adj[node]:
              if not seen[neighbour]:
                  q.put(neighbour)