@fredlackey/devutils 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/README.md +5 -5
  2. package/package.json +1 -1
  3. package/src/commands/install.js +374 -36
  4. package/src/installs/adobe-creative-cloud.js +527 -25
  5. package/src/installs/adobe-creative-cloud.md +605 -0
  6. package/src/installs/appcleaner.js +303 -26
  7. package/src/installs/appcleaner.md +699 -0
  8. package/src/installs/apt-transport-https.js +390 -0
  9. package/src/installs/apt-transport-https.md +678 -0
  10. package/src/installs/atomicparsley.js +624 -26
  11. package/src/installs/atomicparsley.md +795 -0
  12. package/src/installs/aws-cli.js +779 -26
  13. package/src/installs/aws-cli.md +727 -0
  14. package/src/installs/balena-etcher.js +688 -26
  15. package/src/installs/balena-etcher.md +761 -0
  16. package/src/installs/bambu-studio.js +912 -26
  17. package/src/installs/bambu-studio.md +780 -0
  18. package/src/installs/bash-completion.js +554 -23
  19. package/src/installs/bash-completion.md +833 -0
  20. package/src/installs/bash.js +399 -26
  21. package/src/installs/bash.md +993 -0
  22. package/src/installs/beyond-compare.js +585 -26
  23. package/src/installs/beyond-compare.md +813 -0
  24. package/src/installs/build-essential.js +511 -26
  25. package/src/installs/build-essential.md +977 -0
  26. package/src/installs/ca-certificates.js +618 -0
  27. package/src/installs/ca-certificates.md +937 -0
  28. package/src/installs/caffeine.js +490 -26
  29. package/src/installs/caffeine.md +839 -0
  30. package/src/installs/camtasia.js +577 -25
  31. package/src/installs/camtasia.md +762 -0
  32. package/src/installs/chatgpt.js +458 -26
  33. package/src/installs/chatgpt.md +814 -0
  34. package/src/installs/chocolatey.js +447 -0
  35. package/src/installs/chocolatey.md +661 -0
  36. package/src/installs/chrome-canary.js +472 -26
  37. package/src/installs/chrome-canary.md +641 -0
  38. package/src/installs/chromium.js +645 -26
  39. package/src/installs/chromium.md +838 -0
  40. package/src/installs/claude-code.js +558 -26
  41. package/src/installs/claude-code.md +1173 -0
  42. package/src/installs/curl.js +361 -26
  43. package/src/installs/curl.md +714 -0
  44. package/src/installs/cursor.js +561 -26
  45. package/src/installs/cursor.md +970 -0
  46. package/src/installs/dbschema.js +674 -26
  47. package/src/installs/dbschema.md +925 -0
  48. package/src/installs/dependencies.md +435 -0
  49. package/src/installs/development-tools.js +600 -0
  50. package/src/installs/development-tools.md +977 -0
  51. package/src/installs/docker.js +1010 -25
  52. package/src/installs/docker.md +1109 -0
  53. package/src/installs/drawio.js +1001 -26
  54. package/src/installs/drawio.md +795 -0
  55. package/src/installs/elmedia-player.js +328 -25
  56. package/src/installs/elmedia-player.md +556 -0
  57. package/src/installs/ffmpeg.js +870 -25
  58. package/src/installs/ffmpeg.md +852 -0
  59. package/src/installs/file.js +464 -0
  60. package/src/installs/file.md +987 -0
  61. package/src/installs/gemini-cli.js +793 -26
  62. package/src/installs/gemini-cli.md +1153 -0
  63. package/src/installs/git.js +382 -26
  64. package/src/installs/git.md +907 -0
  65. package/src/installs/gitego.js +931 -26
  66. package/src/installs/gitego.md +1172 -0
  67. package/src/installs/go.js +913 -26
  68. package/src/installs/go.md +958 -0
  69. package/src/installs/google-chrome.js +801 -25
  70. package/src/installs/google-chrome.md +862 -0
  71. package/src/installs/gpg.js +412 -73
  72. package/src/installs/gpg.md +1056 -0
  73. package/src/installs/homebrew.js +1015 -26
  74. package/src/installs/homebrew.md +988 -0
  75. package/src/installs/imageoptim.js +950 -26
  76. package/src/installs/imageoptim.md +1119 -0
  77. package/src/installs/installers.json +2297 -0
  78. package/src/installs/jq.js +382 -26
  79. package/src/installs/jq.md +809 -0
  80. package/src/installs/keyboard-maestro.js +701 -26
  81. package/src/installs/keyboard-maestro.md +825 -0
  82. package/src/installs/latex.js +771 -26
  83. package/src/installs/latex.md +1095 -0
  84. package/src/installs/lftp.js +338 -26
  85. package/src/installs/lftp.md +907 -0
  86. package/src/installs/lsb-release.js +346 -0
  87. package/src/installs/lsb-release.md +814 -0
  88. package/src/installs/messenger.js +829 -26
  89. package/src/installs/messenger.md +900 -0
  90. package/src/installs/microsoft-office.js +550 -26
  91. package/src/installs/microsoft-office.md +760 -0
  92. package/src/installs/microsoft-teams.js +782 -25
  93. package/src/installs/microsoft-teams.md +886 -0
  94. package/src/installs/node.js +886 -26
  95. package/src/installs/node.md +1153 -0
  96. package/src/installs/nordpass.js +698 -26
  97. package/src/installs/nordpass.md +921 -0
  98. package/src/installs/nvm.js +977 -26
  99. package/src/installs/nvm.md +1057 -0
  100. package/src/installs/openssh.js +734 -64
  101. package/src/installs/openssh.md +1056 -0
  102. package/src/installs/pandoc.js +644 -26
  103. package/src/installs/pandoc.md +1036 -0
  104. package/src/installs/pinentry.js +492 -26
  105. package/src/installs/pinentry.md +1142 -0
  106. package/src/installs/pngyu.js +851 -26
  107. package/src/installs/pngyu.md +896 -0
  108. package/src/installs/postman.js +781 -26
  109. package/src/installs/postman.md +940 -0
  110. package/src/installs/procps.js +425 -0
  111. package/src/installs/procps.md +851 -0
  112. package/src/installs/safari-tech-preview.js +355 -25
  113. package/src/installs/safari-tech-preview.md +533 -0
  114. package/src/installs/sfnt2woff.js +640 -26
  115. package/src/installs/sfnt2woff.md +795 -0
  116. package/src/installs/shellcheck.js +463 -26
  117. package/src/installs/shellcheck.md +1005 -0
  118. package/src/installs/slack.js +722 -25
  119. package/src/installs/slack.md +865 -0
  120. package/src/installs/snagit.js +566 -25
  121. package/src/installs/snagit.md +844 -0
  122. package/src/installs/software-properties-common.js +372 -0
  123. package/src/installs/software-properties-common.md +805 -0
  124. package/src/installs/spotify.js +858 -25
  125. package/src/installs/spotify.md +901 -0
  126. package/src/installs/studio-3t.js +803 -26
  127. package/src/installs/studio-3t.md +918 -0
  128. package/src/installs/sublime-text.js +780 -25
  129. package/src/installs/sublime-text.md +914 -0
  130. package/src/installs/superwhisper.js +687 -25
  131. package/src/installs/superwhisper.md +630 -0
  132. package/src/installs/tailscale.js +727 -26
  133. package/src/installs/tailscale.md +1100 -0
  134. package/src/installs/tar.js +389 -0
  135. package/src/installs/tar.md +946 -0
  136. package/src/installs/termius.js +780 -26
  137. package/src/installs/termius.md +844 -0
  138. package/src/installs/terraform.js +761 -26
  139. package/src/installs/terraform.md +899 -0
  140. package/src/installs/tidal.js +752 -25
  141. package/src/installs/tidal.md +864 -0
  142. package/src/installs/tmux.js +328 -26
  143. package/src/installs/tmux.md +1030 -0
  144. package/src/installs/tree.js +393 -26
  145. package/src/installs/tree.md +833 -0
  146. package/src/installs/unzip.js +460 -0
  147. package/src/installs/unzip.md +879 -0
  148. package/src/installs/vim.js +403 -26
  149. package/src/installs/vim.md +1040 -0
  150. package/src/installs/vlc.js +803 -26
  151. package/src/installs/vlc.md +927 -0
  152. package/src/installs/vscode.js +825 -26
  153. package/src/installs/vscode.md +1002 -0
  154. package/src/installs/wget.js +415 -0
  155. package/src/installs/wget.md +791 -0
  156. package/src/installs/whatsapp.js +710 -25
  157. package/src/installs/whatsapp.md +854 -0
  158. package/src/installs/winpty.js +352 -0
  159. package/src/installs/winpty.md +620 -0
  160. package/src/installs/woff2.js +535 -26
  161. package/src/installs/woff2.md +977 -0
  162. package/src/installs/wsl.js +572 -0
  163. package/src/installs/wsl.md +699 -0
  164. package/src/installs/xcode-clt.js +520 -0
  165. package/src/installs/xcode-clt.md +351 -0
  166. package/src/installs/xcode.js +542 -26
  167. package/src/installs/xcode.md +573 -0
  168. package/src/installs/yarn.js +806 -26
  169. package/src/installs/yarn.md +1074 -0
  170. package/src/installs/yq.js +636 -26
  171. package/src/installs/yq.md +944 -0
  172. package/src/installs/yt-dlp.js +683 -26
  173. package/src/installs/yt-dlp.md +946 -0
  174. package/src/installs/yum-utils.js +297 -0
  175. package/src/installs/yum-utils.md +648 -0
  176. package/src/installs/zoom.js +740 -25
  177. package/src/installs/zoom.md +884 -0
  178. package/src/scripts/README.md +567 -45
  179. package/src/scripts/STATUS.md +208 -0
  180. package/src/scripts/afk.js +395 -7
  181. package/src/scripts/backup-all.js +731 -9
  182. package/src/scripts/backup-source.js +711 -8
  183. package/src/scripts/brewd.js +373 -7
  184. package/src/scripts/brewi.js +505 -9
  185. package/src/scripts/brewr.js +512 -9
  186. package/src/scripts/brews.js +462 -9
  187. package/src/scripts/brewu.js +488 -7
  188. package/src/scripts/c.js +185 -7
  189. package/src/scripts/ccurl.js +325 -8
  190. package/src/scripts/certbot-crontab-init.js +488 -8
  191. package/src/scripts/certbot-init.js +641 -9
  192. package/src/scripts/ch.js +339 -7
  193. package/src/scripts/claude-danger.js +253 -8
  194. package/src/scripts/clean-dev.js +419 -8
  195. package/src/scripts/clear-dns-cache.js +525 -7
  196. package/src/scripts/clone.js +417 -7
  197. package/src/scripts/code-all.js +420 -7
  198. package/src/scripts/count-files.js +195 -8
  199. package/src/scripts/count-folders.js +195 -8
  200. package/src/scripts/count.js +248 -8
  201. package/src/scripts/d.js +203 -7
  202. package/src/scripts/datauri.js +373 -8
  203. package/src/scripts/delete-files.js +363 -7
  204. package/src/scripts/docker-clean.js +410 -8
  205. package/src/scripts/dp.js +426 -7
  206. package/src/scripts/e.js +375 -9
  207. package/src/scripts/empty-trash.js +497 -7
  208. package/src/scripts/evm.js +428 -9
  209. package/src/scripts/fetch-github-repos.js +441 -10
  210. package/src/scripts/get-channel.js +329 -8
  211. package/src/scripts/get-course.js +384 -11
  212. package/src/scripts/get-dependencies.js +290 -9
  213. package/src/scripts/get-folder.js +783 -10
  214. package/src/scripts/get-tunes.js +411 -10
  215. package/src/scripts/get-video.js +352 -9
  216. package/src/scripts/git-backup.js +561 -9
  217. package/src/scripts/git-clone.js +477 -9
  218. package/src/scripts/git-pup.js +303 -7
  219. package/src/scripts/git-push.js +380 -8
  220. package/src/scripts/h.js +607 -9
  221. package/src/scripts/hide-desktop-icons.js +483 -7
  222. package/src/scripts/hide-hidden-files.js +522 -7
  223. package/src/scripts/install-dependencies-from.js +440 -9
  224. package/src/scripts/ips.js +647 -10
  225. package/src/scripts/iso.js +354 -8
  226. package/src/scripts/killni.js +561 -7
  227. package/src/scripts/ll.js +451 -8
  228. package/src/scripts/local-ip.js +310 -8
  229. package/src/scripts/m.js +508 -8
  230. package/src/scripts/map.js +293 -8
  231. package/src/scripts/mkd.js +287 -7
  232. package/src/scripts/ncu-update-all.js +441 -8
  233. package/src/scripts/nginx-init.js +702 -12
  234. package/src/scripts/npmi.js +366 -7
  235. package/src/scripts/o.js +495 -8
  236. package/src/scripts/org-by-date.js +321 -7
  237. package/src/scripts/p.js +208 -7
  238. package/src/scripts/packages.js +313 -8
  239. package/src/scripts/path.js +209 -7
  240. package/src/scripts/ports.js +582 -8
  241. package/src/scripts/q.js +290 -8
  242. package/src/scripts/refresh-files.js +378 -10
  243. package/src/scripts/remove-smaller-files.js +500 -8
  244. package/src/scripts/rename-files-with-date.js +517 -9
  245. package/src/scripts/resize-image.js +523 -9
  246. package/src/scripts/rm-safe.js +653 -8
  247. package/src/scripts/s.js +525 -9
  248. package/src/scripts/set-git-public.js +349 -7
  249. package/src/scripts/show-desktop-icons.js +459 -7
  250. package/src/scripts/show-hidden-files.js +456 -7
  251. package/src/scripts/tpa.js +265 -8
  252. package/src/scripts/tpo.js +264 -7
  253. package/src/scripts/u.js +489 -7
  254. package/src/scripts/vpush.js +422 -8
  255. package/src/scripts/y.js +267 -7
  256. package/src/utils/common/os.js +94 -2
  257. package/src/utils/ubuntu/apt.js +13 -7
  258. package/src/utils/windows/choco.js +82 -26
  259. package/src/utils/windows/winget.js +89 -27
@@ -1,26 +1,663 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Scan local network for active IPs using nmap.
4
+ * ips - Scan local network for active IP addresses using nmap
5
+ *
6
+ * Migrated from legacy dotfiles function.
7
+ * Original:
8
+ * ips(){
9
+ * local usage="ips [%NETWORK_BASE_IP%] [%BIT_DEPTH%] [ip-only | no-sudo]"
10
+ * local addr="$1";
11
+ * local mask="$2";
12
+ * ...
13
+ * eval "${prefix}nmap $addr/$mask -n -sP${suffix}"
14
+ * }
15
+ *
16
+ * This script scans the local network to discover active hosts using nmap.
17
+ * It performs a ping scan (-sP or -sn) to find which IP addresses are responding.
18
+ *
19
+ * Usage:
20
+ * ips # Scan 192.168.1.0/24 (default)
21
+ * ips 10.0.0.0 16 # Scan 10.0.0.0/16
22
+ * ips ip-only # Show only IP addresses, not full report
23
+ * ips no-sudo # Run without sudo (may miss some hosts)
24
+ * ips 192.168.1.0 24 ip-only # Combine options
25
+ * ips help # Show usage information
26
+ *
5
27
  * @module scripts/ips
6
28
  */
7
29
 
30
+ const os = require('../utils/common/os');
31
+ const { execSync, spawnSync } = require('child_process');
32
+
33
+ // Default network configuration
34
+ const DEFAULT_IP = '192.168.1.0';
35
+ const DEFAULT_MASK = 24;
36
+ const MIN_MASK = 4;
37
+ const MAX_MASK = 30;
38
+
39
+ /**
40
+ * Helper function to check if a command exists on the system.
41
+ * Uses platform-appropriate command checking.
42
+ *
43
+ * @param {string} cmd - The command name to check
44
+ * @returns {boolean} True if the command exists, false otherwise
45
+ */
46
+ function isCommandAvailable(cmd) {
47
+ try {
48
+ // Use 'which' on Unix-like systems, 'where' on Windows
49
+ const checkCmd = process.platform === 'win32' ? `where ${cmd}` : `which ${cmd}`;
50
+ execSync(checkCmd, { stdio: 'ignore' });
51
+ return true;
52
+ } catch {
53
+ return false;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Validates an IPv4 address format.
59
+ * Checks if the string matches the pattern X.X.X.X where X is 0-255.
60
+ *
61
+ * @param {string} ip - The IP address string to validate
62
+ * @returns {boolean} True if valid IPv4 format, false otherwise
63
+ */
64
+ function isValidIPv4(ip) {
65
+ if (!ip || typeof ip !== 'string') {
66
+ return false;
67
+ }
68
+ // Match IPv4 pattern: four octets separated by dots
69
+ const ipv4Regex = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
70
+ const match = ip.match(ipv4Regex);
71
+ if (!match) {
72
+ return false;
73
+ }
74
+ // Check each octet is in valid range (0-255)
75
+ for (let i = 1; i <= 4; i++) {
76
+ const octet = parseInt(match[i], 10);
77
+ if (octet < 0 || octet > 255) {
78
+ return false;
79
+ }
80
+ }
81
+ return true;
82
+ }
83
+
84
+ /**
85
+ * Validates a subnet mask value.
86
+ * Must be a number between MIN_MASK and MAX_MASK (typically 4-30).
87
+ *
88
+ * @param {string|number} mask - The subnet mask to validate
89
+ * @returns {boolean} True if valid mask, false otherwise
90
+ */
91
+ function isValidMask(mask) {
92
+ const maskNum = parseInt(mask, 10);
93
+ return !isNaN(maskNum) && maskNum >= MIN_MASK && maskNum <= MAX_MASK;
94
+ }
95
+
96
+ /**
97
+ * Parses command line arguments to extract IP, mask, and options.
98
+ * Arguments can be in any order - the function detects what each argument is.
99
+ *
100
+ * @param {string[]} args - Command line arguments
101
+ * @returns {{ ip: string, mask: number, ipOnly: boolean, noSudo: boolean, help: boolean }}
102
+ */
103
+ function parseArgs(args) {
104
+ const result = {
105
+ ip: DEFAULT_IP,
106
+ mask: DEFAULT_MASK,
107
+ ipOnly: false,
108
+ noSudo: false,
109
+ help: false
110
+ };
111
+
112
+ // Check for special flags first
113
+ const argsString = args.join(' ').toLowerCase();
114
+ if (argsString.includes('help') || argsString.includes('-h') || argsString.includes('--help')) {
115
+ result.help = true;
116
+ return result;
117
+ }
118
+ if (argsString.includes('ip-only')) {
119
+ result.ipOnly = true;
120
+ }
121
+ if (argsString.includes('no-sudo')) {
122
+ result.noSudo = true;
123
+ }
124
+
125
+ // Filter out option flags to find IP and mask
126
+ const filteredArgs = args.filter(arg => {
127
+ const lower = arg.toLowerCase();
128
+ return lower !== 'ip-only' && lower !== 'no-sudo' && lower !== 'help';
129
+ });
130
+
131
+ // First non-flag argument should be IP address
132
+ if (filteredArgs.length > 0) {
133
+ const potentialIp = filteredArgs[0];
134
+ if (isValidIPv4(potentialIp)) {
135
+ result.ip = potentialIp;
136
+ } else {
137
+ console.log(`Invalid IP address supplied: ${potentialIp}. Defaulting to ${DEFAULT_IP}.`);
138
+ }
139
+ }
140
+
141
+ // Second non-flag argument should be subnet mask
142
+ if (filteredArgs.length > 1) {
143
+ const potentialMask = filteredArgs[1];
144
+ if (isValidMask(potentialMask)) {
145
+ result.mask = parseInt(potentialMask, 10);
146
+ } else {
147
+ console.log(`Invalid mask supplied: ${potentialMask}. Defaulting to ${DEFAULT_MASK} bits.`);
148
+ }
149
+ }
150
+
151
+ return result;
152
+ }
153
+
154
+ /**
155
+ * Displays usage information for the ips command.
156
+ */
157
+ function showUsage() {
158
+ console.log('ips - Scan local network for active IP addresses');
159
+ console.log('');
160
+ console.log('Usage: ips [NETWORK_BASE_IP] [BIT_DEPTH] [OPTIONS]');
161
+ console.log('');
162
+ console.log('Arguments:');
163
+ console.log(' NETWORK_BASE_IP Network address to scan (default: 192.168.1.0)');
164
+ console.log(' BIT_DEPTH Subnet mask in CIDR notation, 4-30 (default: 24)');
165
+ console.log('');
166
+ console.log('Options:');
167
+ console.log(' ip-only Show only IP addresses, not full nmap report');
168
+ console.log(' no-sudo Run without sudo (may miss some hosts)');
169
+ console.log(' help, -h, --help Show this help message');
170
+ console.log('');
171
+ console.log('Examples:');
172
+ console.log(' ips # Scan 192.168.1.0/24 with sudo');
173
+ console.log(' ips 10.0.0.0 16 # Scan 10.0.0.0/16 with sudo');
174
+ console.log(' ips ip-only # Scan default network, show only IPs');
175
+ console.log(' ips no-sudo # Scan without sudo (less accurate)');
176
+ console.log(' ips 192.168.1.0 24 ip-only # Combine options');
177
+ console.log('');
178
+ console.log('Note: nmap must be installed. Without sudo, some hosts may not be detected.');
179
+ }
180
+
181
+ /**
182
+ * Extracts IP addresses from nmap output.
183
+ * Parses lines containing "Nmap scan report for X.X.X.X" and extracts the IP.
184
+ *
185
+ * @param {string} output - Raw nmap output
186
+ * @returns {string[]} Array of IP addresses found
187
+ */
188
+ function extractIpsFromOutput(output) {
189
+ const ips = [];
190
+ const lines = output.split('\n');
191
+ for (const line of lines) {
192
+ // nmap outputs: "Nmap scan report for 192.168.1.1"
193
+ // or sometimes: "Nmap scan report for hostname (192.168.1.1)"
194
+ const reportMatch = line.match(/Nmap scan report for\s+(?:\S+\s+\()?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/);
195
+ if (reportMatch) {
196
+ ips.push(reportMatch[1]);
197
+ } else {
198
+ // Simple IP on the line
199
+ const simpleMatch = line.match(/Nmap scan report for\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/);
200
+ if (simpleMatch) {
201
+ ips.push(simpleMatch[1]);
202
+ }
203
+ }
204
+ }
205
+ return ips;
206
+ }
207
+
208
+ /**
209
+ * Pure Node.js implementation - NOT FULLY APPLICABLE for this script.
210
+ *
211
+ * Network scanning requires the nmap tool which is a native OS command.
212
+ * While Node.js can do basic network operations, a full network scan
213
+ * requires nmap's capabilities (ARP scanning, ICMP, etc.).
214
+ *
215
+ * This function throws an error because nmap is required for proper scanning.
216
+ *
217
+ * @param {string[]} args - Command line arguments
218
+ * @returns {Promise<void>}
219
+ * @throws {Error} Always throws - nmap is required
220
+ */
221
+ async function do_ips_nodejs(args) {
222
+ throw new Error(
223
+ 'do_ips_nodejs should not be called directly. ' +
224
+ 'Network scanning requires the nmap tool which must be installed on the system.'
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Scan local network on macOS using nmap.
230
+ *
231
+ * macOS requires sudo for full ARP scanning capability. Without sudo,
232
+ * nmap falls back to TCP connect scanning which is slower and may miss hosts.
233
+ *
234
+ * @param {string[]} args - Command line arguments
235
+ * @returns {Promise<void>}
236
+ */
237
+ async function do_ips_macos(args) {
238
+ const options = parseArgs(args);
239
+
240
+ // Show help before checking for nmap - user might just want usage info
241
+ if (options.help) {
242
+ showUsage();
243
+ return;
244
+ }
245
+
246
+ // Check if nmap is installed
247
+ if (!isCommandAvailable('nmap')) {
248
+ console.error('Error: nmap is required but not installed.');
249
+ console.error('');
250
+ console.error('Install it with: brew install nmap');
251
+ process.exit(1);
252
+ }
253
+
254
+ // Build the nmap command
255
+ // -n: No DNS resolution (faster)
256
+ // -sn: Ping scan (host discovery only, no port scan) - replaces deprecated -sP
257
+ const target = `${options.ip}/${options.mask}`;
258
+ const nmapArgs = [target, '-n', '-sn'];
259
+
260
+ console.log(`Scanning ${target}...`);
261
+
262
+ try {
263
+ let result;
264
+ if (options.noSudo) {
265
+ // Run without sudo
266
+ result = spawnSync('nmap', nmapArgs, { encoding: 'utf8' });
267
+ } else {
268
+ // Run with sudo
269
+ result = spawnSync('sudo', ['nmap', ...nmapArgs], {
270
+ encoding: 'utf8',
271
+ stdio: ['inherit', 'pipe', 'pipe']
272
+ });
273
+ }
274
+
275
+ if (result.error) {
276
+ throw result.error;
277
+ }
278
+
279
+ const output = result.stdout || '';
280
+
281
+ if (options.ipOnly) {
282
+ // Extract and print only IP addresses
283
+ const ips = extractIpsFromOutput(output);
284
+ if (ips.length === 0) {
285
+ console.log('No hosts found.');
286
+ } else {
287
+ ips.forEach(ip => console.log(ip));
288
+ }
289
+ } else {
290
+ // Print full nmap output
291
+ console.log(output);
292
+ if (result.stderr) {
293
+ console.error(result.stderr);
294
+ }
295
+ }
296
+ } catch (error) {
297
+ console.error('Error running nmap:', error.message);
298
+ process.exit(1);
299
+ }
300
+ }
301
+
8
302
  /**
9
- * Scans the local network for active IP addresses using nmap.
10
- * Defaults to scanning 192.168.1.0/24.
303
+ * Scan local network on Ubuntu using nmap.
304
+ *
305
+ * Ubuntu installation typically uses apt to install nmap.
306
+ * Sudo is recommended for ARP-based host discovery.
11
307
  *
12
308
  * @param {string[]} args - Command line arguments
13
- * @param {string} [args.0] - Network base IP (default: "192.168.1.0")
14
- * @param {string} [args.1] - Subnet mask bits (default: "24")
15
- * @param {string} [args.2] - Options: "ip-only" or "no-sudo"
16
309
  * @returns {Promise<void>}
17
310
  */
18
- async function main(args) {
19
- // TODO: Implement network scanning
311
+ async function do_ips_ubuntu(args) {
312
+ const options = parseArgs(args);
313
+
314
+ // Show help before checking for nmap - user might just want usage info
315
+ if (options.help) {
316
+ showUsage();
317
+ return;
318
+ }
319
+
320
+ // Check if nmap is installed
321
+ if (!isCommandAvailable('nmap')) {
322
+ console.error('Error: nmap is required but not installed.');
323
+ console.error('');
324
+ console.error('Install it with: sudo apt install nmap');
325
+ process.exit(1);
326
+ }
327
+
328
+ const target = `${options.ip}/${options.mask}`;
329
+ const nmapArgs = [target, '-n', '-sn'];
330
+
331
+ console.log(`Scanning ${target}...`);
332
+
333
+ try {
334
+ let result;
335
+ if (options.noSudo) {
336
+ result = spawnSync('nmap', nmapArgs, { encoding: 'utf8' });
337
+ } else {
338
+ result = spawnSync('sudo', ['nmap', ...nmapArgs], {
339
+ encoding: 'utf8',
340
+ stdio: ['inherit', 'pipe', 'pipe']
341
+ });
342
+ }
343
+
344
+ if (result.error) {
345
+ throw result.error;
346
+ }
347
+
348
+ const output = result.stdout || '';
349
+
350
+ if (options.ipOnly) {
351
+ const ips = extractIpsFromOutput(output);
352
+ if (ips.length === 0) {
353
+ console.log('No hosts found.');
354
+ } else {
355
+ ips.forEach(ip => console.log(ip));
356
+ }
357
+ } else {
358
+ console.log(output);
359
+ if (result.stderr) {
360
+ console.error(result.stderr);
361
+ }
362
+ }
363
+ } catch (error) {
364
+ console.error('Error running nmap:', error.message);
365
+ process.exit(1);
366
+ }
367
+ }
368
+
369
+ /**
370
+ * Scan local network on Raspberry Pi OS using nmap.
371
+ *
372
+ * Raspberry Pi OS (Raspbian) uses apt for package management.
373
+ * This is identical to Ubuntu implementation.
374
+ *
375
+ * @param {string[]} args - Command line arguments
376
+ * @returns {Promise<void>}
377
+ */
378
+ async function do_ips_raspbian(args) {
379
+ const options = parseArgs(args);
380
+
381
+ // Show help before checking for nmap - user might just want usage info
382
+ if (options.help) {
383
+ showUsage();
384
+ return;
385
+ }
386
+
387
+ // Check if nmap is installed
388
+ if (!isCommandAvailable('nmap')) {
389
+ console.error('Error: nmap is required but not installed.');
390
+ console.error('');
391
+ console.error('Install it with: sudo apt install nmap');
392
+ process.exit(1);
393
+ }
394
+
395
+ const target = `${options.ip}/${options.mask}`;
396
+ const nmapArgs = [target, '-n', '-sn'];
397
+
398
+ console.log(`Scanning ${target}...`);
399
+
400
+ try {
401
+ let result;
402
+ if (options.noSudo) {
403
+ result = spawnSync('nmap', nmapArgs, { encoding: 'utf8' });
404
+ } else {
405
+ result = spawnSync('sudo', ['nmap', ...nmapArgs], {
406
+ encoding: 'utf8',
407
+ stdio: ['inherit', 'pipe', 'pipe']
408
+ });
409
+ }
410
+
411
+ if (result.error) {
412
+ throw result.error;
413
+ }
414
+
415
+ const output = result.stdout || '';
416
+
417
+ if (options.ipOnly) {
418
+ const ips = extractIpsFromOutput(output);
419
+ if (ips.length === 0) {
420
+ console.log('No hosts found.');
421
+ } else {
422
+ ips.forEach(ip => console.log(ip));
423
+ }
424
+ } else {
425
+ console.log(output);
426
+ if (result.stderr) {
427
+ console.error(result.stderr);
428
+ }
429
+ }
430
+ } catch (error) {
431
+ console.error('Error running nmap:', error.message);
432
+ process.exit(1);
433
+ }
434
+ }
435
+
436
+ /**
437
+ * Scan local network on Amazon Linux using nmap.
438
+ *
439
+ * Amazon Linux uses dnf or yum for package management.
440
+ * Network scanning from EC2 instances should respect AWS security policies.
441
+ *
442
+ * @param {string[]} args - Command line arguments
443
+ * @returns {Promise<void>}
444
+ */
445
+ async function do_ips_amazon_linux(args) {
446
+ const options = parseArgs(args);
447
+
448
+ // Show help before checking for nmap - user might just want usage info
449
+ if (options.help) {
450
+ showUsage();
451
+ return;
452
+ }
453
+
454
+ // Check if nmap is installed
455
+ if (!isCommandAvailable('nmap')) {
456
+ console.error('Error: nmap is required but not installed.');
457
+ console.error('');
458
+ console.error('Install it with: sudo dnf install nmap');
459
+ console.error(' or: sudo yum install nmap');
460
+ process.exit(1);
461
+ }
462
+
463
+ const target = `${options.ip}/${options.mask}`;
464
+ const nmapArgs = [target, '-n', '-sn'];
465
+
466
+ console.log(`Scanning ${target}...`);
467
+ console.log('Note: Network scanning from cloud instances should comply with provider policies.');
468
+
469
+ try {
470
+ let result;
471
+ if (options.noSudo) {
472
+ result = spawnSync('nmap', nmapArgs, { encoding: 'utf8' });
473
+ } else {
474
+ result = spawnSync('sudo', ['nmap', ...nmapArgs], {
475
+ encoding: 'utf8',
476
+ stdio: ['inherit', 'pipe', 'pipe']
477
+ });
478
+ }
479
+
480
+ if (result.error) {
481
+ throw result.error;
482
+ }
483
+
484
+ const output = result.stdout || '';
485
+
486
+ if (options.ipOnly) {
487
+ const ips = extractIpsFromOutput(output);
488
+ if (ips.length === 0) {
489
+ console.log('No hosts found.');
490
+ } else {
491
+ ips.forEach(ip => console.log(ip));
492
+ }
493
+ } else {
494
+ console.log(output);
495
+ if (result.stderr) {
496
+ console.error(result.stderr);
497
+ }
498
+ }
499
+ } catch (error) {
500
+ console.error('Error running nmap:', error.message);
501
+ process.exit(1);
502
+ }
503
+ }
504
+
505
+ /**
506
+ * Scan local network on Windows using Command Prompt.
507
+ *
508
+ * Windows nmap does not require sudo/elevation for basic scanning.
509
+ * nmap for Windows can be installed from https://nmap.org/download.html
510
+ *
511
+ * @param {string[]} args - Command line arguments
512
+ * @returns {Promise<void>}
513
+ */
514
+ async function do_ips_cmd(args) {
515
+ const options = parseArgs(args);
516
+
517
+ // Show help before checking for nmap - user might just want usage info
518
+ if (options.help) {
519
+ showUsage();
520
+ return;
521
+ }
522
+
523
+ // Check if nmap is installed
524
+ if (!isCommandAvailable('nmap')) {
525
+ console.error('Error: nmap is required but not installed.');
526
+ console.error('');
527
+ console.error('Download and install from: https://nmap.org/download.html');
528
+ console.error('Or install with: winget install Nmap.Nmap');
529
+ console.error(' or: choco install nmap');
530
+ process.exit(1);
531
+ }
532
+
533
+ const target = `${options.ip}/${options.mask}`;
534
+ const nmapArgs = [target, '-n', '-sn'];
535
+
536
+ console.log(`Scanning ${target}...`);
537
+
538
+ try {
539
+ // Windows doesn't use sudo - nmap runs with current user privileges
540
+ // For best results, run as Administrator
541
+ const result = spawnSync('nmap', nmapArgs, { encoding: 'utf8' });
542
+
543
+ if (result.error) {
544
+ throw result.error;
545
+ }
546
+
547
+ const output = result.stdout || '';
548
+
549
+ if (options.ipOnly) {
550
+ const ips = extractIpsFromOutput(output);
551
+ if (ips.length === 0) {
552
+ console.log('No hosts found.');
553
+ } else {
554
+ ips.forEach(ip => console.log(ip));
555
+ }
556
+ } else {
557
+ console.log(output);
558
+ if (result.stderr) {
559
+ console.error(result.stderr);
560
+ }
561
+ }
562
+ } catch (error) {
563
+ console.error('Error running nmap:', error.message);
564
+ console.error('');
565
+ console.error('Tip: For best results, run from an elevated Command Prompt.');
566
+ process.exit(1);
567
+ }
568
+ }
569
+
570
+ /**
571
+ * Scan local network on Windows using PowerShell.
572
+ *
573
+ * PowerShell can run nmap the same as CMD.
574
+ * The no-sudo option is ignored on Windows.
575
+ *
576
+ * @param {string[]} args - Command line arguments
577
+ * @returns {Promise<void>}
578
+ */
579
+ async function do_ips_powershell(args) {
580
+ // Same as CMD - nmap works the same way in PowerShell
581
+ return do_ips_cmd(args);
582
+ }
583
+
584
+ /**
585
+ * Scan local network from Git Bash on Windows.
586
+ *
587
+ * Git Bash runs on Windows, so this uses the Windows nmap installation.
588
+ * The behavior is identical to the CMD implementation.
589
+ *
590
+ * @param {string[]} args - Command line arguments
591
+ * @returns {Promise<void>}
592
+ */
593
+ async function do_ips_gitbash(args) {
594
+ // Git Bash on Windows - same as CMD
595
+ return do_ips_cmd(args);
596
+ }
597
+
598
+ /**
599
+ * Main entry point - detects environment and executes appropriate implementation.
600
+ *
601
+ * The "ips" command scans the local network for active IP addresses using nmap.
602
+ * This is useful for network discovery, troubleshooting, and security auditing.
603
+ *
604
+ * Features:
605
+ * - Configurable network address and subnet mask
606
+ * - Option to show only IP addresses (ip-only)
607
+ * - Option to run without sudo for faster but less accurate results
608
+ * - Works across all major platforms
609
+ *
610
+ * @param {string[]} args - Command line arguments
611
+ * @returns {Promise<void>}
612
+ */
613
+ async function do_ips(args) {
614
+ const platform = os.detect();
615
+
616
+ const handlers = {
617
+ 'macos': do_ips_macos,
618
+ 'ubuntu': do_ips_ubuntu,
619
+ 'debian': do_ips_ubuntu,
620
+ 'raspbian': do_ips_raspbian,
621
+ 'amazon_linux': do_ips_amazon_linux,
622
+ 'rhel': do_ips_amazon_linux,
623
+ 'fedora': do_ips_ubuntu,
624
+ 'linux': do_ips_ubuntu,
625
+ 'wsl': do_ips_ubuntu,
626
+ 'cmd': do_ips_cmd,
627
+ 'windows': do_ips_cmd,
628
+ 'powershell': do_ips_powershell,
629
+ 'gitbash': do_ips_gitbash
630
+ };
631
+
632
+ const handler = handlers[platform.type];
633
+ if (!handler) {
634
+ console.error(`Platform '${platform.type}' is not supported for this command.`);
635
+ console.error('');
636
+ console.error('Supported platforms:');
637
+ console.error(' - macOS');
638
+ console.error(' - Ubuntu, Debian, and other Linux distributions');
639
+ console.error(' - Raspberry Pi OS');
640
+ console.error(' - Amazon Linux, RHEL, Fedora');
641
+ console.error(' - Windows (CMD, PowerShell, Git Bash)');
642
+ process.exit(1);
643
+ }
644
+
645
+ await handler(args);
20
646
  }
21
647
 
22
- module.exports = { main };
648
+ module.exports = {
649
+ main: do_ips,
650
+ do_ips,
651
+ do_ips_nodejs,
652
+ do_ips_macos,
653
+ do_ips_ubuntu,
654
+ do_ips_raspbian,
655
+ do_ips_amazon_linux,
656
+ do_ips_cmd,
657
+ do_ips_powershell,
658
+ do_ips_gitbash
659
+ };
23
660
 
24
661
  if (require.main === module) {
25
- main(process.argv.slice(2));
662
+ do_ips(process.argv.slice(2));
26
663
  }